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-2023 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 */
73BN_EXPORT extern void quat_mat2quat(quat_t quat,
74 const mat_t mat);
75
76/**
77 *@brief Convert Quaternion to Matrix.
78 */
79BN_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 */
85BN_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 */
96BN_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 */
106BN_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 */
118BN_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 */
132BN_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 */
148BN_EXPORT extern void quat_make_nearest(quat_t q1,
149 const quat_t q2);
150
151BN_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 */
159BN_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 */
167BN_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:366
hvect_t quat_t
4-element quaternion
Definition: vmath.h:360
fundamental vector, matrix, quaternion math macros