qmath.h
Go to the documentation of this file.
1 /* Q M A T H . H
3  *
4  * Copyright (c) 2004-2014 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
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 /* @file qmath.h */
24 /** @{ */
25
26 /** @brief
27  *
28  * Quaternion math routines.
29  *
30  * Unit Quaternions:
31  * Q = [ r, a ] where r = cos(theta/2) = rotation amount
32  * |a| = sin(theta/2) = rotation axis
33  *
34  * If a = 0 we have the reals; if one coord is zero we have
35  * complex numbers (2D rotations).
36  *
37  * [r, a][s, b] = [rs - a.b, rb + sa + axb]
38  *
39  * -1
40  * [r, a] = (r - a) / (r^2 + a.a)
41  *
42  * Powers of quaternions yield incremental rotations,
43  * e.g. Q^3 is rotated three times as far as Q.
44  *
45  * Some operations on quaternions:
46  * -1
47  * [0, P'] = Q [0, P]Q Rotate a point P by quaternion Q
48  * -1 a
49  * slerp(Q, R, a) = Q(Q R) Spherical linear interp: 0 < a < 1
50  *
51  * bisect(P, Q) = (P + Q) / |P + Q| Great circle bisector
52  *
53  * Additions inspired by "Quaternion Calculus For Animation" by Ken Shoemake,
54  * SIGGRAPH '89 course notes for "Math for SIGGRAPH", May 1989.
55  *
56  */
57
58 #ifndef BN_QMATH_H
59 #define BN_QMATH_H
60
61 #include "common.h"
62 #include "vmath.h"
63 #include "bn/defines.h"
64
66
67 /*
68  * Quaternion support
69  */
70
71 /**
72  *@brief
73  *
74  * Convert Matrix to Quaternion.
75  */
76 BN_EXPORT extern void quat_mat2quat(quat_t quat,
77  const mat_t mat);
78
79 /**
80  *@brief
81  *
82  * Convert Quaternion to Matrix.
83  *
84  * NB: This only works for UNIT quaternions. We may get imaginary results
85  * otherwise. We should normalize first (still yields same rotation).
86  */
87 BN_EXPORT extern void quat_quat2mat(mat_t mat,
88  const quat_t quat);
89
90 /**
91  *@brief
92  *
93  * Gives the euclidean distance between two quaternions.
94  *
95  */
96 BN_EXPORT extern double quat_distance(const quat_t q1,
97  const quat_t q2);
98
99 /**
100  *@brief
101  * Gives the quaternion point representing twice the rotation
102  * from q1 to q2.
103  * Needed for patching Bezier curves together.
104  * A rather poor name admittedly.
105  */
106 BN_EXPORT extern void quat_double(quat_t qout,
107  const quat_t q1,
108  const quat_t q2);
109
110 /**
111  *@brief
112  * Gives the bisector of quaternions q1 and q2.
113  * (Could be done with quat_slerp and factor 0.5)
114  * [I believe they must be unit quaternions this to work]
115  */
116 BN_EXPORT extern void quat_bisect(quat_t qout,
117  const quat_t q1,
118  const quat_t q2);
119
120 /**
121  *@brief
122  * Do Spherical Linear Interpolation between two unit quaternions
123  * by the given factor.
124  *
125  * As f goes from 0 to 1, qout goes from q1 to q2.
126  * Code based on code by Ken Shoemake
127  */
128 BN_EXPORT extern void quat_slerp(quat_t qout,
129  const quat_t q1,
130  const quat_t q2,
131  double f);
132
133 /**
134  *@brief
135  * Spherical Bezier Interpolate between four quaternions by amount f.
136  * These are intended to be used as start and stop quaternions along
137  * with two control quaternions chosen to match spline segments with
138  * first order continuity.
139  *
140  * Uses the method of successive bisection.
141  */
142 BN_EXPORT extern void quat_sberp(quat_t qout,
143  const quat_t q1,
144  const quat_t qa,
145  const quat_t qb,
146  const quat_t q2,
147  double f);
148
149 /**
150  *@brief
151  * Set the quaternion q1 to the quaternion which yields the
152  * smallest rotation from q2 (of the two versions of q1 which
153  * produce the same orientation).
154  *
155  * Note that smallest euclidian distance implies smallest great
156  * circle distance as well (since surface is convex).
157  */
158 BN_EXPORT extern void quat_make_nearest(quat_t q1,
159  const quat_t q2);
160
161 BN_EXPORT extern void quat_print(const char *title,
162  const quat_t quat);
163
164 /**
165  *@brief
166  * Exponentiate a quaternion, assuming that the scalar part is 0.
167  * Code by Ken Shoemake.
168  */
169 BN_EXPORT extern void quat_exp(quat_t out,
170  const quat_t in);
171
172 /**
173  *@brief
174  * Take the natural logarithm of a unit quaternion.
175  * Code by Ken Shoemake.
176  */
177 BN_EXPORT extern void quat_log(quat_t out,
178  const quat_t in);
179
181
182 #endif /* BN_QMATH_H */
183 /** @} */
184 /*
185  * Local Variables:
186  * mode: C
187  * tab-width: 8
188  * indent-tabs-mode: t
189  * c-file-style: "stroustrup"
190  * End:
191  * ex: shiftwidth=4 tabstop=8
192  */
void quat_print(const char *title, const quat_t quat)
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_bisect(quat_t qout, const quat_t q1, const quat_t q2)
Gives the bisector of quaternions q1 and q2. (Could be done with quat_slerp and factor 0...
#define __BEGIN_DECLS
Definition: common.h:73
goto out
Definition: nmg_mod.c:3846
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. Needed for patching Bezier ...
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_quat2mat(mat_t mat, const quat_t quat)
Convert Quaternion to Matrix.
#define __END_DECLS
Definition: common.h:74
double quat_distance(const quat_t q1, const quat_t q2)
Gives the euclidean distance between two quaternions.
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_mat2quat(quat_t quat, const mat_t mat)
Quaternion math routines.
void quat_log(quat_t out, const quat_t in)
Take the natural logarithm of a unit quaternion. 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...