BRL-CAD
tcl.c
Go to the documentation of this file.
1 /* T C L . C
2  * BRL-CAD
3  *
4  * Copyright (c) 1995-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
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 /** @addtogroup bntcl */
22 /** @{ */
23 /** @file libbn/tcl.c
24  *
25  * @brief
26  * Tcl interfaces to all the LIBBN math routines.
27  *
28  */
29 
30 #include "common.h"
31 
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <math.h>
35 #include <string.h>
36 
37 #include "tcl.h"
38 
39 #include "bu/str.h"
40 #include "vmath.h"
41 #include "bn/mat.h"
42 #include "bn/noise.h"
43 #include "bn/plane_struct.h"
44 #include "bn/plane_calc.h"
45 #include "bn/qmath.h"
46 #include "bn/rand.h"
47 #include "bn/bn_tcl.h"
48 #include "bn/tcl_encode.h"
49 
50 int
51 bn_decode_mat(fastf_t *mat, const char *str)
52 {
53  double m[16];
54  int ret;
55 
56  if (BU_STR_EQUAL(str, "I")) {
57  MAT_IDN(m);
58  return 16;
59  }
60  if (*str == '{') str++;
61 
62  ret = sscanf(str,
63  "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",
64  &m[0], &m[1], &m[2], &m[3], &m[4], &m[5], &m[6], &m[7],
65  &m[8], &m[9], &m[10], &m[11], &m[12], &m[13], &m[14], &m[15]);
66  MAT_COPY(mat, m);
67 
68  return ret;
69 }
70 
71 
72 int
73 bn_decode_quat(fastf_t *quat, const char *str)
74 {
75  double q[4];
76  int ret;
77 
78  if (*str == '{') str++;
79  ret = sscanf(str, "%lf %lf %lf %lf", &q[0], &q[1], &q[2], &q[3]);
80  HMOVE(quat, q);
81 
82  return ret;
83 }
84 
85 
86 int
87 bn_decode_vect(fastf_t *vec, const char *str)
88 {
89  double v[3];
90  int ret;
91 
92  if (*str == '{') str++;
93  ret = sscanf(str, "%lf %lf %lf", &v[0], &v[1], &v[2]);
94  VMOVE(vec, v);
95 
96  return ret;
97 }
98 
99 
100 int
101 bn_decode_hvect(fastf_t *v, const char *str)
102 {
103  return bn_decode_quat(v, str);
104 }
105 
106 
107 void
108 bn_encode_mat(struct bu_vls *vp, const mat_t m)
109 {
110  if (m == NULL) {
111  bu_vls_putc(vp, 'I');
112  return;
113  }
114 
115  bu_vls_printf(vp, "%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g",
116  INTCLAMP(m[0]), INTCLAMP(m[1]), INTCLAMP(m[2]), INTCLAMP(m[3]),
117  INTCLAMP(m[4]), INTCLAMP(m[5]), INTCLAMP(m[6]), INTCLAMP(m[7]),
118  INTCLAMP(m[8]), INTCLAMP(m[9]), INTCLAMP(m[10]), INTCLAMP(m[11]),
119  INTCLAMP(m[12]), INTCLAMP(m[13]), INTCLAMP(m[14]), INTCLAMP(m[15]));
120 }
121 
122 
123 void
124 bn_encode_quat(struct bu_vls *vp, const mat_t q)
125 {
126  bu_vls_printf(vp, "%g %g %g %g", V4INTCLAMPARGS(q));
127 }
128 
129 
130 void
131 bn_encode_vect(struct bu_vls *vp, const mat_t v)
132 {
133  bu_vls_printf(vp, "%g %g %g", V3INTCLAMPARGS(v));
134 }
135 
136 
137 void
138 bn_encode_hvect(struct bu_vls *vp, const mat_t v)
139 {
140  bu_vls_printf(vp, "%g %g %g %g", V4INTCLAMPARGS(v));
141 }
142 
143 
144 void
145 bn_quat_distance_wrapper(double *dp, mat_t q1, mat_t q2)
146 {
147  *dp = quat_distance(q1, q2);
148 }
149 
150 
151 void
152 bn_mat_scale_about_pt_wrapper(int *statusp, mat_t mat, const point_t pt, const double scale)
153 {
154  *statusp = bn_mat_scale_about_pt(mat, pt, scale);
155 }
156 
157 
158 static void
159 bn_mat4x3pnt(fastf_t *o, mat_t m, point_t i)
160 {
161  MAT4X3PNT(o, m, i);
162 }
163 
164 
165 static void
166 bn_mat4x3vec(fastf_t *o, mat_t m, vect_t i)
167 {
168  MAT4X3VEC(o, m, i);
169 }
170 
171 
172 static void
173 bn_hdivide(fastf_t *o, const mat_t i)
174 {
175  HDIVIDE(o, i);
176 }
177 
178 
179 static void
180 bn_vjoin1(fastf_t *o, const point_t pnt, double scale, const vect_t dir)
181 {
182  VJOIN1(o, pnt, scale, dir);
183 }
184 
185 
186 static void bn_vblend(mat_t a, fastf_t b, mat_t c, fastf_t d, mat_t e)
187 {
188  VBLEND2(a, b, c, d, e);
189 }
190 
191 
192 #define MATH_FUNC_VOID_CAST(_func) ((void (*)(void))_func)
193 
194 static struct math_func_link {
195  const char *name;
196  void (*func)(void);
197 } math_funcs[] = {
198  {"bn_dist_pt2_lseg2", MATH_FUNC_VOID_CAST(bn_dist_pt2_lseg2)},
199  {"bn_isect_line2_line2", MATH_FUNC_VOID_CAST(bn_isect_line2_line2)},
200  {"bn_isect_line3_line3", MATH_FUNC_VOID_CAST(bn_isect_line3_line3)},
201  {"mat_mul", MATH_FUNC_VOID_CAST(bn_mat_mul)},
202  {"mat_inv", MATH_FUNC_VOID_CAST(bn_mat_inv)},
203  {"mat_trn", MATH_FUNC_VOID_CAST(bn_mat_trn)},
204  {"matXvec", MATH_FUNC_VOID_CAST(bn_matXvec)},
205  {"mat4x3vec", MATH_FUNC_VOID_CAST(bn_mat4x3vec)},
206  {"mat4x3pnt", MATH_FUNC_VOID_CAST(bn_mat4x3pnt)},
207  {"hdivide", MATH_FUNC_VOID_CAST(bn_hdivide)},
208  {"vjoin1", MATH_FUNC_VOID_CAST(bn_vjoin1)},
209  {"vblend", MATH_FUNC_VOID_CAST(bn_vblend)},
210  {"mat_ae", MATH_FUNC_VOID_CAST(bn_mat_ae)},
211  {"mat_ae_vec", MATH_FUNC_VOID_CAST(bn_ae_vec)},
212  {"mat_aet_vec", MATH_FUNC_VOID_CAST(bn_aet_vec)},
213  {"mat_angles", MATH_FUNC_VOID_CAST(bn_mat_angles)},
214  {"mat_eigen2x2", MATH_FUNC_VOID_CAST(bn_eigen2x2)},
215  {"mat_fromto", MATH_FUNC_VOID_CAST(bn_mat_fromto)},
216  {"mat_xrot", MATH_FUNC_VOID_CAST(bn_mat_xrot)},
217  {"mat_yrot", MATH_FUNC_VOID_CAST(bn_mat_yrot)},
218  {"mat_zrot", MATH_FUNC_VOID_CAST(bn_mat_zrot)},
219  {"mat_lookat", MATH_FUNC_VOID_CAST(bn_mat_lookat)},
220  {"mat_vec_ortho", MATH_FUNC_VOID_CAST(bn_vec_ortho)},
221  {"mat_vec_perp", MATH_FUNC_VOID_CAST(bn_vec_perp)},
222  {"mat_scale_about_pt", MATH_FUNC_VOID_CAST(bn_mat_scale_about_pt_wrapper)},
223  {"mat_xform_about_pt", MATH_FUNC_VOID_CAST(bn_mat_xform_about_pt)},
224  {"mat_arb_rot", MATH_FUNC_VOID_CAST(bn_mat_arb_rot)},
225  {"quat_mat2quat", MATH_FUNC_VOID_CAST(quat_mat2quat)},
226  {"quat_quat2mat", MATH_FUNC_VOID_CAST(quat_quat2mat)},
227  {"quat_distance", MATH_FUNC_VOID_CAST(bn_quat_distance_wrapper)},
228  {"quat_double", MATH_FUNC_VOID_CAST(quat_double)},
229  {"quat_bisect", MATH_FUNC_VOID_CAST(quat_bisect)},
230  {"quat_slerp", MATH_FUNC_VOID_CAST(quat_slerp)},
231  {"quat_sberp", MATH_FUNC_VOID_CAST(quat_sberp)},
232  {"quat_make_nearest", MATH_FUNC_VOID_CAST(quat_make_nearest)},
233  {"quat_exp", MATH_FUNC_VOID_CAST(quat_exp)},
234  {"quat_log", MATH_FUNC_VOID_CAST(quat_log)},
235  {0, 0}
236 };
237 
238 
239 /**
240  *@brief
241  * Tcl wrappers for the math functions.
242  *
243  * This is where you should put clauses, in the below "if" statement, to add
244  * Tcl support for the LIBBN math routines.
245  */
246 int
247 bn_math_cmd(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
248 {
249  void (*math_func)(void);
250  struct bu_vls result = BU_VLS_INIT_ZERO;
251  struct math_func_link *mfl;
252 
253  mfl = (struct math_func_link *)clientData;
254  math_func = mfl->func;
255 
256  if (math_func == MATH_FUNC_VOID_CAST(bn_mat_mul)) {
257  mat_t o, a, b;
258  if (argc < 3 || bn_decode_mat(a, argv[1]) < 16 ||
259  bn_decode_mat(b, argv[2]) < 16) {
260  bu_vls_printf(&result, "usage: %s matA matB", argv[0]);
261  goto error;
262  }
263  bn_mat_mul(o, a, b);
264  bn_encode_mat(&result, o);
265  } else if (math_func == MATH_FUNC_VOID_CAST(bn_mat_inv)
266  || math_func == MATH_FUNC_VOID_CAST(bn_mat_trn)) {
267  mat_t o, a;
268  /* need new math func pointer of correct signature */
269  void (*_math_func)(mat_t, register const mat_t);
270  /* cast math_func to new func pointer */
271  _math_func = (void (*)(mat_t, register const mat_t))math_func;
272 
273  if (argc < 2 || bn_decode_mat(a, argv[1]) < 16) {
274  bu_vls_printf(&result, "usage: %s mat", argv[0]);
275  goto error;
276  }
277  _math_func(o, a);
278  bn_encode_mat(&result, o);
279  } else if (math_func == MATH_FUNC_VOID_CAST(bn_matXvec)) {
280  mat_t m;
281  hvect_t i, o;
282  if (argc < 3 || bn_decode_mat(m, argv[1]) < 16 ||
283  bn_decode_hvect(i, argv[2]) < 4) {
284  bu_vls_printf(&result, "usage: %s mat hvect", argv[0]);
285  goto error;
286  }
287  bn_matXvec(o, m, i);
288  bn_encode_hvect(&result, o);
289  } else if (math_func == MATH_FUNC_VOID_CAST(bn_mat4x3pnt)) {
290  mat_t m;
291  point_t i, o;
292  MAT_ZERO(m);
293  if (argc < 3 || bn_decode_mat(m, argv[1]) < 16 ||
294  bn_decode_vect(i, argv[2]) < 3) {
295  bu_vls_printf(&result, "usage: %s mat point", argv[0]);
296  goto error;
297  }
298  bn_mat4x3pnt(o, m, i);
299  bn_encode_vect(&result, o);
300  } else if (math_func == MATH_FUNC_VOID_CAST(bn_mat4x3vec)) {
301  mat_t m;
302  vect_t i, o;
303  MAT_ZERO(m);
304  if (argc < 3 || bn_decode_mat(m, argv[1]) < 16 ||
305  bn_decode_vect(i, argv[2]) < 3) {
306  bu_vls_printf(&result, "usage: %s mat vect", argv[0]);
307  goto error;
308  }
309  bn_mat4x3vec(o, m, i);
310  bn_encode_vect(&result, o);
311  } else if (math_func == MATH_FUNC_VOID_CAST(bn_hdivide)) {
312  hvect_t i;
313  vect_t o;
314  if (argc < 2 || bn_decode_hvect(i, argv[1]) < 4) {
315  bu_vls_printf(&result, "usage: %s hvect", argv[0]);
316  goto error;
317  }
318  bn_hdivide(o, i);
319  bn_encode_vect(&result, o);
320  } else if (math_func == MATH_FUNC_VOID_CAST(bn_vjoin1)) {
321  point_t o;
322  point_t b, d;
323  double c;
324 
325  if (argc < 4) {
326  bu_vls_printf(&result, "usage: %s pnt scale dir", argv[0]);
327  goto error;
328  }
329  if (bn_decode_vect(b, argv[1]) < 3) goto error;
330  if (Tcl_GetDouble(interp, argv[2], &c) != TCL_OK) goto error;
331  if (bn_decode_vect(d, argv[3]) < 3) goto error;
332 
333  VJOIN1(o, b, c, d); /* bn_vjoin1(o, b, c, d) */
334  bn_encode_vect(&result, o);
335 
336  } else if (math_func == MATH_FUNC_VOID_CAST(bn_vblend)) {
337  point_t a, c, e;
338  double b, d;
339 
340  if (argc < 5) {
341  bu_vls_printf(&result, "usage: %s scale pnt scale pnt", argv[0]);
342  goto error;
343  }
344 
345  if (Tcl_GetDouble(interp, argv[1], &b) != TCL_OK) goto error;
346  if (bn_decode_vect(c, argv[2]) < 3) goto error;
347  if (Tcl_GetDouble(interp, argv[3], &d) != TCL_OK) goto error;
348  if (bn_decode_vect(e, argv[4]) < 3) goto error;
349 
350  VBLEND2(a, b, c, d, e);
351  bn_encode_vect(&result, a);
352 
353  } else if (math_func == MATH_FUNC_VOID_CAST(bn_mat_ae)) {
354  mat_t o;
355  double az, el;
356 
357  if (argc < 3) {
358  bu_vls_printf(&result, "usage: %s azimuth elevation", argv[0]);
359  goto error;
360  }
361  if (Tcl_GetDouble(interp, argv[1], &az) != TCL_OK) goto error;
362  if (Tcl_GetDouble(interp, argv[2], &el) != TCL_OK) goto error;
363 
364  bn_mat_ae(o, (fastf_t)az, (fastf_t)el);
365  bn_encode_mat(&result, o);
366  } else if (math_func == MATH_FUNC_VOID_CAST(bn_ae_vec)) {
367  fastf_t az, el;
368  vect_t v;
369 
370  if (argc < 2 || bn_decode_vect(v, argv[1]) < 3) {
371  bu_vls_printf(&result, "usage: %s vect", argv[0]);
372  goto error;
373  }
374 
375  bn_ae_vec(&az, &el, v);
376  bu_vls_printf(&result, "%g %g", az, el);
377  } else if (math_func == MATH_FUNC_VOID_CAST(bn_aet_vec)) {
378  double acc;
379  fastf_t az, el, twist, accuracy;
380  vect_t vec_ae, vec_twist;
381 
382  if (argc < 4 || bn_decode_vect(vec_ae, argv[1]) < 3 ||
383  bn_decode_vect(vec_twist, argv[2]) < 3 ||
384  sscanf(argv[3], "%lf", &acc) < 1) {
385  bu_vls_printf(&result, "usage: %s vec_ae vec_twist accuracy",
386  argv[0]);
387  goto error;
388  }
389  accuracy = acc;
390 
391  bn_aet_vec(&az, &el, &twist, vec_ae, vec_twist, accuracy);
392  bu_vls_printf(&result, "%g %g %g", az, el, twist);
393  } else if (math_func == MATH_FUNC_VOID_CAST(bn_mat_angles)) {
394  mat_t o;
395  double alpha, beta, ggamma;
396 
397  if (argc < 4) {
398  bu_vls_printf(&result, "usage: %s alpha beta gamma", argv[0]);
399  goto error;
400  }
401  if (Tcl_GetDouble(interp, argv[1], &alpha) != TCL_OK) goto error;
402  if (Tcl_GetDouble(interp, argv[2], &beta) != TCL_OK) goto error;
403  if (Tcl_GetDouble(interp, argv[3], &ggamma) != TCL_OK) goto error;
404 
405  bn_mat_angles(o, alpha, beta, ggamma);
406  bn_encode_mat(&result, o);
407  } else if (math_func == MATH_FUNC_VOID_CAST(bn_eigen2x2)) {
408  fastf_t val1, val2;
409  vect_t vec1, vec2;
410  double a, b, c;
411 
412  if (argc < 4) {
413  bu_vls_printf(&result, "usage: %s a b c", argv[0]);
414  goto error;
415  }
416  if (Tcl_GetDouble(interp, argv[1], &a) != TCL_OK) goto error;
417  if (Tcl_GetDouble(interp, argv[2], &c) != TCL_OK) goto error;
418  if (Tcl_GetDouble(interp, argv[3], &b) != TCL_OK) goto error;
419 
420  bn_eigen2x2(&val1, &val2, vec1, vec2, (fastf_t)a, (fastf_t)b,
421  (fastf_t)c);
422  bu_vls_printf(&result, "%g %g {%g %g %g} {%g %g %g}", INTCLAMP(val1), INTCLAMP(val2),
423  V3INTCLAMPARGS(vec1), V3INTCLAMPARGS(vec2));
424  } else if (math_func == MATH_FUNC_VOID_CAST(bn_mat_fromto)) {
425  mat_t o;
426  vect_t from, to;
427  static const struct bn_tol tol = {
428  BN_TOL_MAGIC, BN_TOL_DIST, BN_TOL_DIST*BN_TOL_DIST, 1e-6, 1-1e-6
429  };
430 
431  if (argc < 3 || bn_decode_vect(from, argv[1]) < 3 ||
432  bn_decode_vect(to, argv[2]) < 3) {
433  bu_vls_printf(&result, "usage: %s vecFrom vecTo", argv[0]);
434  goto error;
435  }
436  bn_mat_fromto(o, from, to, &tol);
437  bn_encode_mat(&result, o);
438  } else if (math_func == MATH_FUNC_VOID_CAST(bn_mat_xrot)
439  || math_func == MATH_FUNC_VOID_CAST(bn_mat_yrot)
440  || math_func == MATH_FUNC_VOID_CAST(bn_mat_zrot)) {
441  mat_t o;
442  double s, c;
443  /* need new math func pointer of correct signature */
444  void (*_math_func)(fastf_t *, double, double);
445  /* cast math_func to new func pointer */
446  _math_func = (void (*)(fastf_t *, double, double))math_func;
447 
448  if (argc < 3) {
449  bu_vls_printf(&result, "usage: %s sinAngle cosAngle", argv[0]);
450  goto error;
451  }
452  if (Tcl_GetDouble(interp, argv[1], &s) != TCL_OK) goto error;
453  if (Tcl_GetDouble(interp, argv[2], &c) != TCL_OK) goto error;
454 
455  _math_func(o, s, c);
456  bn_encode_mat(&result, o);
457  } else if (math_func == MATH_FUNC_VOID_CAST(bn_mat_lookat)) {
458  mat_t o;
459  vect_t dir;
460  int yflip;
461  if (argc < 3 || bn_decode_vect(dir, argv[1]) < 3) {
462  bu_vls_printf(&result, "usage: %s dir yflip", argv[0]);
463  goto error;
464  }
465  if (Tcl_GetBoolean(interp, argv[2], &yflip) != TCL_OK) goto error;
466 
467  bn_mat_lookat(o, dir, yflip);
468  bn_encode_mat(&result, o);
469  } else if (math_func == MATH_FUNC_VOID_CAST(bn_vec_ortho)
470  || math_func == MATH_FUNC_VOID_CAST(bn_vec_perp)) {
471  vect_t ov, vec;
472  /* need new math func pointer of correct signature */
473  void (*_math_func)(vect_t, const vect_t);
474  /* cast math_func to new func pointer */
475  _math_func = (void (*)(vect_t, const vect_t))math_func;
476 
477  if (argc < 2 || bn_decode_vect(vec, argv[1]) < 3) {
478  bu_vls_printf(&result, "usage: %s vec", argv[0]);
479  goto error;
480  }
481 
482  _math_func(ov, vec);
483  bn_encode_vect(&result, ov);
484  } else if (math_func == MATH_FUNC_VOID_CAST(bn_mat_scale_about_pt_wrapper)) {
485  mat_t o;
486  vect_t v;
487  double scale;
488  int status;
489 
490  if (argc < 3 || bn_decode_vect(v, argv[1]) < 3) {
491  bu_vls_printf(&result, "usage: %s pt scale", argv[0]);
492  goto error;
493  }
494  if (Tcl_GetDouble(interp, argv[2], &scale) != TCL_OK) goto error;
495 
496  bn_mat_scale_about_pt_wrapper(&status, o, v, scale);
497  if (status != 0) {
498  bu_vls_printf(&result, "error performing calculation");
499  goto error;
500  }
501  bn_encode_mat(&result, o);
502  } else if (math_func == MATH_FUNC_VOID_CAST(bn_mat_xform_about_pt)) {
503  mat_t o, xform;
504  vect_t v;
505 
506  if (argc < 3 || bn_decode_mat(xform, argv[1]) < 16 ||
507  bn_decode_vect(v, argv[2]) < 3) {
508  bu_vls_printf(&result, "usage: %s xform pt", argv[0]);
509  goto error;
510  }
511 
512  bn_mat_xform_about_pt(o, xform, v);
513  bn_encode_mat(&result, o);
514  } else if (math_func == MATH_FUNC_VOID_CAST(bn_mat_arb_rot)) {
515  mat_t o;
516  point_t pt;
517  vect_t dir;
518  double angle;
519 
520  if (argc < 4 || bn_decode_vect(pt, argv[1]) < 3 ||
521  bn_decode_vect(dir, argv[2]) < 3) {
522  bu_vls_printf(&result, "usage: %s pt dir angle", argv[0]);
523  goto error;
524  }
525  if (Tcl_GetDouble(interp, argv[3], &angle) != TCL_OK)
526  return TCL_ERROR;
527 
528  bn_mat_arb_rot(o, pt, dir, (fastf_t)angle);
529  bn_encode_mat(&result, o);
530  } else if (math_func == MATH_FUNC_VOID_CAST(quat_mat2quat)) {
531  mat_t mat;
532  quat_t quat;
533 
534  if (argc < 2 || bn_decode_mat(mat, argv[1]) < 16) {
535  bu_vls_printf(&result, "usage: %s mat", argv[0]);
536  goto error;
537  }
538 
539  quat_mat2quat(quat, mat);
540  bn_encode_quat(&result, quat);
541  } else if (math_func == MATH_FUNC_VOID_CAST(quat_quat2mat)) {
542  mat_t mat;
543  quat_t quat;
544 
545  if (argc < 2 || bn_decode_quat(quat, argv[1]) < 4) {
546  bu_vls_printf(&result, "usage: %s quat", argv[0]);
547  goto error;
548  }
549 
550  quat_quat2mat(mat, quat);
551  bn_encode_mat(&result, mat);
552  } else if (math_func == MATH_FUNC_VOID_CAST(bn_quat_distance_wrapper)) {
553  quat_t q1, q2;
554  double d;
555 
556  if (argc < 3 || bn_decode_quat(q1, argv[1]) < 4 ||
557  bn_decode_quat(q2, argv[2]) < 4) {
558  bu_vls_printf(&result, "usage: %s quatA quatB", argv[0]);
559  goto error;
560  }
561 
562  bn_quat_distance_wrapper(&d, q1, q2);
563  bu_vls_printf(&result, "%g", d);
564  } else if (math_func == MATH_FUNC_VOID_CAST(quat_double)
565  || math_func == MATH_FUNC_VOID_CAST(quat_bisect)
566  || math_func == MATH_FUNC_VOID_CAST(quat_make_nearest)) {
567  quat_t oqot, q1, q2;
568  void (*_math_func)(fastf_t *, const fastf_t *, const fastf_t *);
569  /* cast math_func to new func pointer */
570  _math_func = (void (*)(fastf_t *, const fastf_t *, const fastf_t *))math_func;
571 
572  if (argc < 3 || bn_decode_quat(q1, argv[1]) < 4 ||
573  bn_decode_quat(q2, argv[2]) < 4) {
574  bu_vls_printf(&result, "usage: %s quatA quatB", argv[0]);
575  goto error;
576  }
577 
578  _math_func(oqot, q1, q2);
579  bn_encode_quat(&result, oqot);
580  } else if (math_func == MATH_FUNC_VOID_CAST(quat_slerp)) {
581  quat_t oq, q1, q2;
582  double d;
583 
584  if (argc < 4 || bn_decode_quat(q1, argv[1]) < 4 ||
585  bn_decode_quat(q2, argv[2]) < 4) {
586  bu_vls_printf(&result, "usage: %s quat1 quat2 factor", argv[0]);
587  goto error;
588  }
589  if (Tcl_GetDouble(interp, argv[3], &d) != TCL_OK) goto error;
590 
591  quat_slerp(oq, q1, q2, d);
592  bn_encode_quat(&result, oq);
593  } else if (math_func == MATH_FUNC_VOID_CAST(quat_sberp)) {
594  quat_t oq, q1, qa, qb, q2;
595  double d;
596 
597  if (argc < 6 || bn_decode_quat(q1, argv[1]) < 4 ||
598  bn_decode_quat(qa, argv[2]) < 4 || bn_decode_quat(qb, argv[3]) < 4 ||
599  bn_decode_quat(q2, argv[4]) < 4) {
600  bu_vls_printf(&result, "usage: %s quat1 quatA quatB quat2 factor",
601  argv[0]);
602  goto error;
603  }
604  if (Tcl_GetDouble(interp, argv[5], &d) != TCL_OK) goto error;
605 
606  quat_sberp(oq, q1, qa, qb, q2, d);
607  bn_encode_quat(&result, oq);
608  } else if (math_func == MATH_FUNC_VOID_CAST(quat_exp)
609  || math_func == MATH_FUNC_VOID_CAST(quat_log)) {
610  quat_t qout, qin;
611  /* need new math func pointer of correct signature */
612  void (*_math_func)(fastf_t *, const fastf_t *);
613  /* cast math_func to new func pointer */
614  _math_func = (void (*)(fastf_t *, const fastf_t *))math_func;
615 
616  if (argc < 2 || bn_decode_quat(qin, argv[1]) < 4) {
617  bu_vls_printf(&result, "usage: %s quat", argv[0]);
618  goto error;
619  }
620 
621  _math_func(qout, qin);
622  bn_encode_quat(&result, qout);
623  } else if (math_func == MATH_FUNC_VOID_CAST(bn_isect_line3_line3)) {
624  fastf_t t, u;
625  point_t pt, a;
626  vect_t dir, c;
627  int i;
628  static const struct bn_tol tol = {
629  BN_TOL_MAGIC, BN_TOL_DIST, BN_TOL_DIST*BN_TOL_DIST, 1e-6, 1-1e-6
630  };
631  if (argc != 5) {
632  bu_vls_printf(&result,
633  "Usage: bn_isect_line3_line3 pt dir pt dir (%d args specified)",
634  argc-1);
635  goto error;
636  }
637 
638  if (bn_decode_vect(pt, argv[1]) < 3) {
639  bu_vls_printf(&result, "bn_isect_line3_line3 no pt: %s\n", argv[0]);
640  goto error;
641  }
642  if (bn_decode_vect(dir, argv[2]) < 3) {
643  bu_vls_printf(&result, "bn_isect_line3_line3 no dir: %s\n", argv[0]);
644  goto error;
645  }
646  if (bn_decode_vect(a, argv[3]) < 3) {
647  bu_vls_printf(&result, "bn_isect_line3_line3 no a pt: %s\n", argv[0]);
648  goto error;
649  }
650  if (bn_decode_vect(c, argv[4]) < 3) {
651  bu_vls_printf(&result, "bn_isect_line3_line3 no c dir: %s\n", argv[0]);
652  goto error;
653  }
654  i = bn_isect_line3_line3(&t, &u, pt, dir, a, c, &tol);
655  if (i != 1) {
656  bu_vls_printf(&result, "bn_isect_line3_line3 no intersection: %s\n", argv[0]);
657  goto error;
658  }
659 
660  VJOIN1(a, pt, t, dir);
661  bn_encode_vect(&result, a);
662 
663  } else if (math_func == MATH_FUNC_VOID_CAST(bn_isect_line2_line2)) {
664  fastf_t dist[2];
665  point_t pt, a;
666  vect_t dir, c;
667  int i;
668  static const struct bn_tol tol = {
669  BN_TOL_MAGIC, BN_TOL_DIST, BN_TOL_DIST*BN_TOL_DIST, 1e-6, 1-1e-6
670  };
671 
672  if (argc != 5) {
673  bu_vls_printf(&result,
674  "Usage: bn_isect_line2_line2 pt dir pt dir (%d args specified)",
675  argc-1);
676  goto error;
677  }
678 
679  /* i = bn_isect_line2_line2 {0 0} {1 0} {1 1} {0 -1} */
680 
681  VSETALL(pt, 0.0);
682  VSETALL(dir, 0.0);
683  VSETALL(a, 0.0);
684  VSETALL(c, 0.0);
685 
686  if (bn_decode_vect(pt, argv[1]) < 2) {
687  bu_vls_printf(&result, "bn_isect_line2_line2 no pt: %s\n", argv[0]);
688  goto error;
689  }
690  if (bn_decode_vect(dir, argv[2]) < 2) {
691  bu_vls_printf(&result, "bn_isect_line2_line2 no dir: %s\n", argv[0]);
692  goto error;
693  }
694  if (bn_decode_vect(a, argv[3]) < 2) {
695  bu_vls_printf(&result, "bn_isect_line2_line2 no a pt: %s\n", argv[0]);
696  goto error;
697  }
698  if (bn_decode_vect(c, argv[4]) < 2) {
699  bu_vls_printf(&result, "bn_isect_line2_line2 no c dir: %s\n", argv[0]);
700  goto error;
701  }
702  i = bn_isect_line2_line2(dist, pt, dir, a, c, &tol);
703  if (i != 1) {
704  bu_vls_printf(&result, "bn_isect_line2_line2 no intersection: %s\n", argv[0]);
705  goto error;
706  }
707 
708  VJOIN1(a, pt, dist[0], dir);
709  bu_vls_printf(&result, "%g %g", V2INTCLAMPARGS(a));
710 
711  } else if (math_func == MATH_FUNC_VOID_CAST(bn_dist_pt2_lseg2)) {
712  point_t ptA, ptB, pca;
713  point_t pt;
714  fastf_t dist;
715  int ret;
716  static const struct bn_tol tol = {
717  BN_TOL_MAGIC, BN_TOL_DIST, BN_TOL_DIST*BN_TOL_DIST, 1e-6, 1-1e-6
718  };
719 
720  if (argc != 4) {
721  bu_vls_printf(&result,
722  "Usage: bn_dist_pt2_lseg2 ptA ptB pt (%d args specified)", argc-1);
723  goto error;
724  }
725 
726  if (bn_decode_vect(ptA, argv[1]) < 2) {
727  bu_vls_printf(&result, "bn_dist_pt2_lseg2 no ptA: %s\n", argv[0]);
728  goto error;
729  }
730 
731  if (bn_decode_vect(ptB, argv[2]) < 2) {
732  bu_vls_printf(&result, "bn_dist_pt2_lseg2 no ptB: %s\n", argv[0]);
733  goto error;
734  }
735 
736  if (bn_decode_vect(pt, argv[3]) < 2) {
737  bu_vls_printf(&result, "bn_dist_pt2_lseg2 no pt: %s\n", argv[0]);
738  goto error;
739  }
740 
741  ret = bn_dist_pt2_lseg2(&dist, pca, ptA, ptB, pt, &tol);
742  switch (ret) {
743  case 0:
744  case 1:
745  case 2:
746  dist = 0.0;
747  break;
748  default:
749  break;
750  }
751 
752  bu_vls_printf(&result, "%g", dist);
753  } else {
754  bu_vls_printf(&result, "libbn/bn_tcl.c: math function %s not supported yet\n", argv[0]);
755  goto error;
756  }
757 
758  Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL);
759  bu_vls_free(&result);
760  return TCL_OK;
761 
762 error:
763  Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL);
764  bu_vls_free(&result);
765  return TCL_ERROR;
766 }
767 
768 
769 int
770 bn_cmd_noise_perlin(ClientData UNUSED(clientData),
771  Tcl_Interp *interp,
772  int argc,
773  char **argv)
774 {
775  point_t pt;
776  double v;
777 
778  if (argc != 4) {
779  Tcl_AppendResult(interp, "wrong # args: should be \"",
780  argv[0], " X Y Z \"",
781  NULL);
782  return TCL_ERROR;
783  }
784 
785  pt[X] = atof(argv[1]);
786  pt[Y] = atof(argv[2]);
787  pt[Z] = atof(argv[3]);
788 
789  v = bn_noise_perlin(pt);
790  Tcl_SetObjResult(interp, Tcl_NewDoubleObj(v));
791 
792  return TCL_OK;
793 }
794 
795 
796 /*
797  * usage: bn_noise_fbm X Y Z h_val lacunarity octaves
798  *
799  */
800 int
801 bn_cmd_noise(ClientData UNUSED(clientData),
802  Tcl_Interp *interp,
803  int argc,
804  char **argv)
805 {
806  point_t pt;
807  double h_val;
808  double lacunarity;
809  double octaves;
810  double val;
811 
812  if (argc != 7) {
813  Tcl_AppendResult(interp, "wrong # args: should be \"",
814  argv[0], " X Y Z h_val lacunarity octaves\"",
815  NULL);
816  return TCL_ERROR;
817  }
818 
819  pt[0] = atof(argv[1]);
820  pt[1] = atof(argv[2]);
821  pt[2] = atof(argv[3]);
822 
823  h_val = atof(argv[4]);
824  lacunarity = atof(argv[5]);
825  octaves = atof(argv[6]);
826 
827 
828  if (BU_STR_EQUAL("bn_noise_turb", argv[0])) {
829  val = bn_noise_turb(pt, h_val, lacunarity, octaves);
830 
831  Tcl_SetObjResult(interp, Tcl_NewDoubleObj(val));
832  } else if (BU_STR_EQUAL("bn_noise_fbm", argv[0])) {
833  val = bn_noise_fbm(pt, h_val, lacunarity, octaves);
834  Tcl_SetObjResult(interp, Tcl_NewDoubleObj(val));
835  } else {
836  Tcl_AppendResult(interp, "Unknown noise type \"",
837  argv[0], "\"", NULL);
838  return TCL_ERROR;
839  }
840  return TCL_OK;
841 }
842 
843 
844 /**
845  * @brief
846  * usage: noise_slice xdim ydim inv h_val lac octaves dX dY dZ sX [sY sZ]
847  *
848  * The idea here is to get a whole slice of noise at once, thereby
849  * avoiding the overhead of doing this in Tcl.
850  */
851 int
852 bn_cmd_noise_slice(ClientData UNUSED(clientData),
853  Tcl_Interp *interp,
854  int argc,
855  char **argv)
856 {
857  double h_val;
858  double lacunarity;
859  double octaves;
860 
861  vect_t delta; /* translation to noise space */
862  vect_t scale; /* scale to noise space */
863  unsigned xdim; /* # samples X direction */
864  unsigned ydim; /* # samples Y direction */
865  unsigned xval, yval;
866 #define NOISE_FBM 0
867 #define NOISE_TURB 1
868 
869 #define COV186_UNUSED_CODE 0
870 #if COV186_UNUSED_CODE
871  int noise_type = NOISE_FBM;
872 #endif
873  double val;
874  point_t pt;
875 
876  if (argc != 7) {
877  Tcl_AppendResult(interp, "wrong # args: should be \"",
878  argv[0], " Xdim Ydim Zval h_val lacunarity octaves\"",
879  NULL);
880  return TCL_ERROR;
881  }
882 
883  xdim = atoi(argv[0]);
884  ydim = atoi(argv[1]);
885  VSETALL(delta, 0.0);
886  VSETALL(scale, 1.);
887  pt[Z] = delta[Z] = atof(argv[2]);
888  h_val = atof(argv[3]);
889  lacunarity = atof(argv[4]);
890  octaves = atof(argv[5]);
891 
892 #define COV186_UNUSED_CODE 0
893  /* Only NOISE_FBM is possible at this time, so comment out the switching for
894  * NOISE_TURB. This may need to be deleted. */
895 #if COV186_UNUSED_CODE
896  switch (noise_type) {
897  case NOISE_FBM:
898 #endif
899  for (yval = 0; yval < ydim; yval++) {
900 
901  pt[Y] = yval * scale[Y] + delta[Y];
902 
903  for (xval = 0; xval < xdim; xval++) {
904  pt[X] = xval * scale[X] + delta[X];
905 
906  bn_noise_fbm(pt, h_val, lacunarity, octaves);
907 
908  }
909  }
910 #if COV186_UNUSED_CODE
911  break;
912  case NOISE_TURB:
913  for (yval = 0; yval < ydim; yval++) {
914 
915  pt[Y] = yval * scale[Y] + delta[Y];
916 
917  for (xval = 0; xval < xdim; xval++) {
918  pt[X] = xval * scale[X] + delta[X];
919 
920  val = bn_noise_turb(pt, h_val, lacunarity, octaves);
921 
922  }
923  }
924  break;
925  }
926 #endif
927 
928 
929  pt[0] = atof(argv[1]);
930  pt[1] = atof(argv[2]);
931  pt[2] = atof(argv[3]);
932 
933  h_val = atof(argv[4]);
934  lacunarity = atof(argv[5]);
935  octaves = atof(argv[6]);
936 
937 
938  if (BU_STR_EQUAL("bn_noise_turb", argv[0])) {
939  val = bn_noise_turb(pt, h_val, lacunarity, octaves);
940  Tcl_SetObjResult(interp, Tcl_NewDoubleObj(val));
941  } else if (BU_STR_EQUAL("bn_noise_fbm", argv[0])) {
942  val = bn_noise_fbm(pt, h_val, lacunarity, octaves);
943  Tcl_SetObjResult(interp, Tcl_NewDoubleObj(val));
944  } else {
945  Tcl_AppendResult(interp, "Unknown noise type \"",
946  argv[0], "\"", NULL);
947  return TCL_ERROR;
948  }
949  return TCL_OK;
950 }
951 
952 
953 int
954 bn_cmd_random(ClientData UNUSED(clientData),
955  Tcl_Interp *interp,
956  int argc,
957  char **argv)
958 {
959  int val;
960  const char *str;
961  double rnd;
962  char buf[32];
963 
964  if (argc != 2) {
965  Tcl_AppendResult(interp, "Wrong # args: Should be \"",
966  argv[0], " varname\"", NULL);
967  return TCL_ERROR;
968  }
969 
970  str=Tcl_GetVar(interp, argv[1], 0);
971  if (!str) {
972  Tcl_AppendResult(interp, "Error getting variable ",
973  argv[1], NULL);
974  return TCL_ERROR;
975  }
976  val = atoi(str);
977 
978  V_MAX(val, 0);
979 
980  rnd = BN_RANDOM(val);
981 
982  snprintf(buf, 32, "%d", val);
983 
984  if (!Tcl_SetVar(interp, argv[1], buf, 0)) {
985  Tcl_AppendResult(interp, "Error setting variable ",
986  argv[1], NULL);
987  return TCL_ERROR;
988  }
989 
990  snprintf(buf, 32, "%g", rnd);
991  Tcl_AppendResult(interp, buf, NULL);
992  return TCL_OK;
993 }
994 
995 
996 void
998  const char *title,
999  const mat_t m)
1000 {
1001  char obuf[1024]; /* snprintf may be non-PARALLEL */
1002 
1003  bn_mat_print_guts(title, m, obuf, 1024);
1004  Tcl_AppendResult(interp, obuf, "\n", (char *)NULL);
1005 }
1006 
1007 
1008 void
1009 bn_tcl_setup(Tcl_Interp *interp)
1010 {
1011  struct math_func_link *mp;
1012 
1013  for (mp = math_funcs; mp->name != NULL; mp++) {
1014  (void)Tcl_CreateCommand(interp, mp->name,
1015  (Tcl_CmdProc *)bn_math_cmd,
1016  (ClientData)mp,
1017  (Tcl_CmdDeleteProc *)NULL);
1018  }
1019 
1020  (void)Tcl_CreateCommand(interp, "bn_noise_perlin",
1021  (Tcl_CmdProc *)bn_cmd_noise_perlin, (ClientData)NULL,
1022  (Tcl_CmdDeleteProc *)NULL);
1023 
1024  (void)Tcl_CreateCommand(interp, "bn_noise_turb",
1025  (Tcl_CmdProc *)bn_cmd_noise, (ClientData)NULL,
1026  (Tcl_CmdDeleteProc *)NULL);
1027 
1028  (void)Tcl_CreateCommand(interp, "bn_noise_fbm",
1029  (Tcl_CmdProc *)bn_cmd_noise, (ClientData)NULL,
1030  (Tcl_CmdDeleteProc *)NULL);
1031 
1032  (void)Tcl_CreateCommand(interp, "bn_noise_slice",
1033  (Tcl_CmdProc *)bn_cmd_noise_slice, (ClientData)NULL,
1034  (Tcl_CmdDeleteProc *)NULL);
1035 
1036  (void)Tcl_CreateCommand(interp, "bn_random",
1037  (Tcl_CmdProc *)bn_cmd_random, (ClientData)NULL,
1038  (Tcl_CmdDeleteProc *)NULL);
1039 }
1040 
1041 
1042 int
1043 Bn_Init(Tcl_Interp *interp)
1044 {
1045  bn_tcl_setup(interp);
1046  return TCL_OK;
1047 }
1048 
1049 
1050 /** @} */
1051 /*
1052  * Local Variables:
1053  * mode: C
1054  * tab-width: 8
1055  * indent-tabs-mode: t
1056  * c-file-style: "stroustrup"
1057  * End:
1058  * ex: shiftwidth=4 tabstop=8
1059  */
void bn_ae_vec(fastf_t *azp, fastf_t *elp, const vect_t v)
Definition: mat.c:374
void bn_mat_ae(mat_t m, double azimuth, double elev)
void bn_tcl_setup(Tcl_Interp *interp)
Tcl interfaces to all the LIBBN math routines.
Definition: tcl.c:1009
Definition: db_flip.c:35
void bn_mat_lookat(mat_t rot, const vect_t dir, int yflip)
Definition: mat.c:785
int bn_cmd_random(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
Definition: tcl.c:954
ustring interp
double dist
>= 0
Definition: tol.h:73
void bn_mat_scale_about_pt_wrapper(int *statusp, mat_t mat, const point_t pt, const double scale)
Definition: tcl.c:152
if lu s
Definition: nmg_mod.c:3860
Definition: clone.c:90
#define VSETALL(a, s)
Definition: color.c:54
double bn_noise_turb(point_t point, double h_val, double lacunarity, double octaves)
Procedural turbulence evaluated at "point";.
void bn_quat_distance_wrapper(double *dp, mat_t q1, mat_t q2)
Definition: tcl.c:145
int bn_cmd_noise(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
Definition: tcl.c:801
#define BN_TOL_MAGIC
Definition: magic.h:74
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 bn_mat_xrot(mat_t m, double sinx, double cosx)
void bn_encode_hvect(struct bu_vls *vp, const mat_t v)
Definition: tcl.c:138
int bn_decode_mat(fastf_t *mat, const char *str)
Definition: tcl.c:51
Header file for the BRL-CAD common definitions.
int bn_decode_hvect(fastf_t *v, const char *str)
Definition: tcl.c:101
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 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...
void bn_tcl_mat_print(Tcl_Interp *interp, const char *title, const mat_t m)
Definition: tcl.c:997
void bu_vls_free(struct bu_vls *vp)
Definition: vls.c:248
Definition: color.c:49
int bn_mat_scale_about_pt(mat_t mat, const point_t pt, const double scale)
Definition: mat.c:884
void bn_matXvec(hvect_t ov, const mat_t im, const hvect_t iv)
int bn_dist_pt2_lseg2(fastf_t *dist_sq, fastf_t pca[2], const point_t a, const point_t b, const point_t p, const struct bn_tol *tol)
Find the distance from a point P to a line segment described by the two endpoints A and B...
void bn_mat_inv(mat_t output, const mat_t input)
#define MATH_FUNC_VOID_CAST(_func)
Definition: tcl.c:192
void bn_mat_fromto(mat_t m, const fastf_t *from, const fastf_t *to, const struct bn_tol *tol)
Definition: mat.c:639
#define BN_TOL_DIST
Definition: tol.h:109
void bn_mat_trn(mat_t om, const mat_t im)
#define UNUSED(parameter)
Definition: common.h:239
void bn_mat_mul(mat_t o, const mat_t a, const mat_t b)
int bn_cmd_noise_slice(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
usage: noise_slice xdim ydim inv h_val lac octaves dX dY dZ sX [sY sZ]
Definition: tcl.c:852
Support for uniform tolerances.
Definition: tol.h:71
char * bu_vls_addr(const struct bu_vls *vp)
Definition: vls.c:111
int bn_math_cmd(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
Tcl wrappers for the math functions.
Definition: tcl.c:247
void bn_mat_angles(mat_t mat, double alpha, double beta, double ggamma)
ustring alpha
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 bn_encode_quat(struct bu_vls *vp, const mat_t q)
Definition: tcl.c:124
double bn_noise_perlin(point_t pt)
Robert Skinner's Perlin-style "Noise" function.
void bn_mat_yrot(mat_t m, double siny, double cosy)
int bn_decode_vect(fastf_t *vec, const char *str)
Definition: tcl.c:87
void bn_mat_print_guts(const char *title, const mat_t m, char *buf, int buflen)
Definition: mat.c:50
void bn_vec_ortho(vect_t out, const vect_t in)
void bn_aet_vec(fastf_t *az, fastf_t *el, fastf_t *twist, vect_t vec_ae, vect_t vec_twist, fastf_t accuracy)
int bn_isect_line3_line3(fastf_t *s, fastf_t *t, const point_t p0, const vect_t u, const point_t q0, const vect_t v, const struct bn_tol *tol)
#define BN_RANDOM(_i)
Definition: rand.h:73
void bu_vls_printf(struct bu_vls *vls, const char *fmt,...) _BU_ATTR_PRINTF23
Definition: vls.c:694
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 NOISE_TURB
Definition: color.c:51
double bn_noise_fbm(point_t point, double h_val, double lacunarity, double octaves)
Procedural fBm evaluated at "point"; returns value stored in "value".
void bn_vec_perp(vect_t new_vec, const vect_t old_vec)
Definition: mat.c:616
int bn_isect_line2_line2(fastf_t *dist, const point_t p, const vect_t d, const point_t a, const vect_t c, const struct bn_tol *tol)
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.
#define BU_VLS_INIT_ZERO
Definition: vls.h:84
void bn_mat_xform_about_pt(mat_t mat, const mat_t xform, const point_t pt)
Definition: mat.c:909
void quat_log(quat_t out, const quat_t in)
Take the natural logarithm of a unit quaternion. Code by Ken Shoemake.
Definition: vls.h:56
HIDDEN const point_t delta
Definition: sh_prj.c:618
double fastf_t
Definition: defines.h:300
void bn_mat_zrot(mat_t m, double sinz, double cosz)
void bu_vls_putc(struct bu_vls *vp, int c)
Definition: vls.c:666
int bn_cmd_noise_perlin(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
Definition: tcl.c:770
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...
int bn_decode_quat(fastf_t *quat, const char *str)
Definition: tcl.c:73
void bn_mat_arb_rot(mat_t m, const point_t pt, const vect_t dir, const fastf_t ang)
Definition: mat.c:987
Definition: color.c:50
#define NOISE_FBM
void bn_encode_vect(struct bu_vls *vp, const mat_t v)
Definition: tcl.c:131
int Bn_Init(Tcl_Interp *interp)
Allows LIBBN to be dynamically loaded to a vanilla tclsh/wish with "load /usr/brlcad/lib/libbn.so".
Definition: tcl.c:1043
void bn_encode_mat(struct bu_vls *vp, const mat_t m)
Definition: tcl.c:108
#define BU_STR_EQUAL(s1, s2)
Definition: str.h:126