Title: | Quaternions Splines |
---|---|
Description: | Provides routines to create some quaternions splines: Barry-Goldman algorithm, De Casteljau algorithm, and Kochanek-Bartels algorithm. The implementations are based on the Python library 'splines'. Quaternions splines allow to construct spherical curves. References: Barry and Goldman <doi:10.1145/54852.378511>, Kochanek and Bartels <doi:10.1145/800031.808575>. |
Authors: | Stéphane Laurent [aut, cre], Matthias Geier [aut] (author of the Python library 'splines') |
Maintainer: | Stéphane Laurent <[email protected]> |
License: | GPL-3 |
Version: | 1.0.1 |
Built: | 2024-10-27 04:04:36 UTC |
Source: | https://github.com/stla/qsplines |
Constructs a spline of unit quaternions by the Barry-Goldman method.
BarryGoldman(keyRotors, keyTimes = NULL, n_intertimes, times)
BarryGoldman(keyRotors, keyTimes = NULL, n_intertimes, times)
keyRotors |
a vector of unit quaternions (rotors) to be interpolated; it is automatically appended with the first one to have a closed spline |
keyTimes |
the times corresponding to the key rotors; must be an
increasing vector of length |
n_intertimes |
a positive integer used to linearly interpolate the
times given in |
times |
the interpolating times, they must lie within the range of
|
A vector of unit quaternions with the same length as times
.
The function does not check whether the quaternions given in
keyRotors
are unit quaternions.
library(qsplines) # Using a Barry-Goldman quaternions spline to construct # a spherical curve interpolating some key points on # the sphere of radius 5. # helper function: spherical to Cartesian coordinates sph2cart <- function(rho, theta, phi){ return(c( rho * cos(theta) * sin(phi), rho * sin(theta) * sin(phi), rho * cos(phi) )) } # construction of the key points on the sphere keyPoints <- matrix(nrow = 0L, ncol = 3L) theta_ <- seq(0, 2*pi, length.out = 9L)[-1L] phi <- 1 for(theta in theta_){ keyPoints <- rbind(keyPoints, sph2cart(5, theta, phi)) phi = pi - phi } n_keyPoints <- nrow(keyPoints) # construction of the key rotors; the first key rotor is the # identity quaternion and rotor i sends the first key point # to the key point i keyRotors <- quaternion(length.out = n_keyPoints) rotor <- keyRotors[1L] <- H1 for(i in seq_len(n_keyPoints - 1L)){ keyRotors[i+1L] <- rotor <- quaternionFromTo( keyPoints[i, ]/5, keyPoints[i+1L, ]/5 ) * rotor } # Barry-Goldman quaternions spline rotors <- BarryGoldman(keyRotors, n_intertimes = 10L) # construction of the interpolating points on the sphere points <- matrix(nrow = 0L, ncol = 3L) keyPoint1 <- rbind(keyPoints[1L, ]) for(i in seq_along(rotors)){ points <- rbind(points, rotate(keyPoint1, rotors[i])) } # visualize the result with the 'rgl' package library(rgl) spheres3d(0, 0, 0, radius = 5, color = "lightgreen") spheres3d(points, radius = 0.2, color = "midnightblue") spheres3d(keyPoints, radius = 0.25, color = "red")
library(qsplines) # Using a Barry-Goldman quaternions spline to construct # a spherical curve interpolating some key points on # the sphere of radius 5. # helper function: spherical to Cartesian coordinates sph2cart <- function(rho, theta, phi){ return(c( rho * cos(theta) * sin(phi), rho * sin(theta) * sin(phi), rho * cos(phi) )) } # construction of the key points on the sphere keyPoints <- matrix(nrow = 0L, ncol = 3L) theta_ <- seq(0, 2*pi, length.out = 9L)[-1L] phi <- 1 for(theta in theta_){ keyPoints <- rbind(keyPoints, sph2cart(5, theta, phi)) phi = pi - phi } n_keyPoints <- nrow(keyPoints) # construction of the key rotors; the first key rotor is the # identity quaternion and rotor i sends the first key point # to the key point i keyRotors <- quaternion(length.out = n_keyPoints) rotor <- keyRotors[1L] <- H1 for(i in seq_len(n_keyPoints - 1L)){ keyRotors[i+1L] <- rotor <- quaternionFromTo( keyPoints[i, ]/5, keyPoints[i+1L, ]/5 ) * rotor } # Barry-Goldman quaternions spline rotors <- BarryGoldman(keyRotors, n_intertimes = 10L) # construction of the interpolating points on the sphere points <- matrix(nrow = 0L, ncol = 3L) keyPoint1 <- rbind(keyPoints[1L, ]) for(i in seq_along(rotors)){ points <- rbind(points, rotate(keyPoint1, rotors[i])) } # visualize the result with the 'rgl' package library(rgl) spheres3d(0, 0, 0, radius = 5, color = "lightgreen") spheres3d(points, radius = 0.2, color = "midnightblue") spheres3d(keyPoints, radius = 0.25, color = "red")
Constructs a quaternions spline using the De Casteljau algorithm.
DeCasteljau( segments, keyTimes = NULL, n_intertimes, times, constantSpeed = FALSE )
DeCasteljau( segments, keyTimes = NULL, n_intertimes, times, constantSpeed = FALSE )
segments |
a list of vectors of unit quaternions; each segment must contain at least two quaternions |
keyTimes |
the times corresponding to the segment boundaries, an
increasing vector of length |
n_intertimes |
a positive integer used to linearly interpolate the
times given in |
times |
the interpolating times, they must lie within the range of
|
constantSpeed |
Boolean, whether to re-parameterize the spline to
have constant speed; in this case, |
A vector of quaternions whose length is the number of interpolating times.
This algorithm is rather for internal purpose. It serves for example as a base for the Konachek-Bartels algorithm.
Linearly interpolate an increasing vector of times. This is useful to deal with the quaternions splines.
interpolateTimes(times, n, last = TRUE)
interpolateTimes(times, n, last = TRUE)
times |
increasing vector of times |
n |
integer, controls the number of interpolations: there will be
|
last |
Boolean, whether to include or exclude the last element |
A vector, a refinement of the times
vector.
library(qsplines) interpolateTimes(1:4, n = 3) interpolateTimes(c(1, 2, 4), n = 3)
library(qsplines) interpolateTimes(1:4, n = 3) interpolateTimes(c(1, 2, 4), n = 3)
Constructs a quaternions spline by the Kochanek-Bartels algorithm.
KochanekBartels( keyRotors, keyTimes = NULL, tcb = c(0, 0, 0), times, n_intertimes, endcondition = "natural", constantSpeed = FALSE )
KochanekBartels( keyRotors, keyTimes = NULL, tcb = c(0, 0, 0), times, n_intertimes, endcondition = "natural", constantSpeed = FALSE )
keyRotors |
a vector of unit quaternions (rotors) to be interpolated |
keyTimes |
the times corresponding to the key rotors; must be an
increasing vector of the same length a |
tcb |
a vector of three numbers respectively corresponding to tension, continuity and bias |
times |
the times of interpolation; each time must lie within the range
of the key times; this parameter can be missing if |
n_intertimes |
if given, this argument has precedence over |
endcondition |
start/end conditions, can be |
constantSpeed |
Boolean, whether to re-parameterize the spline to
have constant speed; in this case, |
A vector of quaternions having the same length as the times
vector.
library(qsplines) # Using a Kochanek-Bartels quaternions spline to construct # a spherical curve interpolating some key points on the # sphere of radius 5 # helper function: spherical to Cartesian coordinates sph2cart <- function(rho, theta, phi){ return(c( rho * cos(theta) * sin(phi), rho * sin(theta) * sin(phi), rho * cos(phi) )) } # construction of the key points on the sphere keyPoints <- matrix(nrow = 0L, ncol = 3L) theta_ <- seq(0, 2*pi, length.out = 9L)[-1L] phi <- 1.3 for(theta in theta_){ keyPoints <- rbind(keyPoints, sph2cart(5, theta, phi)) phi = pi - phi } n_keyPoints <- nrow(keyPoints) # 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 keyRotors <- quaternion(length.out = n_keyPoints) rotor <- keyRotors[1L] <- H1 for(i in seq_len(n_keyPoints - 1L)){ keyRotors[i+1L] <- rotor <- quaternionFromTo( keyPoints[i, ]/5, keyPoints[i+1L, ]/5 ) * rotor } # Kochanek-Bartels quaternions spline rotors <- KochanekBartels( keyRotors, n_intertimes = 25L, endcondition = "closed", tcb = c(-1, 5, 0) ) # construction of the interpolating points on the sphere points <- matrix(nrow = 0L, ncol = 3L) keyPoint1 <- rbind(keyPoints[1L, ]) for(i in seq_along(rotors)){ points <- rbind(points, rotate(keyPoint1, rotors[i])) } # visualize the result with the 'rgl' package library(rgl) spheres3d(0, 0, 0, radius = 5, color = "lightgreen") spheres3d(points, radius = 0.2, color = "midnightblue") spheres3d(keyPoints, radius = 0.25, color = "red")
library(qsplines) # Using a Kochanek-Bartels quaternions spline to construct # a spherical curve interpolating some key points on the # sphere of radius 5 # helper function: spherical to Cartesian coordinates sph2cart <- function(rho, theta, phi){ return(c( rho * cos(theta) * sin(phi), rho * sin(theta) * sin(phi), rho * cos(phi) )) } # construction of the key points on the sphere keyPoints <- matrix(nrow = 0L, ncol = 3L) theta_ <- seq(0, 2*pi, length.out = 9L)[-1L] phi <- 1.3 for(theta in theta_){ keyPoints <- rbind(keyPoints, sph2cart(5, theta, phi)) phi = pi - phi } n_keyPoints <- nrow(keyPoints) # 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 keyRotors <- quaternion(length.out = n_keyPoints) rotor <- keyRotors[1L] <- H1 for(i in seq_len(n_keyPoints - 1L)){ keyRotors[i+1L] <- rotor <- quaternionFromTo( keyPoints[i, ]/5, keyPoints[i+1L, ]/5 ) * rotor } # Kochanek-Bartels quaternions spline rotors <- KochanekBartels( keyRotors, n_intertimes = 25L, endcondition = "closed", tcb = c(-1, 5, 0) ) # construction of the interpolating points on the sphere points <- matrix(nrow = 0L, ncol = 3L) keyPoint1 <- rbind(keyPoints[1L, ]) for(i in seq_along(rotors)){ points <- rbind(points, rotate(keyPoint1, rotors[i])) } # visualize the result with the 'rgl' package library(rgl) spheres3d(0, 0, 0, radius = 5, color = "lightgreen") spheres3d(points, radius = 0.2, color = "midnightblue") spheres3d(keyPoints, radius = 0.25, color = "red")
Get a unit quaternion whose corresponding rotation sends
u
to v
; the vectors u
and v
must be normalized.
quaternionFromTo(u, v)
quaternionFromTo(u, v)
u , v
|
two unit 3D vectors |
A unit quaternion whose corresponding rotation transforms u
to v
.
library(qsplines) u <- c(1, 1, 1) / sqrt(3) v <- c(1, 0, 0) q <- quaternionFromTo(u, v) rotate(rbind(u), q) # this should be v
library(qsplines) u <- c(1, 1, 1) / sqrt(3) v <- c(1, 0, 0) q <- quaternionFromTo(u, v) rotate(rbind(u), q) # this should be v
Run a Shiny app which demonstrates the Kochanek-Bartels spline.
shinyKBS()
shinyKBS()
No value returned.