# R/MRtwoD.R In AIG: Automatic Item Generator

#' @export
#' @importFrom rgl rgl.postscript
#' @importFrom rgl rgl.light
#' @importFrom rgl rgl.viewpoint
#' @importFrom rgl clear3d
#' @importFrom rgl rgl.clear
#' @importFrom rgl rgl.snapshot
#' @param items The number of items to generate.
#' @param wd This is the working directory to save the figures in. If not provided, the file will be saved in the current working directory.
#' @param view There are three options ("2D", "top", "bottom") to view the display figure from different prespectives.
#' @param seed To generate the same set of item(s) on the local computer.
#' @param degree This allows users to change the rotation of the display figure by increasing or decreasing the value.
#' @param ansDegree This will allow users to change the degree of rotation for the correct figure.
#' @param test This will generate the specific value in the name of the saved images.
#' @description This function generates a 2 or 3 dimensional display figure with 4 2D distractors and 1 2D answer.
#' @details To see the 3D display figure, change the view argument to either 'top' or 'bottom'. For 3D figures, some of the cubes may be hidden in sight. Hence, the 2D answer may not seem correct. So one would need to rotate the display figure several times to ensure that none of the cubes are hidden. The rotation can be done by changing the degree value in the function. To ensure that the same image is generated again, please provide a seed value. Currently angle of the view from the top and the bottom is fixed. It may be better to generate one item at a time for the 3D displayed figures. This is not a problem for 2D items.
#'
#' By default the actual answer is always at half of the display polar coordinates. The display figure polar coordinates by default is 360. Increasing the degrees will make the figure rotate clock-wise and decreasing the degrees will make the figure rotate anti-clockwise.
#'
#'  4 distractors are generated. 2 of the generated distractors are a mirror image of the displayed figure. The difference in the polar coordinates between the two distractors are fixed at 120. The third distractor is a figure wihout the first square that is generated by the display item. The fourth distractor is a figure with an additional square added to the distractor. Currently, the polar coordinates are fixed for the third and fourth distractor as well.
#'
#' There are occassions where a mirror distractor will not work. In such an instance, the item together with the distractors will not be useful for the test. Hence, it will be a good item to remove the item from the test. It is also a good idea to keep track on your local computer which seed it is so you can avoid having to regenerate the item. That is where the seed will come in handy. The seed correspond to the number position of which the item is created. For example, if you want to recreate item/figure number 19, then all you need do so is to keep the argument item = 1, but change the argument seed = 19. This will re-generate the number 19th item. Bear in mind that the created figures will use item 19 as the file name. So if you try to re-generate the 19th item 10 times, then all it does is to rewrite on the same image for 10 times. Hence, you will not get replicates.
#'
#' Finally, to automatically generate more than 1 item, just make sure that the argument seed = NULL, and put in how many values you want in the argument item. See the examples for help.
#'
#'
#' @author Aiden Loe and Francis Smart
#' @title Spatial 2D Reasoning Items
#' @return
#' \describe{
#' \item{ans}{Return the matrix that generates the display figure and answer.}
#' \item{mirror}{Return the matrix that generates a mirror figure.}
#' \item{dist3}{Return the matrix that generates the distractor without the first square.}
#' \item{dist4}{Return the matrix that generates the distractor that adds an extra square.}
#'     }
#' @examples
#'
#'
#' #2D display figure (Generate the 19th item given the seed value)
#' spatial2d(items=1, wd=NULL,view="2D", seed=19, degree=360, ansDegree= 180, test = 2)
#'
#' #2D display figure (Generate 10 items)
#' #seed must be NULL
#' #spatial2d(items=10, wd=NULL,view="2D", seed=NULL, degree=360, ansDegree= 180, test = 2)
#'
#' #wd<- "~/desktop"
#' #3D display figure (top view)
#' #spatial2d(items=1, wd=wd,view="top", seed=1, degree=320, ansDegree=160, test = 2)
#'
#' #3D display figure (bottom view)
#' #spatial2d(items=1, wd=wd,view="bottom", seed=1, degree=320, ansDegree=100, test = 2)

