MoveG 1.0.0
A modern C++ library for Robotics
Loading...
Searching...
No Matches
appoggio.cpp File Reference

Go to the source code of this file.

Functions

Quaterniond my_slerp (Quaterniond v0, Quaterniond v1, double t)
 

Function Documentation

◆ my_slerp()

Quaterniond my_slerp ( Quaterniond  v0,
Quaterniond  v1,
double  t 
)

Definition at line 2 of file appoggio.cpp.

3{
4 // Only unit quaternions are valid rotations.
5 // Normalize to avoid undefined behavior.
6 v0.normalize();
7 v1.normalize();
8
9 // Compute the cosine of the angle between the two vectors.
10 double dot = v0.dot(v1);
11
12 // If the dot product is negative, slerp won't take
13 // the shorter path. Note that v1 and -v1 are equivalent when
14 // the negation is applied to all four components. Fix by
15 // reversing one quaternion.
16 if (dot < 0.0f)
17 {
18 v1 = quaternion_negation(v1);
19 dot = -dot;
20 }
21
22 Quaterniond vdiff = quaternion_minus(v1, v0);
23
24 const double DOT_THRESHOLD = 0.9995;
25 if (dot > DOT_THRESHOLD)
26 {
27 // If the inputs are too close for comfort, linearly interpolate
28 // and normalize the result.
29
30 Quaterniond result = scalar_product(vdiff, t);
31 result.normalize();
32 return result;
33 }
34
35 // Since dot is in range [0, DOT_THRESHOLD], acos is safe
36 double theta_0 = acos(dot); // theta_0 = angle between input vectors
37 double theta = theta_0 * t; // theta = angle between v0 and result
38 double sin_theta = sin(theta); // compute this value only once
39 double sin_theta_0 = sin(theta_0); // compute this value only once
40
41 double s0 =
42 cos(theta) - dot * sin_theta / sin_theta_0; // == sin(theta_0 - theta) / sin(theta_0)
43 double s1 = sin_theta / sin_theta_0;
44
45 return quaternion_plus(scalar_product(v0, s0), scalar_product(v1, s1));
46}