BRL-CAD
qmath.h
Go to the documentation of this file.
1 /* Q M A T H . H
2  * BRL-CAD
3  *
4  * Copyright (c) 2004-2024 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 
21 /*----------------------------------------------------------------------*/
22 /** @addtogroup bn_quat
23  *
24  * @brief
25  * Quaternion math routines.
26  *
27  * Unit Quaternions:
28  * Q = [ r, a ] where r = cos(theta/2) = rotation amount
29  * |a| = sin(theta/2) = rotation axis
30  *
31  * If a = 0 we have the reals; if one coord is zero we have
32  * complex numbers (2D rotations).
33  *
34  * [r, a][s, b] = [rs - a.b, rb + sa + axb]
35  *
36  * -1
37  * [r, a] = (r - a) / (r^2 + a.a)
38  *
39  * Powers of quaternions yield incremental rotations,
40  * e.g. Q^3 is rotated three times as far as Q.
41  *
42  * Some operations on quaternions:
43  * -1
44  * [0, P'] = Q [0, P]Q Rotate a point P by quaternion Q
45  * -1 a
46  * slerp(Q, R, a) = Q(Q R) Spherical linear interp: 0 < a < 1
47  *
48  * bisect(P, Q) = (P + Q) / |P + Q| Great circle bisector
49  *
50  * Additions inspired by "Quaternion Calculus For Animation" by Ken Shoemake,
51  * SIGGRAPH '89 course notes for "Math for SIGGRAPH", May 1989.
52  *
53  */
54 /** @{ */
55 /* @file qmath.h */
56 
57 #ifndef BN_QMATH_H
58 #define BN_QMATH_H
59 
60 #include "common.h"
61 #include "vmath.h"
62 #include "bn/defines.h"
63 
64 __BEGIN_DECLS
65 
66 /*
67  * Quaternion support
68  */
69 
70 /**
71  *@brief Convert Matrix to Quaternion.
72  */
73 BN_EXPORT extern void quat_mat2quat(quat_t quat,
74  const mat_t mat);
75 
76 /**
77  *@brief Convert Quaternion to Matrix.
78  */
79 BN_EXPORT extern void quat_quat2mat(mat_t mat,
80  const quat_t quat);
81 
82 /**
83  *@brief Gives the euclidean distance between two quaternions.
84  */
85 BN_EXPORT extern double quat_distance(const quat_t q1,
86  const quat_t q2);
87 
88 /**
89  *@brief
90  * Gives the quaternion point representing twice the rotation
91  * from q1 to q2.
92  *
93  * Needed for patching Bezier curves together.
94  * A rather poor name admittedly.
95  */
96 BN_EXPORT extern void quat_double(quat_t qout,
97  const quat_t q1,
98  const quat_t q2);
99 
100 /**
101  *@brief Gives the bisector of quaternions q1 and q2.
102  *
103  * (Could be done with quat_slerp and factor 0.5)
104  * [I believe they must be unit quaternions this to work]
105  */
106 BN_EXPORT extern void quat_bisect(quat_t qout,
107  const quat_t q1,
108  const quat_t q2);
109 
110 /**
111  *@brief
112  * Do Spherical Linear Interpolation between two unit quaternions
113  * by the given factor.
114  *
115  * As f goes from 0 to 1, qout goes from q1 to q2.
116  * Code based on code by Ken Shoemake
117  */
118 BN_EXPORT extern void quat_slerp(quat_t qout,
119  const quat_t q1,
120  const quat_t q2,
121  double f);
122 
123 /**
124  *@brief
125  * Spherical Bezier Interpolate between four quaternions by amount f.
126  * These are intended to be used as start and stop quaternions along
127  * with two control quaternions chosen to match spline segments with
128  * first order continuity.
129  *
130  * Uses the method of successive bisection.
131  */
132 BN_EXPORT extern void quat_sberp(quat_t qout,
133  const quat_t q1,
134  const quat_t qa,
135  const quat_t qb,
136  const quat_t q2,
137  double f);
138 
139 /**
140  *@brief
141  * Set the quaternion q1 to the quaternion which yields the
142  * smallest rotation from q2 (of the two versions of q1 which
143  * produce the same orientation).
144  *
145  * Note that smallest euclidean distance implies smallest great
146  * circle distance as well (since surface is convex).
147  */
148 BN_EXPORT extern void quat_make_nearest(quat_t q1,
149  const quat_t q2);
150 
151 BN_EXPORT extern void quat_print(const char *title,
152  const quat_t quat);
153 
154 /**
155  *@brief
156  * Exponentiate a quaternion, assuming that the scalar part is 0.
157  * Code by Ken Shoemake.
158  */
159 BN_EXPORT extern void quat_exp(quat_t out,
160  const quat_t in);
161 
162 /**
163  *@brief
164  * Take the natural logarithm of a unit quaternion.
165  * Code by Ken Shoemake.
166  */
167 BN_EXPORT extern void quat_log(quat_t out,
168  const quat_t in);
169 
170 __END_DECLS
171 
172 #endif /* BN_QMATH_H */
173 /** @} */
174 /*
175  * Local Variables:
176  * mode: C
177  * tab-width: 8
178  * indent-tabs-mode: t
179  * c-file-style: "stroustrup"
180  * End:
181  * ex: shiftwidth=4 tabstop=8
182  */
Header file for the BRL-CAD common definitions.
void quat_log(quat_t out, const quat_t in)
Take the natural logarithm of a unit quaternion. Code by Ken Shoemake.
double quat_distance(const quat_t q1, const quat_t q2)
Gives the euclidean distance between two quaternions.
void quat_mat2quat(quat_t quat, const mat_t mat)
Convert Matrix to Quaternion.
void quat_sberp(quat_t qout, const quat_t q1, const quat_t qa, const quat_t qb, const quat_t q2, double f)
Spherical Bezier Interpolate between four quaternions by amount f. These are intended to be used as s...
void quat_slerp(quat_t qout, const quat_t q1, const quat_t q2, double f)
Do Spherical Linear Interpolation between two unit quaternions by the given factor.
void quat_double(quat_t qout, const quat_t q1, const quat_t q2)
Gives the quaternion point representing twice the rotation from q1 to q2.
void quat_bisect(quat_t qout, const quat_t q1, const quat_t q2)
Gives the bisector of quaternions q1 and q2.
void quat_quat2mat(mat_t mat, const quat_t quat)
Convert Quaternion to Matrix.
void quat_print(const char *title, const quat_t quat)
void quat_exp(quat_t out, const quat_t in)
Exponentiate a quaternion, assuming that the scalar part is 0. Code by Ken Shoemake.
void quat_make_nearest(quat_t q1, const quat_t q2)
Set the quaternion q1 to the quaternion which yields the smallest rotation from q2 (of the two versio...
fastf_t mat_t[ELEMENTS_PER_MAT]
4x4 matrix
Definition: vmath.h:370
hvect_t quat_t
4-element quaternion
Definition: vmath.h:364
fundamental vector, matrix, quaternion math macros