Nothing
tkspinControl <- function(base, dev = cur3d(), continue=FALSE,
speed=30, scale=100, ...) {
if (!requireNamespace("tcltk"))
stop("This function requires 'tcltk'.")
slider <- tcltk::tclVar(speed)
getZooms <- function() {
old <- cur3d()
on.exit(set3d(old))
result <- numeric(max(dev))
for (device in dev) {
set3d(device)
result[device] <- par3d("zoom")
}
result
}
zooms <- getZooms()
scale <- tcltk::tclVar(scale)
continuous <- tcltk::tclVar(as.numeric(continue))
buttonPress <- NULL
direction <- NULL
lastTime <- proc.time()[3]
timeDiff <- 0
rotateUp <- function() {
angle <- timeDiff*as.numeric(tcltk::tclObj(slider))*pi/180
par3d(userMatrix = rotationMatrix(-angle, 1,0,0) %*% par3d("userMatrix"))
}
rotateLeft <- function() {
angle <- timeDiff*as.numeric(tcltk::tclObj(slider))*pi/180
par3d(userMatrix = rotationMatrix(-angle, 0,1,0) %*% par3d("userMatrix"))
}
rotateRight <- function() {
angle <- timeDiff*as.numeric(tcltk::tclObj(slider))*pi/180
par3d(userMatrix = rotationMatrix(angle, 0,1,0) %*% par3d("userMatrix"))
}
rotateSpin <- function() {
angle <- timeDiff*as.numeric(tcltk::tclObj(slider))*pi/180
par3d(userMatrix = rotationMatrix(-angle, 0,0,1) %*% par3d("userMatrix"))
}
rotateDown <- function() {
angle <- timeDiff*as.numeric(tcltk::tclObj(slider))*pi/180
par3d(userMatrix = rotationMatrix(angle, 1,0,0) %*% par3d("userMatrix"))
}
rotate <- function() {
old <- cur3d()
on.exit(set3d(old))
if (buttonPress) {
if ((currentTime <- proc.time()[3]) > lastTime) {
timeDiff <<- currentTime - lastTime
lastTime <<- currentTime
for (device in dev) {
set3d(device)
if (direction == "up")
rotateUp()
if (direction == "left")
rotateLeft()
if (direction == "spin")
rotateSpin()
if (direction == "right")
rotateRight()
if (direction == "down")
rotateDown()
}
}
tcltk::tcl("after",5,rotate)
}
}
# rotation button callback functions
# note that "..." argument is necessary
upButtonPress <- function(...) {
buttonPress <<- TRUE
lastTime <<- proc.time()[3]
direction <<- "up"
rotate()
}
leftButtonPress <- function(...) {
buttonPress <<- TRUE
lastTime <<- proc.time()[3]
direction <<- "left"
rotate()
}
spinButtonPress <- function(...) {
buttonPress <<- TRUE
lastTime <<- proc.time()[3]
direction <<- "spin"
rotate()
}
rightButtonPress <- function(...) {
buttonPress <<- TRUE
lastTime <<- proc.time()[3]
direction <<- "right"
rotate()
}
downButtonPress <- function(...) {
buttonPress <<- TRUE
lastTime <<- proc.time()[3]
direction <<- "down"
rotate()
}
onIdle <- function(...) {
buttonPress <<- TRUE
rotate()
buttonPress <<- FALSE
if (as.numeric(tcltk::tclObj(continuous)))
tcltk::tcl("after", "idle", onIdle)
}
buttonRelease <- function(...) {
buttonPress <<- FALSE
if (as.numeric(tcltk::tclObj(continuous)))
tcltk::tcl("after", "idle", onIdle)
}
resetAxis <- function(...) {
old <- cur3d()
on.exit(set3d(old))
for (device in dev) {
set3d(device)
par3d(userMatrix = diag(4))
}
}
setScale <- function(...) {
old <- cur3d()
on.exit(set3d(old))
scale <- as.numeric(tcltk::tclObj(scale))
for (device in dev) {
set3d(device)
par3d(zoom = 10^((scale - 100)/50)*zooms[device])
}
}
spec.frm <- tcltk::tkframe(base, ...)
first.frm <- tcltk::tkframe(spec.frm)
second.frm <- tcltk::tkframe(spec.frm)
third.frm <- tcltk::tkframe(spec.frm)
fourth.frm <- tcltk::tkframe(spec.frm)
# rotations buttons
upButton <- tcltk::tkbutton(first.frm, text=" ^ ")
leftButton <- tcltk::tkbutton(first.frm, text=" < ")
spinButton <- tcltk::tkbutton(first.frm, text=" O ")
rightButton <- tcltk::tkbutton(first.frm, text=" > ")
downButton <- tcltk::tkbutton(first.frm, text=" v ")
tcltk::tkgrid(tcltk::tklabel(first.frm, text=" "), upButton, tcltk::tklabel(first.frm, text=" "))
tcltk::tkgrid(leftButton,spinButton,rightButton)
tcltk::tkgrid(tcltk::tklabel(first.frm, text=" "), downButton, tcltk::tklabel(first.frm, text=" "))
tcltk::tkbind(upButton, "<Button-1>", upButtonPress)
tcltk::tkbind(leftButton, "<Button-1>", leftButtonPress)
tcltk::tkbind(spinButton, "<Button-1>", spinButtonPress)
tcltk::tkbind(rightButton, "<Button-1>", rightButtonPress)
tcltk::tkbind(downButton, "<Button-1>", downButtonPress)
tcltk::tkbind(upButton,"<ButtonRelease-1>", buttonRelease)
tcltk::tkbind(leftButton,"<ButtonRelease-1>", buttonRelease)
tcltk::tkbind(spinButton,"<ButtonRelease-1>", buttonRelease)
tcltk::tkbind(rightButton,"<ButtonRelease-1>", buttonRelease)
tcltk::tkbind(downButton,"<ButtonRelease-1>", buttonRelease)
# control buttons
frameAxis <- tcltk::tkframe(second.frm,borderwidth=2)
tcltk::tkpack(frameAxis)
buttonAxis <- tcltk::tkbutton(frameAxis,text=" Reset Axis ",command=resetAxis)
contBox <- tcltk::tkcheckbutton(frameAxis,text="Continue rotating", variable=continuous)
tcltk::tkpack(contBox, buttonAxis,fill="x")
#control scale frame
frameControl <- tcltk::tkframe(third.frm,borderwidth=4)
tcltk::tkpack(frameControl)
frameControlSpeed <- tcltk::tkframe(frameControl)
sliderSpeed <- tcltk::tkscale(frameControlSpeed, showvalue=FALSE,
orient="horiz", from=0, to=400,resolution=1,variable=slider)
tcltk::tkpack(tcltk::tklabel(frameControlSpeed,text="Speed:"),sliderSpeed,side="left")
frameControlScale <- tcltk::tkframe(frameControl)
sliderScale <- tcltk::tkscale(frameControlScale,showvalue=FALSE,orient="horiz",
from=0, to=200,resolution=1, variable=scale, command=setScale)
tcltk::tkpack(tcltk::tklabel(frameControlScale,text="Scale:"),sliderScale,side="left")
tcltk::tkpack(frameControlSpeed,frameControlScale)
tcltk::tkpack(first.frm, second.frm, third.frm, fourth.frm)
tcltk::tkpack(spec.frm,expand=TRUE)
spec.frm
}
tkspin3d <- function(dev = cur3d(), ...) {
if (!requireNamespace("tcltk"))
stop("This function requires 'tcltk'.")
args <- list(...)
controlargs <- list()
if (length(args)) {
controlargindices <- which(names(args) %in% names(formals(tkspinControl)))
if (length(controlargindices)) {
args <- args[-controlargindices]
controlargs <- args[controlargindices]
}
}
base <- do.call(tcltk::tktoplevel, args)
tcltk::tkwm.title(base, "Spin")
spin <- do.call(tkspinControl, c(list(base = base, dev = dev), controlargs))
quit <- tcltk::tkbutton(base,text="Quit", command=function()tcltk::tkdestroy(base))
tcltk::tkpack(spin, quit)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.