BRL-CAD
mat.h
Go to the documentation of this file.
1/* M A T . 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
23/** @addtogroup bn_mat
24 *
25 * @brief
26 * Matrix and vector functionality
27 */
28/** @{ */
29/* @file mat.h */
30
31#ifndef BN_MAT_H
32#define BN_MAT_H
33
34#include "common.h"
35#include <stdio.h> /* For FILE */
36#include "vmath.h"
37#include "bu/vls.h"
38#include "bn/defines.h"
39#include "bn/tol.h"
40
41__BEGIN_DECLS
42
43/*
44 * 4x4 Matrix math
45 */
46
47BN_EXPORT extern const mat_t bn_mat_identity;
48
49BN_EXPORT extern void bn_mat_print(const char *title,
50 const mat_t m);
51
52BN_EXPORT extern void bn_mat_print_guts(const char *title,
53 const mat_t m,
54 char *buf,
55 int buflen);
56
57BN_EXPORT extern void bn_mat_print_vls(const char *title,
58 const mat_t m,
59 struct bu_vls *vls);
60
61/**
62 * A wrapper for the system atan2(). On the Silicon Graphics, and
63 * perhaps on others, x==0 incorrectly returns infinity.
64 */
65BN_EXPORT extern double bn_atan2(double x, double y);
66
67#define bn_mat_zero(_m) { \
68 bu_log("%s:%d bn_mat_zero() is deprecated, use MAT_ZERO()\n", \
69 __FILE__, __LINE__); \
70 (_m)[0] = (_m)[1] = (_m)[2] = (_m)[3] = \
71 (_m)[4] = (_m)[5] = (_m)[6] = (_m)[7] = \
72 (_m)[8] = (_m)[9] = (_m)[10] = (_m)[11] = \
73 (_m)[12] = (_m)[13] = (_m)[14] = (_m)[15] = 0.0; }
74/*
75 #define bn_mat_zero(_m) (void)memset((void *)_m, 0, sizeof(mat_t))
76*/
77#define bn_mat_idn(_m) { \
78 bu_log("%s:%d bn_mat_idn() is deprecated, use MAT_IDN()\n", \
79 __FILE__, __LINE__); \
80 (_m)[1] = (_m)[2] = (_m)[3] = (_m)[4] = \
81 (_m)[6] = (_m)[7] = (_m)[8] = (_m)[9] = \
82 (_m)[11] = (_m)[12] = (_m)[13] = (_m)[14] = 0.0; \
83 (_m)[0] = (_m)[5] = (_m)[10] = (_m)[15] = 1.0; }
84/*
85 #define bn_mat_idn(_m) (void)memcpy((void *)_m, (const void *)bn_mat_identity, sizeof(mat_t))
86*/
87
88#define bn_mat_copy(_d, _s) { \
89 bu_log("%s:%d bn_mat_copy() is deprecated, use MAT_COPY()\n", \
90 __FILE__, __LINE__); \
91 (_d)[0] = (_s)[0];\
92 (_d)[1] = (_s)[1];\
93 (_d)[2] = (_s)[2];\
94 (_d)[3] = (_s)[3];\
95 (_d)[4] = (_s)[4];\
96 (_d)[5] = (_s)[5];\
97 (_d)[6] = (_s)[6];\
98 (_d)[7] = (_s)[7];\
99 (_d)[8] = (_s)[8];\
100 (_d)[9] = (_s)[9];\
101 (_d)[10] = (_s)[10];\
102 (_d)[11] = (_s)[11];\
103 (_d)[12] = (_s)[12];\
104 (_d)[13] = (_s)[13];\
105 (_d)[14] = (_s)[14];\
106 (_d)[15] = (_s)[15]; }
107/*
108 #define bn_mat_copy(_d, _s) (void)memcpy((void *)_d, (const void *)(_s), sizeof(mat_t))
109*/
110
111
112/**
113 * Multiply matrix "a" by "b" and store the result in "o".
114 *
115 * This is different from multiplying "b" by "a" (most of the time!)
116 * Also, "o" must not be the same as either of the inputs.
117 */
118BN_EXPORT extern void bn_mat_mul(mat_t o,
119 const mat_t a,
120 const mat_t b);
121
122/**
123 * o = i * o
124 *
125 * A convenience wrapper for bn_mat_mul() to update a matrix in place.
126 * The argument ordering is confusing either way.
127 */
128BN_EXPORT extern void bn_mat_mul2(const mat_t i,
129 mat_t o);
130
131/**
132 * o = a * b * c
133 *
134 * The output matrix may be the same as 'b' or 'c', but may not be
135 * 'a'.
136 */
137BN_EXPORT extern void bn_mat_mul3(mat_t o,
138 const mat_t a,
139 const mat_t b,
140 const mat_t c);
141
142/**
143 * o = a * b * c * d
144 *
145 * The output matrix may be the same as any input matrix.
146 */
147BN_EXPORT extern void bn_mat_mul4(mat_t o,
148 const mat_t a,
149 const mat_t b,
150 const mat_t c,
151 const mat_t d);
152
153/**
154 * Multiply the matrix "im" by the vector "iv" and store the result in
155 * the vector "ov". Note this is post-multiply, and operates on
156 * 4-tuples. Use MAT4X3VEC() to operate on 3-tuples.
157 */
158BN_EXPORT extern void bn_matXvec(hvect_t ov,
159 const mat_t im,
160 const hvect_t iv);
161
162/**
163 * The matrix pointed at by "input" is inverted and stored in the area
164 * pointed at by "output".
165 *
166 * Calls bu_bomb if matrix is singular.
167 */
168BN_EXPORT extern void bn_mat_inv(mat_t output,
169 const mat_t input);
170
171/**
172 * The matrix pointed at by "input" is inverted and stored in the area
173 * pointed at by "output".
174 *
175 * Invert a 4-by-4 matrix using Algorithm 120 from ACM. This is a
176 * modified Gauss-Jordan algorithm. Note: Inversion is done in place,
177 * with 3 work vectors.
178 *
179 * @return 1 if OK.
180 * @return 0 if matrix is singular.
181 */
182BN_EXPORT extern int bn_mat_inverse(mat_t output,
183 const mat_t input);
184
185/**
186 * Takes a pointer to a [x, y, z] vector, and a pointer to space for a
187 * homogeneous vector [x, y, z, w], and builds [x, y, z, 1].
188 */
189BN_EXPORT extern void bn_vtoh_move(hvect_t h,
190 const vect_t v);
191
192/**
193 * Takes a pointer to [x, y, z, w], and converts it to an ordinary
194 * vector [x/w, y/w, z/w]. Optimization for the case of w==1 is
195 * performed.
196 *
197 * FIXME: make tolerance configurable
198 */
199BN_EXPORT extern void bn_htov_move(vect_t v,
200 const hvect_t h);
201
202BN_EXPORT extern void bn_mat_trn(mat_t om,
203 const mat_t im);
204
205/**
206 * Compute a 4x4 rotation matrix given Azimuth and Elevation.
207 *
208 * Azimuth is +X, Elevation is +Z, both in degrees.
209 *
210 * Formula due to Doug Gwyn, BRL.
211 */
212BN_EXPORT extern void bn_mat_ae(mat_t m,
213 double azimuth,
214 double elev);
215
216/**
217 * Find the azimuth and elevation angles that correspond to the
218 * direction (not including twist) given by a direction vector.
219 */
220BN_EXPORT extern void bn_ae_vec(fastf_t *azp,
221 fastf_t *elp,
222 const vect_t v);
223
224/**
225 * Find the azimuth, elevation, and twist from two vectors. Vec_ae is
226 * in the direction of view (+z in mged view) and vec_twist points to
227 * the viewers right (+x in mged view). Accuracy (degrees) is used to
228 * stabilize flutter between equivalent extremes of atan2(), and to
229 * snap twist to zero when elevation is near +/- 90
230 */
231BN_EXPORT extern void bn_aet_vec(fastf_t *az,
232 fastf_t *el,
233 fastf_t *twist,
234 vect_t vec_ae,
235 vect_t vec_twist,
236 fastf_t accuracy);
237
238/**
239 * Find a unit vector from the origin given azimuth and elevation.
240 */
241BN_EXPORT extern void bn_vec_ae(vect_t vec,
242 fastf_t az,
243 fastf_t el);
244
245/**
246 * Find a vector from the origin given azimuth, elevation, and distance.
247 */
248BN_EXPORT extern void bn_vec_aed(vect_t vec,
249 fastf_t az,
250 fastf_t el,
251 fastf_t dist);
252
253/**
254 * This routine builds a Homogeneous rotation matrix, given alpha,
255 * beta, and gamma as angles of rotation, in degrees.
256 *
257 * Alpha is angle of rotation about the X axis, and is done third.
258 * Beta is angle of rotation about the Y axis, and is done second.
259 * Gamma is angle of rotation about Z axis, and is done first.
260 *
261 * FIXME: make tolerance configurable
262 */
263BN_EXPORT extern void bn_mat_angles(mat_t mat,
264 double alpha,
265 double beta, double ggamma);
266
267/**
268 * This routine builds a Homogeneous rotation matrix, given alpha,
269 * beta, and gamma as angles of rotation, in radians.
270 *
271 * Alpha is angle of rotation about the X axis, and is done third.
272 * Beta is angle of rotation about the Y axis, and is done second.
273 * Gamma is angle of rotation about Z axis, and is done first.
274 *
275 * FIXME: make tolerance configurable
276 */
277BN_EXPORT extern void bn_mat_angles_rad(mat_t mat,
278 double alpha,
279 double beta,
280 double ggamma);
281
282/**
283 * Find the eigenvalues and eigenvectors of a symmetric 2x2 matrix.
284 * (a b)
285 * (b c)
286 *
287 * The eigenvalue with the smallest absolute value is returned in
288 * val1, with its eigenvector in vec1.
289 */
290BN_EXPORT extern void bn_eigen2x2(fastf_t *val1,
291 fastf_t *val2,
292 vect_t vec1,
293 vect_t vec2,
294 fastf_t a,
295 fastf_t b,
296 fastf_t c);
297
298/**
299 * Given a vector, create another vector which is perpendicular to it.
300 * The output vector will have unit length only if the input vector
301 * did.
302 *
303 * FIXME: make tolerance configurable
304 */
305BN_EXPORT extern void bn_vec_perp(vect_t new_vec,
306 const vect_t old_vec);
307
308/**
309 * Given two vectors, compute a rotation matrix that will transform
310 * space by the angle between the two. There are many candidate
311 * matrices.
312 *
313 * The input 'from' and 'to' vectors need not be unit length.
314 * MAT4X3VEC(to, m, from) is the identity that is created.
315 *
316 */
317BN_EXPORT extern void bn_mat_fromto(mat_t m,
318 const fastf_t *from,
319 const fastf_t *to,
320 const struct bn_tol *tol);
321
322/**
323 * Given the sin and cos of an X rotation angle, produce the rotation
324 * matrix.
325 */
326BN_EXPORT extern void bn_mat_xrot(mat_t m,
327 double sinx,
328 double cosx);
329
330/**
331 * Given the sin and cos of a Y rotation angle, produce the rotation
332 * matrix.
333 */
334BN_EXPORT extern void bn_mat_yrot(mat_t m,
335 double siny,
336 double cosy);
337
338/**
339 * Given the sin and cos of a Z rotation angle, produce the rotation
340 * matrix.
341 */
342BN_EXPORT extern void bn_mat_zrot(mat_t m,
343 double sinz,
344 double cosz);
345
346/**
347 * Given a direction vector D of unit length, product a matrix which
348 * rotates that vector D onto the -Z axis. This matrix will be
349 * suitable for use as a "model2view" matrix.
350 *
351 * XXX This routine will fail if the vector is already more or less
352 * aligned with the Z axis.
353 *
354 * This is done in several steps.
355 *
356 @code
357 1) Rotate D about Z to match +X axis. Azimuth adjustment.
358 2) Rotate D about Y to match -Y axis. Elevation adjustment.
359 3) Rotate D about Z to make projection of X axis again point
360 in the +X direction. Twist adjustment.
361 4) Optionally, flip sign on Y axis if original Z becomes inverted.
362 This can be nice for static frames, but is astonishing when
363 used in animation.
364 @endcode
365*/
366BN_EXPORT extern void bn_mat_lookat(mat_t rot,
367 const vect_t dir,
368 int yflip);
369
370/**
371 * Given a vector, create another vector which is perpendicular to it,
372 * and with unit length. This algorithm taken from Gift's arvec.f; a
373 * faster algorithm may be possible.
374 *
375 * FIXME: make tolerance configurable
376 */
377BN_EXPORT extern void bn_vec_ortho(vect_t out,
378 const vect_t in);
379
380/**
381 * Build a matrix to scale uniformly around a given point.
382 *
383 * @return -1 if scale is too small.
384 * @return 0 if OK.
385 *
386 * FIXME: make tolerance configurable
387 */
388BN_EXPORT extern int bn_mat_scale_about_pnt(mat_t mat,
389 const point_t pnt,
390 const double scale);
391
392/**
393 * Build a matrix to apply arbitrary 4x4 transformation around a given
394 * point.
395 */
396BN_EXPORT extern void bn_mat_xform_about_pnt(mat_t mat,
397 const mat_t xform,
398 const point_t pnt);
399
400/**
401 * @return 0 When matrices are not equal
402 * @return 1 When matrices are equal
403 */
404BN_EXPORT extern int bn_mat_is_equal(const mat_t a,
405 const mat_t b,
406 const struct bn_tol *tol);
407
408/**
409 * This routine is intended for detecting identity matrices read in
410 * from ascii or binary files, where the numbers are pure ones or
411 * zeros. This routine is *not* intended for tolerance-based
412 * "near-zero" comparisons; as such, it shouldn't be used on matrices
413 * which are the result of calculation.
414 *
415 *
416 * @return 0 non-identity
417 * @return 1 a perfect identity matrix
418 */
419BN_EXPORT extern int bn_mat_is_identity(const mat_t m);
420
421/**
422 * Construct a transformation matrix for rotation about an arbitrary
423 * axis. The axis is defined by a point (pt) and a unit direction
424 * vector (dir). The angle of rotation is "ang"
425 *
426 * FIXME: make tolerance configurable
427 */
428BN_EXPORT extern void bn_mat_arb_rot(mat_t m,
429 const point_t pt,
430 const vect_t dir,
431 const fastf_t ang);
432
433/**
434 * Return a pointer to a copy of the matrix in dynamically allocated
435 * memory.
436 */
437BN_EXPORT extern matp_t bn_mat_dup(const mat_t in);
438
439/**
440 * Check to ensure that a rotation matrix preserves axis
441 * perpendicularity. Note that not all matrices are rotation
442 * matrices.
443 *
444 *
445 * @return -1 FAIL
446 * @return 0 OK
447 */
448BN_EXPORT extern int bn_mat_ck(const char *title,
449 const mat_t m);
450
451/**
452 * Calculates the determinant of the 3X3 "rotation" part of the passed
453 * matrix.
454 */
455BN_EXPORT extern fastf_t bn_mat_det3(const mat_t m);
456
457/**
458 * Calculates the determinant of the 4X4 matrix
459 */
460BN_EXPORT extern fastf_t bn_mat_determinant(const mat_t m);
461
462/**
463 * FIXME: make tolerance configurable
464 */
465BN_EXPORT extern int bn_mat_is_non_unif(const mat_t m);
466
467/**
468 * Given a model-space transformation matrix "change",
469 * return a matrix which applies the change with-respect-to
470 * given "point" and "direc".
471 */
472BN_EXPORT extern void bn_wrt_point_direc(mat_t out,
473 const mat_t change,
474 const mat_t in,
475 const point_t point,
476 const vect_t direc,
477 const struct bn_tol *tol);
478
479
480/* Matrix stuff from MGED's dozoom.c - somewhat unfinished,
481 * judging by the comments. Can probably be simplified/combined */
482BN_EXPORT extern void persp_mat(mat_t m, fastf_t fovy, fastf_t aspect, fastf_t near1, fastf_t far1, fastf_t backoff);
483BN_EXPORT extern void mike_persp_mat(fastf_t *pmat, const fastf_t *eye);
484BN_EXPORT extern void deering_persp_mat(fastf_t *m, const fastf_t *l, const fastf_t *h, const fastf_t *eye);
485
486
487/* Option parser/validator for libbu's option system that will read in a matrix
488 * from the argv entries. set_var should be a matp_t
489 *
490 * NOTE: In one sense this could be defined with the other option parsers in
491 * bu/opt.h, as vmath.h (which defines the matrix type) is stand-alone, but
492 * since it is defining a matrix it's a better overall conceptual fit with
493 * libbn - hence it is defined as part of that API. */
494BN_EXPORT extern int bn_opt_mat(struct bu_vls *msg, size_t argc, const char **argv, void *set_var);
495
496__END_DECLS
497
498#endif /* BN_MAT_H */
499/** @} */
500/*
501 * Local Variables:
502 * mode: C
503 * tab-width: 8
504 * indent-tabs-mode: t
505 * c-file-style: "stroustrup"
506 * End:
507 * ex: shiftwidth=4 tabstop=8
508 */
Header file for the BRL-CAD common definitions.
void deering_persp_mat(fastf_t *m, const fastf_t *l, const fastf_t *h, const fastf_t *eye)
void bn_mat_lookat(mat_t rot, const vect_t dir, int yflip)
void bn_mat_print(const char *title, const mat_t m)
void bn_mat_arb_rot(mat_t m, const point_t pt, const vect_t dir, const fastf_t ang)
void bn_vtoh_move(hvect_t h, const vect_t v)
void bn_mat_xform_about_pnt(mat_t mat, const mat_t xform, const point_t pnt)
void bn_vec_perp(vect_t new_vec, const vect_t old_vec)
void bn_mat_ae(mat_t m, double azimuth, double elev)
void bn_mat_mul4(mat_t o, const mat_t a, const mat_t b, const mat_t c, const mat_t d)
void bn_wrt_point_direc(mat_t out, const mat_t change, const mat_t in, const point_t point, const vect_t direc, const struct bn_tol *tol)
void bn_mat_angles(mat_t mat, double alpha, double beta, double ggamma)
void bn_ae_vec(fastf_t *azp, fastf_t *elp, const vect_t v)
void bn_matXvec(hvect_t ov, const mat_t im, const hvect_t iv)
void bn_aet_vec(fastf_t *az, fastf_t *el, fastf_t *twist, vect_t vec_ae, vect_t vec_twist, fastf_t accuracy)
void bn_eigen2x2(fastf_t *val1, fastf_t *val2, vect_t vec1, vect_t vec2, fastf_t a, fastf_t b, fastf_t c)
void bn_mat_fromto(mat_t m, const fastf_t *from, const fastf_t *to, const struct bn_tol *tol)
void bn_htov_move(vect_t v, const hvect_t h)
int bn_mat_scale_about_pnt(mat_t mat, const point_t pnt, const double scale)
void bn_mat_mul3(mat_t o, const mat_t a, const mat_t b, const mat_t c)
void bn_mat_print_vls(const char *title, const mat_t m, struct bu_vls *vls)
void bn_vec_aed(vect_t vec, fastf_t az, fastf_t el, fastf_t dist)
void bn_mat_inv(mat_t output, const mat_t input)
void bn_mat_trn(mat_t om, const mat_t im)
void bn_mat_yrot(mat_t m, double siny, double cosy)
void bn_vec_ortho(vect_t out, const vect_t in)
int bn_opt_mat(struct bu_vls *msg, size_t argc, const char **argv, void *set_var)
const mat_t bn_mat_identity
void bn_mat_print_guts(const char *title, const mat_t m, char *buf, int buflen)
double bn_atan2(double x, double y)
void bn_mat_zrot(mat_t m, double sinz, double cosz)
void persp_mat(mat_t m, fastf_t fovy, fastf_t aspect, fastf_t near1, fastf_t far1, fastf_t backoff)
void bn_mat_mul(mat_t o, const mat_t a, const mat_t b)
void bn_mat_xrot(mat_t m, double sinx, double cosx)
int bn_mat_ck(const char *title, const mat_t m)
matp_t bn_mat_dup(const mat_t in)
fastf_t bn_mat_det3(const mat_t m)
int bn_mat_inverse(mat_t output, const mat_t input)
void bn_vec_ae(vect_t vec, fastf_t az, fastf_t el)
void bn_mat_angles_rad(mat_t mat, double alpha, double beta, double ggamma)
void bn_mat_mul2(const mat_t i, mat_t o)
int bn_mat_is_equal(const mat_t a, const mat_t b, const struct bn_tol *tol)
int bn_mat_is_non_unif(const mat_t m)
int bn_mat_is_identity(const mat_t m)
fastf_t bn_mat_determinant(const mat_t m)
void mike_persp_mat(fastf_t *pmat, const fastf_t *eye)
void int float float float * scale
Definition: tig.h:142
void float float * y
Definition: tig.h:73
void int * c
Definition: tig.h:139
void float * input
Definition: tig.h:163
void float * x
Definition: tig.h:72
fastf_t vect_t[ELEMENTS_PER_VECT]
3-tuple vector
Definition: vmath.h:345
double fastf_t
fastest 64-bit (or larger) floating point type
Definition: vmath.h:330
fastf_t mat_t[ELEMENTS_PER_MAT]
4x4 matrix
Definition: vmath.h:366
fastf_t hvect_t[ELEMENTS_PER_HVECT]
4-tuple vector
Definition: vmath.h:357
fastf_t * matp_t
pointer to a 4x4 matrix
Definition: vmath.h:369
fastf_t point_t[ELEMENTS_PER_POINT]
3-tuple point
Definition: vmath.h:351
Definition: tol.h:72
Definition: vls.h:53
Definition: geom.h:906
fundamental vector, matrix, quaternion math macros