Skip to content

Commit 6ec40c2

Browse files
add Slerp for 3D rotations (#252)
* add Slerp for 3D rotations * Update src/unitquaternion.jl Co-authored-by: Yuto Horikawa <[email protected]> * Update src/unitquaternion.jl Co-authored-by: Yuto Horikawa <[email protected]> * move specialized slerp methods * test all rotation types --------- Co-authored-by: Yuto Horikawa <[email protected]>
1 parent 2f9be71 commit 6ec40c2

File tree

4 files changed

+26
-1
lines changed

4 files changed

+26
-1
lines changed

src/Rotations.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export
5353
RotationVecGenerator,
5454

5555
# Quaternion math ops
56-
logm, expm, , ,
56+
logm, expm, , , slerp,
5757

5858
# Quaternion maps
5959
ExponentialMap, QuatVecMap, CayleyMap, MRPMap, IdentityMap,

src/euler_types.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ for axis in [:X, :Y, :Z]
3030

3131
@inline Base.inv(r::$RotType) = $RotType(-r.theta)
3232

33+
# specialized slerp for single axis rotations
34+
Quaternions.slerp(r1::$RotType, r2::$RotType, t::Real) = $RotType(r1.theta + (mod2pi(r2.theta - r1.theta + π) - π) * t)
35+
3336
# define identity rotations for convenience
3437
@inline Base.one(::Type{$RotType}) = $RotType(0.0)
3538
@inline Base.one(::Type{$RotType{T}}) where {T} = $RotType{T}(zero(T))

src/unitquaternion.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,14 @@ function rotation_between(from::SVector{3}, to::SVector{3})
328328
@inbounds return QuatRotation(w, v[1], v[2], v[3]) # relies on normalization in constructor
329329
end
330330

331+
"""
332+
slerp(R1::Rotaion{3}, R2::Rotaion{3}, t::Real)
333+
334+
Perform spherical linear interpolation (Slerp) between rotations `R1` and `R2`.
335+
"""
336+
Quaternions.slerp(q1::QuatRotation, q2::QuatRotation, t::Real) = QuatRotation(slerp(q1.q, q2.q, t))
337+
Quaternions.slerp(r1::Rotation{3}, r2::Rotation{3}, t::Real) = slerp(QuatRotation(r1), QuatRotation(r2), t)
338+
331339
# ~~~~~~~~~~~~~~~ Kinematics ~~~~~~~~~~~~~~~ $
332340
"""
333341
kinematics(R::Rotation{3}, ω::AbstractVector)

test/rotation_tests.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,20 @@ all_types = (RotMatrix3, RotMatrix{3}, AngleAxis, RotationVec,
246246
end
247247
end
248248

249+
@testset "Slerp rotations" begin
250+
repeats = 100
251+
@testset "slerp($(R1), $(R2), rand())" for R1 in all_types, R2 in all_types
252+
Random.seed!(0)
253+
for i in 1:repeats
254+
r1 = rand(R1)
255+
q1 = QuatRotation(r1)
256+
r2 = rand(R2)
257+
q2 = QuatRotation(r2)
258+
t = rand()
259+
@test slerp(r1, r2, t) slerp(q1, q2, t)
260+
end
261+
end
262+
end
249263

250264
#########################################################################
251265
# Test conversions between rotation types

0 commit comments

Comments
 (0)