Animating a 'rgl' mesh at constant speed
The purpose of my package qsplines is to construct quaternions splines. This is a port of the Python library splines, written by Matthias Geier. A quaternions spline is a sequence of quaternions interpolating some given quaternions.
One feature I particularly like is the possibility to get a quaternions spline having constant speed. I’m going to illustrate this feature.
Firstly, I take some key points following a spherical curve on the unit ball. Then I will take, for each key point, a unit quaternion (“rotor”) which sends the first key point to this key point, through the rotation it corresponds to. The spherical curve I take is a so-called satellite curve.
# satellite curve
# https://mathcurve.com/courbes3d.gb/satellite/satellite.shtml
function(t, R = 1, alpha = pi/2, k = 8) {
satellite <-c(
cos(alpha) * cos(t) * cos(k*t) - sin(t) * sin(k*t),
cos(alpha) * sin(t) * cos(k*t) + cos(t) * sin(k*t),
sin(alpha) * cos(k*t)
)
}# take key points running on the satellite curve
10L
nkeypoints <- seq(0, 2*pi, length.out = nkeypoints+1L)[1L:nkeypoints]
t_ <- t(vapply(t_, satellite, numeric(3L))) keyPoints <-
Now the rotors as previously described:
# construction of the key rotors; the first key rotor
# is the identity quaternion and rotor i sends the
# first key point to the i-th key point
quaternion(length.out = nkeypoints)
keyRotors <- keyRotors[1L] <- H1
rotor <-for(i in seq_len(nkeypoints - 1L)){
+1L] <- rotor <-
keyRotors[i quaternionFromTo(keyPoints[i, ], keyPoints[i+1L, ]) * rotor
}
And now the constant speed quaternions spline:
# Kochanek-Bartels quaternions spline interpolating the key rotors
KochanekBartels(
rotors <-n_intertimes = 10L,
keyRotors, endcondition = "closed", tcb = c(0, 0, 0),
constantSpeed = TRUE
)
And now, with the help of this spline, we can construct an animation of a rgl mesh rotating at constant speed. I take a mesh of a Dupin cyclide.
library(rgl)
cgalMeshes::cyclideMesh(
mesh0 <-a = 97, c = 32, mu = 57, nu = 200L, nv = 200L
)open3d(windowRect = 50 + c(0, 0, 512, 512), zoom = 0.6)
for(i in 1L:length(rotors)) {
as.orthogonal(rotors[i])
rotMatrix <- rotate3d(mesh0, matrix = rotMatrix)
mesh <-# this invisible sphere is used to fix the frame
spheres3d(x = 0, y = 0, z = 0, radius = 200, alpha = 0)
shade3d(mesh0, color = "chartreuse")
sprintf("pic%03d.png", i)
png <-snapshot3d(png, webshot = FALSE)
clear3d()
}# mount animation
Sys.glob("*.png")
pngFiles <-library(gifski)
gifski(
"cyclide_constantSpeed.gif",
pngFiles, width = 512, height = 512,
delay = 1/10
)file.remove(pngFiles)
If you want to play with this stuff, you can change the parameters of the satellite curve to get a different motion, and also change the tcb
argument in the KochanekBartels
function (tension, continuity, bias). There is a Shiny application in qsplines allowing to visualize the effects of tcb
.