spatial2d <- function(items ,wd=NULL, view="2D",seed=NULL, degree= 360, ansDegree=180, test = 1){

if(view !="2D" && view !="top" && view !="bottom") stop("The input for the argument view is incorrect.")
##### Working Directory ####
if(is.null(wd)){
wd = getwd()
message("Item and distractors saved in current working directory.")
}

res <- try(setwd(wd),silent = TRUE)
if(class(res) == "try-error"){
stop("Working Directory does not exist.")
}

result <- NULL
for(item in 1:items){

if(!is.null(seed)){
item <- seed
}

# This will finalise the item
clear3d()
rgl.light()
clear3d(type = "lights") # for 2d
j <- NULL
k <- NULL
set.seed(item)
vlist <- c(1,2,2)
(zlist <- matrix(NA,ncol=3,nrow=15))
for (i in 1:15) { # 15 is the max. Arbitary number. Can be anything. #Does not take last row
cube(vlist[1],vlist[2],vlist[3])
(step <- sample(1:3, 1))
(vlist[step] <- vlist[step]+(-1)^rbinom(1,1,.25))
(zlist[i,] <- vlist)
zlist
}

if(view == "2D"){
clear3d()
cube(zlist[1:15,1],zlist[1:15,2],zlist[1:15,3])
rgl.viewpoint(theta = degree, phi = 90, fov = 0) # become 2D display item
rgl.snapshot(filename=paste0("display2d_",item,"-",test,".",fmt="jpg"))
#save <- paste0(wd,"/display2d_",item,".pdf")
#rgl.postscript(save,"pdf")
}

if(view == "top"){
clear3d()
set.seed(item)
# vlist <- c(1,2,2)
# (zlist <- matrix(NA,ncol=3,nrow=15))
# for (i in 1:15) { # 15 is the max. Arbitary number. Can be anything. #Does not take last row
#   cube(vlist[1],vlist[2],vlist[3])
#   (step <- sample(2, 1))
#   (vlist[step] <- vlist[step]+(-1)^rbinom(1,1,.25))
#   (zlist[i,] <- vlist)
#   zlist
# }
cube(zlist[1:15,1],zlist[1:15,2],zlist[1:15,3]) #
rgl.light()
rgl.viewpoint(theta = 20, phi = 10, fov = 10)
rgl.snapshot(filename=paste0("displayTop_",item,"-",test,".",fmt="jpg"))

#save <- paste0(wd,"/displayTop_",item,".pdf")
#rgl.postscript(save,"pdf")
}

if(view == "bottom"){
clear3d()
set.seed(item)
# vlist <- c(1,2,2)
# (zlist <- matrix(NA,ncol=3,nrow=15))
# for (i in 1:15) { # 15 is the max. Arbitary number. Can be anything. #Does not take last row
#   cube(vlist[1],vlist[2],vlist[3])
#   (step <- sample(1:3, 1))
#   (vlist[step] <- vlist[step]+(-1)^rbinom(1,1,.25))
#   (zlist[i,] <- vlist)
#   zlist
# }
cube(zlist[1:15,1],zlist[1:15,2],zlist[1:15,3]) #
rgl.light()
rgl.viewpoint(theta = degree, phi = -35, fov = 5)
rgl.snapshot(filename=paste0("displayBottom_",item,"-",test,".",fmt="jpg"))
#save <- paste0(wd,"/displayBottom_",item,".pdf")
#rgl.postscript(save,"pdf")
}

cube(zlist[1:15,1],zlist[1:15,2],zlist[1:15,3]) #
rgl.clear(type="lights")
rgl.viewpoint(theta = ansDegree, phi = 90, fov = 0)
rgl.snapshot(filename=paste0("ans_",item,"-",test,".",fmt="jpg"))
#save <- paste0(wd,"/ans_",item,".pdf")
#rgl.postscript(save,"pdf")

#Distractor 1
#mirror image
set.seed(item)
clear3d()
mlist <- cbind(zlist[1:15,3],zlist[1:15,2],zlist[1:15,1])
cube(zlist[1:15,3],zlist[1:15,2],zlist[1:15,1]) #
rgl.viewpoint(theta = 380, phi = 90, fov = 0)
rgl.snapshot(filename=paste0("dist(mirror)_",item,"-",test,".",fmt="jpg"))
#save <- paste0(wd,"/dist(mirror)_",item,".pdf")
#rgl.postscript(save,"pdf")

#Distractor 2
#mirror image
set.seed(item)
clear3d()
cube(zlist[1:15,3],zlist[1:15,2],zlist[1:15,1]) #
rgl.viewpoint(theta = 260, phi = 90, fov = 0)
rgl.snapshot(filename=paste0("dist(mirror2)_",item,"-",test,".",fmt="jpg"))
#save <- paste0(wd,"/dist(mirror2)_",item,".pdf")
#rgl.postscript(save,"pdf")

#Distractor 3
# -1
(dlist2 <- zlist)
dlist3 <- dlist2[!duplicated(dlist2[,c(1,3)]),c(1:3)]
clear3d()
cube(dlist3[2:nrow(dlist3),1],dlist3[2:nrow(dlist3),2],dlist3[2:nrow(dlist3),3])
rgl.snapshot(filename=paste0("dist(3)_",item,"-",test,".",fmt="jpg"))
#save <- paste0(wd,"/dist(3)_",item,".pdf")
#rgl.postscript(save,"pdf")

#Distractor 4
set.seed(item)
(dlist4 <- zlist)
if((dlist4[14,3] == dlist4[15,3])==TRUE){
dlist4[15,3]<-  dlist4[15,3]+1 # + 1 on the last column

}else if((dlist4[14,3] == dlist4[15,3]-2)==TRUE){
dlist4[15,1]<-  dlist4[15,1]+1 #+ 1 at the start
dlist4[15,3]<-  dlist4[15,3]+1 #+ 1 at the end

}else{
dlist4[15,1]<-  dlist4[15,1]+1 #+ 1 at the start
}
dlist4
zlist
clear3d()
cube(dlist4[1:15,1],dlist4[1:15,2],dlist4[1:15,3])
rgl.snapshot(filename=paste0("dist(4)_",item,"-",test,".",fmt="jpg"))
#save <- paste0(wd,"/dist(4)_",item,".pdf")
#rgl.postscript(save,"pdf")

name <- paste0('item_',item)

result[[name]] <- list(ans=zlist, mirror=mlist, dist3 = dlist3, dist4 = dlist4)

}

result
return(result)
class(result) <- "twoD"

}

#first column, higher values, means on top of the square with the lower value (x) left-right
#second column, make the picture looks smaller as the number increase. (y) up-down
#3rd column, adding a cube forward or backward (z)


## Try the AIG package in your browser

Any scripts or data that you put into this service are public.

AIG documentation built on May 1, 2019, 11:29 p.m.