RflySimSDK v3.05
RflySimSDK说明文档
载入中...
搜索中...
未找到
rfly_quat.h
1
2/*****************************************************************************
3 *
4 quat.h - include file for quaternion, vector and matrix routines.
5
6
7 Overview:
8
9 quatlib is a library of routines that implements a grab-bag of
10 useful routines for dealing with quaternions, vectors, and
11 matrices. See the quatlib man page for an overview.
12
13
14 Notes:
15
16 - to address the quaternion elements, use the Q_X, Q_Y, Q_Z and Q_W
17 #defines from this file.
18
19 - to find out which version of the library you're using, do:
20
21 % ident <path>/libquat.a
22
23 (this information is in the rcsid string in quat.c)
24
25 - see /afs/unc/proj/hmd/src/quat/{quat,vector,matrix}.c
26 for implementation details.
27
28
29 Conventions:
30
31 - general-purpose quaternion routines start with q_
32
33 - all non-integer values are doubles by default- the exceptions
34 to this are old (non-open-) GL routines which use floats.
35
36 - vector routines start with "q_vec"
37
38 - matrix routines have the string "matrix" somewhere in their name
39
40 - all matrices are 4x4
41
42 - positive rotation directions are as follows:
43
44 about Z axis: from X axis to Y axis
45 about X axis: from Y axis to Z axis
46 about Y axis: from Z axis to X axis
47
48 - all angles are specified in radians
49
50 - destination parameter (if any) is always first argument (as in
51 Unix string routines)
52
53 - src and dest parameters can always be the same, as long as they
54 are of the same type (copying is done if necessary)
55
56 - naming conventions for conversion routines:
57
58 q_{to,from}_whatever for routines involving quaternions
59 q_x_to_y for all others (ie., no "from" is used)
60
61
62 Revision History (for whole library, not just this file):
63
64 Author Date Comments
65 ------ -------- ----------------------------
66 Rich Holloway 09/10/01 Misc cleanup, deleted PPHIGS support,
67 added q_xyz_quat_xform(), renamed
68 qogl_matrix_mult_fixed() back to
69 qogl_matrix_mult().
70 Mark Livingston 01/09/96 Added routines for OpenGL matrices
71 Rich Holloway 09/27/93 Added Gary Bishop's matrix to euler rtn
72 Rich Holloway 07/16/92 Added q_euler_to_col_matrix(), routines
73 for working with GL matrices, added
74 documentation for euler angle routines
75 Erik Erikson/ 06/26/92 Added q_xyz_quat_compose
76 Stefan Gottschalk/
77 Russ Taylor
78
79 Rich Holloway 05/13/92 Added Q_NULL_VECTOR, Q_ID_MATRIX
80 Jon Leech/ 04/29/92 Added CM_ prototypes
81 Erik Erikson
82
83 Rich Holloway 09/21/90 Made into library, made all matrices 4x4,
84 added matrix routines for
85 4x4 (standard) or 3x4 (for PPHIGS),
86 changed names of
87 routines (to avoid name conflicts with
88 non-library routines) by prefixing
89 everything with "q_".
90
91 Russ Taylor 1990 Modified q_slerp to pick shortest path
92 between two angles
93
94 Warren Robinett 12/89 Added PPHIGS support routines
95
96 Ken Shoemake 1985 Initial version
97
98 RCS Header:
99 $Id: quat.h,v 2.37 2004/07/22 20:54:42 taylorr Exp $
100 *
101 *****************************************************************************/
102
103/* prevent multiple includes */
104#ifndef Q_INCLUDED
105#define Q_INCLUDED
106
107
108/*****************************************************************************
109 *
110 #defines
111 *
112 *****************************************************************************/
113
114/* for accessing the elements of q_type and q_vec_type */
115#define Q_X 0
116#define Q_Y 1
117#define Q_Z 2
118#define Q_W 3
119
120/* For accessing the elements of a q_vec_type describing Euler angles */
121#define Q_YAW 0
122#define Q_PITCH 1
123#define Q_ROLL 2
124
125/* tolerance for quaternion operations */
126#define Q_EPSILON (1e-10)
127
128/* min and max macros */
129#define Q_MAX(x, y) ( ((x) > (y)) ? (x) : (y) )
130#define Q_MIN(x, y) ( ((x) < (y)) ? (x) : (y) )
131
132#define Q_ABS(x) ( ((x) > 0 ) ? (x) : (-(x)) )
133
134/*
135 * use local definition of PI for machines that have no def in math.h; this
136 * value stolen from DEC Ultrix 4.1 math.h
137 */
138#define Q_PI 3.14159265358979323846
139
140#define Q_ID_QUAT { 0.0, 0.0, 0.0, 1.0 }
141
142#define Q_ID_MATRIX { {1.0, 0.0, 0.0, 0.0}, \
143 {0.0, 1.0, 0.0, 0.0}, \
144 {0.0, 0.0, 1.0, 0.0}, \
145 {0.0, 0.0, 0.0, 1.0} }
146
147#define Q_NULL_VECTOR { 0.0, 0.0, 0.0 }
148
149/*
150 * degree/radian conversion
151 */
152#define Q_DEG_TO_RAD(deg) ( ((deg)*Q_PI)/180.0 )
153#define Q_RAD_TO_DEG(rad) ( (((rad)*180.0)/Q_PI) )
154
155
156/*****************************************************************************
157 *
158 typedefs
159 *
160 *****************************************************************************/
161
162/* basic quaternion type- scalar part is last element in array */
163typedef double q_type[4];
164
165/* basic vector type */
166typedef double q_vec_type[3];
167
168/* for row and column matrices */
169typedef double q_matrix_type[4][4];
170
171/* for working with gl or other 4x4 float matrices */
172typedef float qgl_matrix_type[4][4];
173
174/* for working with OpenGL matrices - these are really just like row matrices
175** (i.e. same bits in same order), but the decl is a 1-D array, not 2-D, sigh
176*/
177typedef double qogl_matrix_type[16];
178
179/* special transformation type using quaternions and vectors */
180typedef struct q_xyz_quat_struct {
181 q_vec_type xyz; /* translation */
182 q_type quat; /* rotation */
184
185
186
187/*****************************************************************************
188 *****************************************************************************
189 *
190 function declarations
191 *
192 *****************************************************************************
193 *****************************************************************************/
194
195/* On some platforms, we need to specifically tell the compiler
196 * that these functions are to have C linkage. [why not everywhere?]
197 */
198
199#if defined(__cplusplus)
200
201#ifdef FLOW
202#define EXTERN_QUALIFICATION
203#else
204#define EXTERN_QUALIFICATION "C"
205#endif /* FLOW */
206
207#define BEGIN_EXTERN_BLOCK extern EXTERN_QUALIFICATION {
208#define END_EXTERN_BLOCK }
209
210#else /* __cplusplus */
211
212#define BEGIN_EXTERN_BLOCK
213#define END_EXTERN_BLOCK
214
215#endif /* __cplusplus */
216
217
218
219BEGIN_EXTERN_BLOCK
220
221/*****************************************************************************
222 *
223 strictly quaternion operations
224 *
225 *****************************************************************************/
226
227/* prints a quaternion */
228void q_print (const q_type quat);
229
230/* make a quaternion given an axis and an angle; x,y,z is axis of
231 * rotation; angle is angle of rotation in radians (see also q_from_two_vecs)
232 *
233 * rotation is counter-clockwise when rotation axis vector is
234 * pointing at you
235 *
236 * if angle or vector are 0, the identity quaternion is returned.
237 */
238void q_make (q_type destQuat,
239 double x, double y, double z,
240 double angle);
241void q_from_axis_angle(q_type destQuat,
242 double x, double y, double z,
243 double angle);
244
245/* Turn a quaternion into an axis and an angle; x,y,z is axis of
246 * rotation; angle is angle of rotation in radians.
247 *
248 * rotation is counter-clockwise when rotation axis vector is
249 * pointing at you
250 *
251 * if the identity quaternion is passed in, the angle will be
252 * zero and the axis will be the Z axis.
253 */
254void q_to_axis_angle (double *x, double *y, double *z, double *angle,
255 const q_type srcQuat);
256
257/* copy srcQuat to destQuat */
258void q_copy (q_type destQuat, const q_type srcQuat);
259
260/* normalizes quaternion; src and dest can be same */
261void q_normalize (q_type destQuat, const q_type srcQuat);
262
263/* invert quat; src and dest can be the same */
264void q_invert (q_type destQuat, const q_type srcQuat);
265
266/*
267 * computes quaternion product destQuat = qLeft * qRight.
268 * destQuat can be same as either qLeft or qRight or both.
269 */
270void q_mult (q_type destQuat, const q_type qLeft, const q_type qRight);
271
272/* conjugate quat; src and dest can be same */
273void q_conjugate (q_type destQuat, const q_type srcQuat);
274
275/* take natural log of unit quat; src and dest can be same */
276void q_log (q_type destQuat, const q_type srcQuat);
277
278/* exponentiate quaternion, assuming scalar part 0. src can be same as dest */
279void q_exp (q_type destQuat, const q_type srcQuat);
280
281
282/*
283 * q_slerp: Spherical linear interpolation of unit quaternions.
284 *
285 * As t goes from 0 to 1, destQuat goes from startQ to endQuat.
286 * This routine should always return a point along the shorter
287 * of the two paths between the two. That is why the vector may be
288 * negated in the end.
289 *
290 * src == dest should be ok, although that doesn't seem to make much
291 * sense here.
292 */
293void q_slerp (q_type destQuat, const q_type startQuat, const q_type endQuat, double t);
294
295/*****************************************************************************
296 *
297 q_from_euler - converts 3 euler angles (in radians) to a quaternion
298
299 Assumes roll is rotation about X, pitch
300 is rotation about Y, yaw is about Z. Assumes order of
301 yaw, pitch, roll applied as follows:
302
303 p' = roll( pitch( yaw(p) ) )
304
305 See comments for q_euler_to_col_matrix for more on this.
306 *
307 *****************************************************************************/
308void q_from_euler (q_type destQuat, double yaw, double pitch, double roll);
309
310/* converts quat to euler angles (yaw, pitch, roll). see
311 * q_col_matrix_to_euler() for conventions. Note that you
312 * cannot use Q_X, Q_Y, and Q_Z to pull the elements out of
313 * the Euler as if they were rotations about these angles --
314 * this will invert X and Z. You need to instead use Q_YAW
315 * (rotation about Z), Q_PITCH (rotation about Y) and Q_ROLL
316 * (rotation about X) to get them.
317 */
318void q_to_euler(q_vec_type yawPitchRoll, const q_type q);
319
320/*****************************************************************************
321 *
322 mixed quaternion operations: conversions to and from vectors & matrices
323 *
324 *****************************************************************************/
325
326/* destVec = q * vec * q(inverse); vec can be same storage as destVec */
327void q_xform (q_vec_type destVec, const q_type q, const q_vec_type vec);
328
329/* quat/vector conversion */
330/* create a quaternion from two vectors that rotates v1 to v2
331 * about an axis perpendicular to both
332 */
333void q_from_two_vecs (q_type destQuat, const q_vec_type v1, const q_vec_type v2);
334
335/* simple conversion */
336void q_from_vec (q_type destQuat, const q_vec_type srcVec);
337void q_to_vec (q_vec_type destVec, const q_type srcQuat);
338
339/* quaternion/4x4 matrix conversions */
340void q_from_row_matrix (q_type destQuat, const q_matrix_type matrix);
341void q_from_col_matrix (q_type destQuat, const q_matrix_type matrix);
342void q_to_row_matrix (q_matrix_type destMatrix, const q_type srcQuat);
343void q_to_col_matrix (q_matrix_type destMatrix, const q_type srcQuat);
344
345/* quat/ogl conversion */
346void q_from_ogl_matrix (q_type destQuat, const qogl_matrix_type matrix);
347void q_to_ogl_matrix (qogl_matrix_type matrix, const q_type srcQuat);
348
349
350/*****************************************************************************
351 *
352 strictly vector operations
353 *
354 *****************************************************************************/
355
356/* prints a vector to stdout */
357void q_vec_print (const q_vec_type vec);
358
359/* compatibility w/ old */
360#define q_set_vec q_vec_set
361
362/* sets vector equal to 3 values given */
363void q_vec_set (q_vec_type vec, double x, double y, double z);
364
365/* copies srcVec to destVec */
366void q_vec_copy (q_vec_type destVec, const q_vec_type srcVec);
367
368/* adds two vectors */
369void q_vec_add (q_vec_type destVec, const q_vec_type aVec, const q_vec_type bVec);
370
371/* destVec = v1 - v2 (v1, v2, destVec need not be distinct storage) */
372void q_vec_subtract (q_vec_type destVec, const q_vec_type v1, const q_vec_type v2);
373
374/* returns value of dot product of v1 and v2 */
375double q_vec_dot_product (const q_vec_type v1, const q_vec_type v2);
376
377/* scale a vector (src and dest need not be distinct) */
378void q_vec_scale (q_vec_type destVec, double scaleFactor, const q_vec_type srcVec);
379
380
381/* negate a vector to point in the opposite direction */
382void q_vec_invert (q_vec_type destVec, const q_vec_type srcVec);
383
384/* normalize a vector (destVec and srcVec may be the same) */
385void q_vec_normalize (q_vec_type destVec, const q_vec_type srcVec);
386
387/* returns magnitude of vector */
388double q_vec_magnitude (const q_vec_type vec);
389
390/* returns distance between two points/vectors */
391double q_vec_distance (const q_vec_type vec1, const q_vec_type vec2);
392
393/* computes cross product of two vectors: destVec = aVec X bVec
394 * destVec same as aVec or bVec ok */
395void q_vec_cross_product (q_vec_type destVec,
396 const q_vec_type aVec, const q_vec_type bVec);
397
398
399/*****************************************************************************
400 *
401 strictly matrix operations
402 *
403 *****************************************************************************/
404
405/* q_matrix_copy - copies srcMatrix to destMatrix (both matrices are 4x4) */
406void q_matrix_copy (q_matrix_type destMatrix, const q_matrix_type srcMatrix);
407
408void qogl_matrix_copy (qogl_matrix_type dest, const qogl_matrix_type src);
409
410/* does a 4x4 matrix multiply (the input matrices are 4x4) and
411 * puts the result in a 4x4 matrix. src == dest ok.
412 */
413void q_matrix_mult (q_matrix_type resultMatrix,
414 const q_matrix_type leftMatrix,
415 const q_matrix_type rightMatrix);
416
417// for backward compatibility
418#define qogl_matrix_mult_fixed qogl_matrix_mult
419
420/*
421 * Computes result=left*right
422 * Used to be called qogl_matrix_mult_fixed because the old version
423 * did not compute the correct result.
424 */
425void qogl_matrix_mult (qogl_matrix_type result,
426 const qogl_matrix_type left,
427 const qogl_matrix_type right);
428
429
430/*****************************************************************************
431 *
432 q_euler_to_col_matrix - euler angles should be in radians
433 computed assuming the order of rotation is: yaw, pitch, roll.
434
435 This means the following:
436
437 p' = roll( pitch( yaw(p) ) )
438
439 or
440
441 p' = Mr * Mp * My * p
442
443 Yaw is rotation about Z axis, pitch is rotation about Y axis, and roll
444 is rotation about X axis. In terms of these axes, then, the process is:
445
446 p' = Mx * My * Mz * p
447
448 where Mx = the standard Foley and van Dam column matrix for rotation
449 about the X axis, and similarly for Y and Z.
450
451 Thus the calling sequence in terms of X, Y, Z is:
452
453 q_euler_to_col_matrix(destMatrix, zRot, yRot, xRot);
454 *
455 *****************************************************************************/
456void q_euler_to_col_matrix (q_matrix_type destMatrix,
457 double yaw, double pitch, double roll);
458
459/*****************************************************************************
460 *
461 q_col_matrix_to_euler- convert a column matrix to euler angles
462
463 input:
464 - vector to hold euler angles
465 - src column matrix
466
467 output:
468 - euler angles in radians in the range -pi to pi;
469 vec[0] = yaw, vec[1] = pitch, vec[2] = roll
470 yaw is rotation about Z axis, pitch is about Y, roll -> X rot.
471
472 notes:
473 - written by Gary Bishop
474 - you cannot use Q_X, Q_Y, and Q_Z to pull the elements out of
475 the Euler as if they were rotations about these angles --
476 this will invert X and Z. You need to instead use Q_YAW
477 (rotation about Z), Q_PITCH (rotation about Y) and Q_ROLL
478 (rotation about X) to get them.
479 *
480 *****************************************************************************/
481void q_col_matrix_to_euler (q_vec_type yawpitchroll, const q_matrix_type colMatrix);
482
483/* prints 4x4 matrix */
484void q_print_matrix (const q_matrix_type matrix);
485
486void qogl_print_matrix (const qogl_matrix_type);
487
488
489/*****************************************************************************
490 *
491 xyz_quat routines
492 *
493 *****************************************************************************/
494
495/* invert a vector/quaternion transformation pair */
496void q_xyz_quat_invert (q_xyz_quat_type *destPtr, const q_xyz_quat_type *srcPtr);
497
498
499/* converts a row matrix to an xyz_quat */
500void q_row_matrix_to_xyz_quat (q_xyz_quat_type * xyzQuatPtr,
501 const q_matrix_type rowMatrix);
502
503/* convert an xyz_quat to a row matrix */
504void q_xyz_quat_to_row_matrix (q_matrix_type rowMatrix,
505 const q_xyz_quat_type * xyzQuatPtr);
506
507void q_ogl_matrix_to_xyz_quat (q_xyz_quat_type * xyzQuatPtr,
508 const qogl_matrix_type matrix);
509
510void q_xyz_quat_to_ogl_matrix (qogl_matrix_type matrix,
511 const q_xyz_quat_type * xyzQuatPtr);
512
513/* compose q_xyz_quat_vecs to form a third. */
514/* C_from_A_ptr may be = to either C_from_B_ptr or B_from_A_ptr (or both) */
515void q_xyz_quat_compose (q_xyz_quat_type * C_from_A_ptr,
516 const q_xyz_quat_type * C_from_B_ptr,
517 const q_xyz_quat_type * B_from_A_ptr);
518
519void q_xyz_quat_xform(q_vec_type dest, const q_xyz_quat_type *xf, const q_vec_type src);
520
521/*****************************************************************************
522 *
523 GL support
524 *
525 *****************************************************************************/
526
527/* convert from quat to GL 4x4 float row matrix */
528void qgl_to_matrix (qgl_matrix_type destMatrix, const q_type srcQuat);
529
530
531/* qgl_from_matrix- Convert GL 4x4 row-major rotation matrix to
532 * unit quaternion.
533 * - same as q_from_row_matrix, except basic type is float, not double
534 */
535void qgl_from_matrix (q_type destQuat, const qgl_matrix_type srcMatrix);
536
537/* print gl-style matrix */
538void qgl_print_matrix (const qgl_matrix_type matrix);
539
540END_EXTERN_BLOCK
541
542#undef BEGIN_EXTERN_BLOCK
543#undef END_EXTERN_BLOCK
544#undef EXTERN_QUALIFICATION
545
546#endif /* Q_INCLUDED */
定义 rfly_quat.h:180