00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #ifndef lint
00037 static const char RCSid[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/libbn/bn_tcl.c,v 14.21 2006/09/07 01:19:17 lbutler Exp $ (ARL)";
00038 #endif
00039
00040 #include "common.h"
00041
00042 #include <stdlib.h>
00043 #include <stdio.h>
00044 #include <math.h>
00045 #ifdef HAVE_STRING_H
00046 # include <string.h>
00047 #else
00048 # include <strings.h>
00049 #endif
00050
00051 #include "tcl.h"
00052
00053 #include "machine.h"
00054 #include "bu.h"
00055 #include "vmath.h"
00056 #include "bn.h"
00057
00058
00059
00060
00061
00062
00063
00064
00065 int
00066 bn_decode_mat(fastf_t *m, const char *str)
00067 {
00068 if( strcmp( str, "I" ) == 0 ) {
00069 MAT_IDN( m );
00070 return 16;
00071 }
00072 if( *str == '{' ) str++;
00073
00074 return sscanf(str,
00075 "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",
00076 &m[0], &m[1], &m[2], &m[3], &m[4], &m[5], &m[6], &m[7],
00077 &m[8], &m[9], &m[10], &m[11], &m[12], &m[13], &m[14], &m[15]);
00078 }
00079
00080 int
00081 bn_decode_quat(fastf_t *q, const char *str)
00082 {
00083 if( *str == '{' ) str++;
00084 return sscanf(str, "%lf %lf %lf %lf", &q[0], &q[1], &q[2], &q[3]);
00085 }
00086
00087 int
00088 bn_decode_vect(fastf_t *v, const char *str)
00089 {
00090 if( *str == '{' ) str++;
00091 return sscanf(str, "%lf %lf %lf", &v[0], &v[1], &v[2]);
00092 }
00093
00094 int
00095 bn_decode_hvect(fastf_t *v, const char *str)
00096 {
00097 if( *str == '{' ) str++;
00098 return sscanf(str, "%lf %lf %lf %lf", &v[0], &v[1], &v[2], &v[3]);
00099 }
00100
00101 void
00102 bn_encode_mat(struct bu_vls *vp, const mat_t m)
00103 {
00104 if( m == NULL ) {
00105 bu_vls_putc(vp, 'I');
00106 return;
00107 }
00108
00109 bu_vls_printf(vp, "%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g",
00110 m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7],
00111 m[8], m[9], m[10], m[11], m[12], m[13], m[14], m[15]);
00112 }
00113
00114 void
00115 bn_encode_quat(struct bu_vls *vp, const mat_t q)
00116 {
00117 bu_vls_printf(vp, "%g %g %g %g", V4ARGS(q));
00118 }
00119
00120 void
00121 bn_encode_vect(struct bu_vls *vp, const mat_t v)
00122 {
00123 bu_vls_printf(vp, "%g %g %g", V3ARGS(v));
00124 }
00125
00126 void
00127 bn_encode_hvect(struct bu_vls *vp, const mat_t v)
00128 {
00129 bu_vls_printf(vp, "%g %g %g %g", V4ARGS(v));
00130 }
00131
00132 void
00133 bn_quat_distance_wrapper(double *dp, mat_t q1, mat_t q2)
00134 {
00135 *dp = quat_distance(q1, q2);
00136 }
00137
00138 void
00139 bn_mat_scale_about_pt_wrapper(int *statusp, mat_t mat, const point_t pt, const double scale)
00140 {
00141 *statusp = bn_mat_scale_about_pt(mat, pt, scale);
00142 }
00143
00144 static void
00145 bn_mat4x3pnt(fastf_t *o, mat_t m, point_t i)
00146 {
00147 MAT4X3PNT(o, m, i);
00148 }
00149
00150 static void
00151 bn_mat4x3vec(fastf_t *o, mat_t m, vect_t i)
00152 {
00153 MAT4X3VEC(o, m, i);
00154 }
00155
00156 static void
00157 bn_hdivide(fastf_t *o, const mat_t i)
00158 {
00159 HDIVIDE(o, i);
00160 }
00161
00162 static void
00163 bn_vjoin1(fastf_t *o, const point_t pnt, double scale, const vect_t dir)
00164 {
00165 VJOIN1( o, pnt, scale, dir );
00166 }
00167
00168
00169 static void bn_vblend(mat_t a, fastf_t b, mat_t c, fastf_t d, mat_t e)
00170 {
00171 VBLEND2( a, b, c, d, e );
00172 }
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 int
00184 bn_math_cmd(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
00185 {
00186 void (*math_func)();
00187 struct bu_vls result;
00188
00189 math_func = (void (*)())clientData;
00190 bu_vls_init(&result);
00191
00192 if (math_func == bn_mat_mul) {
00193 mat_t o, a, b;
00194 if (argc < 3 || bn_decode_mat(a, argv[1]) < 16 ||
00195 bn_decode_mat(b, argv[2]) < 16) {
00196 bu_vls_printf(&result, "usage: %s matA matB", argv[0]);
00197 goto error;
00198 }
00199 bn_mat_mul(o, a, b);
00200 bn_encode_mat(&result, o);
00201 } else if (math_func == bn_mat_inv || math_func == bn_mat_trn) {
00202 mat_t o, a;
00203
00204 if (argc < 2 || bn_decode_mat(a, argv[1]) < 16) {
00205 bu_vls_printf(&result, "usage: %s mat", argv[0]);
00206 goto error;
00207 }
00208 (*math_func)(o, a);
00209 bn_encode_mat(&result, o);
00210 } else if (math_func == bn_matXvec) {
00211 mat_t m;
00212 hvect_t i, o;
00213 if (argc < 3 || bn_decode_mat(m, argv[1]) < 16 ||
00214 bn_decode_hvect(i, argv[2]) < 4) {
00215 bu_vls_printf(&result, "usage: %s mat hvect", argv[0]);
00216 goto error;
00217 }
00218 bn_matXvec(o, m, i);
00219 bn_encode_hvect(&result, o);
00220 } else if (math_func == bn_mat4x3pnt) {
00221 mat_t m;
00222 point_t i, o;
00223 if (argc < 3 || bn_decode_mat(m, argv[1]) < 16 ||
00224 bn_decode_vect(i, argv[2]) < 3) {
00225 bu_vls_printf(&result, "usage: %s mat point", argv[0]);
00226 goto error;
00227 }
00228 bn_mat4x3pnt(o, m, i);
00229 bn_encode_vect(&result, o);
00230 } else if (math_func == bn_mat4x3vec) {
00231 mat_t m;
00232 vect_t i, o;
00233 if (argc < 3 || bn_decode_mat(m, argv[1]) < 16 ||
00234 bn_decode_vect(i, argv[2]) < 3) {
00235 bu_vls_printf(&result, "usage: %s mat vect", argv[0]);
00236 goto error;
00237 }
00238 bn_mat4x3vec(o, m, i);
00239 bn_encode_vect(&result, o);
00240 } else if (math_func == bn_hdivide) {
00241 hvect_t i;
00242 vect_t o;
00243 if (argc < 2 || bn_decode_hvect(i, argv[1]) < 4) {
00244 bu_vls_printf(&result, "usage: %s hvect", argv[0]);
00245 goto error;
00246 }
00247 bn_hdivide(o, i);
00248 bn_encode_vect(&result, o);
00249 } else if (math_func == bn_vjoin1) {
00250 point_t o;
00251 point_t b, d;
00252 fastf_t c;
00253
00254 if (argc < 4) {
00255 bu_vls_printf(&result, "usage: %s pnt scale dir", argv[0]);
00256 goto error;
00257 }
00258 if( bn_decode_vect(b, argv[1]) < 3) goto error;
00259 if (Tcl_GetDouble(interp, argv[2], &c) != TCL_OK) goto error;
00260 if( bn_decode_vect(d, argv[3]) < 3) goto error;
00261
00262 VJOIN1( o, b, c, d );
00263 bn_encode_vect(&result, o);
00264
00265 } else if ( math_func == bn_vblend) {
00266 point_t a, c, e;
00267 fastf_t b, d;
00268
00269 if( argc < 5 ) {
00270 bu_vls_printf(&result, "usage: %s scale pnt scale pnt", argv[0]);
00271 goto error;
00272 }
00273
00274 if( Tcl_GetDouble(interp, argv[1], &b) != TCL_OK) goto error;
00275 if( bn_decode_vect( c, argv[2] ) < 3) goto error;
00276 if( Tcl_GetDouble(interp, argv[3], &d) != TCL_OK) goto error;
00277 if( bn_decode_vect( e, argv[4] ) < 3) goto error;
00278
00279 VBLEND2( a, b, c, d, e )
00280 bn_encode_vect( &result, a );
00281
00282 } else if (math_func == bn_mat_ae) {
00283 mat_t o;
00284 double az, el;
00285
00286 if (argc < 3) {
00287 bu_vls_printf(&result, "usage: %s azimuth elevation", argv[0]);
00288 goto error;
00289 }
00290 if (Tcl_GetDouble(interp, argv[1], &az) != TCL_OK) goto error;
00291 if (Tcl_GetDouble(interp, argv[2], &el) != TCL_OK) goto error;
00292
00293 bn_mat_ae(o, (fastf_t)az, (fastf_t)el);
00294 bn_encode_mat(&result, o);
00295 } else if (math_func == bn_ae_vec) {
00296 fastf_t az, el;
00297 vect_t v;
00298
00299 if (argc < 2 || bn_decode_vect(v, argv[1]) < 3) {
00300 bu_vls_printf(&result, "usage: %s vect", argv[0]);
00301 goto error;
00302 }
00303
00304 bn_ae_vec(&az, &el, v);
00305 bu_vls_printf(&result, "%g %g", az, el);
00306 } else if (math_func == bn_aet_vec) {
00307 fastf_t az, el, twist, accuracy;
00308 vect_t vec_ae, vec_twist;
00309
00310 if (argc < 4 || bn_decode_vect(vec_ae, argv[1]) < 3 ||
00311 bn_decode_vect(vec_twist, argv[2]) < 3 ||
00312 sscanf(argv[3], "%lf", &accuracy) < 1) {
00313 bu_vls_printf(&result, "usage: %s vec_ae vec_twist accuracy",
00314 argv[0]);
00315 goto error;
00316 }
00317
00318 bn_aet_vec(&az, &el, &twist, vec_ae, vec_twist, accuracy);
00319 bu_vls_printf(&result, "%g %g %g", az, el, twist);
00320 } else if (math_func == bn_mat_angles) {
00321 mat_t o;
00322 double alpha, beta, ggamma;
00323
00324 if (argc < 4) {
00325 bu_vls_printf(&result, "usage: %s alpha beta gamma", argv[0]);
00326 goto error;
00327 }
00328 if (Tcl_GetDouble(interp, argv[1], &alpha) != TCL_OK) goto error;
00329 if (Tcl_GetDouble(interp, argv[2], &beta) != TCL_OK) goto error;
00330 if (Tcl_GetDouble(interp, argv[3], &ggamma) != TCL_OK) goto error;
00331
00332 bn_mat_angles(o, alpha, beta, ggamma);
00333 bn_encode_mat(&result, o);
00334 } else if (math_func == bn_eigen2x2) {
00335 fastf_t val1, val2;
00336 vect_t vec1, vec2;
00337 double a, b, c;
00338
00339 if (argc < 4) {
00340 bu_vls_printf(&result, "usage: %s a b c", argv[0]);
00341 goto error;
00342 }
00343 if (Tcl_GetDouble(interp, argv[1], &a) != TCL_OK) goto error;
00344 if (Tcl_GetDouble(interp, argv[2], &c) != TCL_OK) goto error;
00345 if (Tcl_GetDouble(interp, argv[3], &b) != TCL_OK) goto error;
00346
00347 bn_eigen2x2(&val1, &val2, vec1, vec2, (fastf_t)a, (fastf_t)b,
00348 (fastf_t)c);
00349 bu_vls_printf(&result, "%g %g {%g %g %g} {%g %g %g}", val1, val2,
00350 V3ARGS(vec1), V3ARGS(vec2));
00351 } else if (math_func == bn_mat_fromto) {
00352 mat_t o;
00353 vect_t from, to;
00354
00355 if (argc < 3 || bn_decode_vect(from, argv[1]) < 3 ||
00356 bn_decode_vect(to, argv[2]) < 3) {
00357 bu_vls_printf(&result, "usage: %s vecFrom vecTo", argv[0]);
00358 goto error;
00359 }
00360 bn_mat_fromto(o, from, to);
00361 bn_encode_mat(&result, o);
00362 } else if (math_func == bn_mat_xrot || math_func == bn_mat_yrot ||
00363 math_func == bn_mat_zrot) {
00364 mat_t o;
00365 double s, c;
00366 if (argc < 3) {
00367 bu_vls_printf(&result, "usage: %s sinAngle cosAngle", argv[0]);
00368 goto error;
00369 }
00370 if (Tcl_GetDouble(interp, argv[1], &s) != TCL_OK) goto error;
00371 if (Tcl_GetDouble(interp, argv[2], &c) != TCL_OK) goto error;
00372
00373 (*math_func)(o, s, c);
00374 bn_encode_mat(&result, o);
00375 } else if (math_func == bn_mat_lookat) {
00376 mat_t o;
00377 vect_t dir;
00378 int yflip;
00379 if (argc < 3 || bn_decode_vect(dir, argv[1]) < 3) {
00380 bu_vls_printf(&result, "usage: %s dir yflip", argv[0]);
00381 goto error;
00382 }
00383 if (Tcl_GetBoolean(interp, argv[2], &yflip) != TCL_OK) goto error;
00384
00385 bn_mat_lookat(o, dir, yflip);
00386 bn_encode_mat(&result, o);
00387 } else if (math_func == bn_vec_ortho || math_func == bn_vec_perp) {
00388 vect_t ov, vec;
00389
00390 if (argc < 2 || bn_decode_vect(vec, argv[1]) < 3) {
00391 bu_vls_printf(&result, "usage: %s vec", argv[0]);
00392 goto error;
00393 }
00394
00395 (*math_func)(ov, vec);
00396 bn_encode_vect(&result, ov);
00397 } else if (math_func == bn_mat_scale_about_pt_wrapper) {
00398 mat_t o;
00399 vect_t v;
00400 double scale;
00401 int status;
00402
00403 if (argc < 3 || bn_decode_vect(v, argv[1]) < 3) {
00404 bu_vls_printf(&result, "usage: %s pt scale", argv[0]);
00405 goto error;
00406 }
00407 if (Tcl_GetDouble(interp, argv[2], &scale) != TCL_OK) goto error;
00408
00409 bn_mat_scale_about_pt_wrapper(&status, o, v, scale);
00410 if (status != 0) {
00411 bu_vls_printf(&result, "error performing calculation");
00412 goto error;
00413 }
00414 bn_encode_mat(&result, o);
00415 } else if (math_func == bn_mat_xform_about_pt) {
00416 mat_t o, xform;
00417 vect_t v;
00418
00419 if (argc < 3 || bn_decode_mat(xform, argv[1]) < 16 ||
00420 bn_decode_vect(v, argv[2]) < 3) {
00421 bu_vls_printf(&result, "usage: %s xform pt", argv[0]);
00422 goto error;
00423 }
00424
00425 bn_mat_xform_about_pt(o, xform, v);
00426 bn_encode_mat(&result, o);
00427 } else if (math_func == bn_mat_arb_rot) {
00428 mat_t o;
00429 point_t pt;
00430 vect_t dir;
00431 double angle;
00432
00433 if (argc < 4 || bn_decode_vect(pt, argv[1]) < 3 ||
00434 bn_decode_vect(dir, argv[2]) < 3) {
00435 bu_vls_printf(&result, "usage: %s pt dir angle", argv[0]);
00436 goto error;
00437 }
00438 if (Tcl_GetDouble(interp, argv[3], &angle) != TCL_OK)
00439 return TCL_ERROR;
00440
00441 bn_mat_arb_rot(o, pt, dir, (fastf_t)angle);
00442 bn_encode_mat(&result, o);
00443 } else if (math_func == quat_mat2quat) {
00444 mat_t mat;
00445 quat_t quat;
00446
00447 if (argc < 2 || bn_decode_mat(mat, argv[1]) < 16) {
00448 bu_vls_printf(&result, "usage: %s mat", argv[0]);
00449 goto error;
00450 }
00451
00452 quat_mat2quat(quat, mat);
00453 bn_encode_quat(&result, quat);
00454 } else if (math_func == quat_quat2mat) {
00455 mat_t mat;
00456 quat_t quat;
00457
00458 if (argc < 2 || bn_decode_quat(quat, argv[1]) < 4) {
00459 bu_vls_printf(&result, "usage: %s quat", argv[0]);
00460 goto error;
00461 }
00462
00463 quat_quat2mat(mat, quat);
00464 bn_encode_mat(&result, mat);
00465 } else if (math_func == bn_quat_distance_wrapper) {
00466 quat_t q1, q2;
00467 double d;
00468
00469 if (argc < 3 || bn_decode_quat(q1, argv[1]) < 4 ||
00470 bn_decode_quat(q2, argv[2]) < 4) {
00471 bu_vls_printf(&result, "usage: %s quatA quatB", argv[0]);
00472 goto error;
00473 }
00474
00475 bn_quat_distance_wrapper(&d, q1, q2);
00476 bu_vls_printf(&result, "%g", d);
00477 } else if (math_func == quat_double || math_func == quat_bisect ||
00478 math_func == quat_make_nearest) {
00479 quat_t oqot, q1, q2;
00480
00481 if (argc < 3 || bn_decode_quat(q1, argv[1]) < 4 ||
00482 bn_decode_quat(q2, argv[2]) < 4) {
00483 bu_vls_printf(&result, "usage: %s quatA quatB", argv[0]);
00484 goto error;
00485 }
00486
00487 (*math_func)(oqot, q1, q2);
00488 bn_encode_quat(&result, oqot);
00489 } else if (math_func == quat_slerp) {
00490 quat_t oq, q1, q2;
00491 double d;
00492
00493 if (argc < 4 || bn_decode_quat(q1, argv[1]) < 4 ||
00494 bn_decode_quat(q2, argv[2]) < 4) {
00495 bu_vls_printf(&result, "usage: %s quat1 quat2 factor", argv[0]);
00496 goto error;
00497 }
00498 if (Tcl_GetDouble(interp, argv[3], &d) != TCL_OK) goto error;
00499
00500 quat_slerp(oq, q1, q2, d);
00501 bn_encode_quat(&result, oq);
00502 } else if (math_func == quat_sberp) {
00503 quat_t oq, q1, qa, qb, q2;
00504 double d;
00505
00506 if (argc < 6 || bn_decode_quat(q1, argv[1]) < 4 ||
00507 bn_decode_quat(qa, argv[2]) < 4 || bn_decode_quat(qb, argv[3]) < 4 ||
00508 bn_decode_quat(q2, argv[4]) < 4) {
00509 bu_vls_printf(&result, "usage: %s quat1 quatA quatB quat2 factor",
00510 argv[0]);
00511 goto error;
00512 }
00513 if (Tcl_GetDouble(interp, argv[5], &d) != TCL_OK) goto error;
00514
00515 quat_sberp(oq, q1, qa, qb, q2, d);
00516 bn_encode_quat(&result, oq);
00517 } else if (math_func == quat_exp || math_func == quat_log) {
00518 quat_t qout, qin;
00519
00520 if (argc < 2 || bn_decode_quat(qin, argv[1]) < 4) {
00521 bu_vls_printf(&result, "usage: %s quat", argv[0]);
00522 goto error;
00523 }
00524
00525 (*math_func)(qout, qin);
00526 bn_encode_quat(&result, qout);
00527 } else if (math_func == (void (*)())bn_isect_line3_line3) {
00528 double t, u;
00529 point_t pt, a;
00530 vect_t dir, c;
00531 int i;
00532 const static struct bn_tol tol = {
00533 BN_TOL_MAGIC, 0.005, 0.005*0.005, 1e-6, 1-1e-6
00534 };
00535 if (argc != 5) {
00536 bu_vls_printf(&result,
00537 "Usage: bn_isect_line3_line3 pt dir pt dir (%d args specified)",
00538 argc-1);
00539 goto error;
00540 }
00541
00542 if (bn_decode_vect(pt, argv[1]) < 3) {
00543 bu_vls_printf(&result, "bn_isect_line3_line3 no pt: %s\n", argv[0]);
00544 goto error;
00545 }
00546 if (bn_decode_vect(dir, argv[2]) < 3) {
00547 bu_vls_printf(&result, "bn_isect_line3_line3 no dir: %s\n", argv[0]);
00548 goto error;
00549 }
00550 if (bn_decode_vect(a, argv[3]) < 3) {
00551 bu_vls_printf(&result, "bn_isect_line3_line3 no a pt: %s\n", argv[0]);
00552 goto error;
00553 }
00554 if (bn_decode_vect(c, argv[4]) < 3) {
00555 bu_vls_printf(&result, "bn_isect_line3_line3 no c dir: %s\n", argv[0]);
00556 goto error;
00557 }
00558 i = bn_isect_line3_line3(&t, &u, pt, dir, a, c, &tol);
00559 if (i != 1) {
00560 bu_vls_printf(&result, "bn_isect_line3_line3 no intersection: %s\n", argv[0]);
00561 goto error;
00562 }
00563
00564 VJOIN1(a, pt, t, dir);
00565 bn_encode_vect(&result, a);
00566
00567 } else if (math_func == (void (*)())bn_isect_line2_line2) {
00568 double dist[2];
00569 point_t pt, a;
00570 vect_t dir, c;
00571 int i;
00572 const static struct bn_tol tol = {
00573 BN_TOL_MAGIC, 0.005, 0.005*0.005, 1e-6, 1-1e-6
00574 };
00575
00576 if (argc != 5) {
00577 bu_vls_printf(&result,
00578 "Usage: bn_isect_line2_line2 pt dir pt dir (%d args specified)",
00579 argc-1);
00580 goto error;
00581 }
00582
00583
00584
00585 VSETALL(pt, 0.0);
00586 VSETALL(dir, 0.0);
00587 VSETALL(a, 0.0);
00588 VSETALL(c, 0.0);
00589
00590 if (bn_decode_vect(pt, argv[1]) < 2) {
00591 bu_vls_printf(&result, "bn_isect_line2_line2 no pt: %s\n", argv[0]);
00592 goto error;
00593 }
00594 if (bn_decode_vect(dir, argv[2]) < 2) {
00595 bu_vls_printf(&result, "bn_isect_line2_line2 no dir: %s\n", argv[0]);
00596 goto error;
00597 }
00598 if (bn_decode_vect(a, argv[3]) < 2) {
00599 bu_vls_printf(&result, "bn_isect_line2_line2 no a pt: %s\n", argv[0]);
00600 goto error;
00601 }
00602 if (bn_decode_vect(c, argv[4]) < 2) {
00603 bu_vls_printf(&result, "bn_isect_line2_line2 no c dir: %s\n", argv[0]);
00604 goto error;
00605 }
00606 i = bn_isect_line2_line2(dist, pt, dir, a, c, &tol);
00607 if (i != 1) {
00608 bu_vls_printf(&result, "bn_isect_line2_line2 no intersection: %s\n", argv[0]);
00609 goto error;
00610 }
00611
00612 VJOIN1(a, pt, dist[0], dir);
00613 bu_vls_printf(&result, "%g %g", a[0], a[1]);
00614
00615 } else {
00616 bu_vls_printf(&result, "libbn/bn_tcl.c: math function %s not supported yet\n", argv[0]);
00617 goto error;
00618 }
00619
00620 Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL);
00621 bu_vls_free(&result);
00622 return TCL_OK;
00623
00624 error:
00625 Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL);
00626 bu_vls_free(&result);
00627 return TCL_ERROR;
00628 }
00629
00630 static struct math_func_link {
00631 char *name;
00632 void (*func)();
00633 } math_funcs[] = {
00634 {"bn_isect_line2_line2", (void (*)())bn_isect_line2_line2},
00635 {"bn_isect_line3_line3", (void (*)())bn_isect_line3_line3},
00636 {"mat_mul", bn_mat_mul},
00637 {"mat_inv", bn_mat_inv},
00638 {"mat_trn", bn_mat_trn},
00639 {"matXvec", bn_matXvec},
00640 {"mat4x3vec", bn_mat4x3vec},
00641 {"mat4x3pnt", bn_mat4x3pnt},
00642 {"hdivide", bn_hdivide},
00643 {"vjoin1", bn_vjoin1},
00644 {"vblend", bn_vblend},
00645 {"mat_ae", bn_mat_ae},
00646 {"mat_ae_vec", bn_ae_vec},
00647 {"mat_aet_vec", bn_aet_vec},
00648 {"mat_angles", bn_mat_angles},
00649 {"mat_eigen2x2", bn_eigen2x2},
00650 {"mat_fromto", bn_mat_fromto},
00651 {"mat_xrot", bn_mat_xrot},
00652 {"mat_yrot", bn_mat_yrot},
00653 {"mat_zrot", bn_mat_zrot},
00654 {"mat_lookat", bn_mat_lookat},
00655 {"mat_vec_ortho", bn_vec_ortho},
00656 {"mat_vec_perp", bn_vec_perp},
00657 {"mat_scale_about_pt", bn_mat_scale_about_pt_wrapper},
00658 {"mat_xform_about_pt", bn_mat_xform_about_pt},
00659 {"mat_arb_rot", bn_mat_arb_rot},
00660 {"quat_mat2quat", quat_mat2quat},
00661 {"quat_quat2mat", quat_quat2mat},
00662 {"quat_distance", bn_quat_distance_wrapper},
00663 {"quat_double", quat_double},
00664 {"quat_bisect", quat_bisect},
00665 {"quat_slerp", quat_slerp},
00666 {"quat_sberp", quat_sberp},
00667 {"quat_make_nearest", quat_make_nearest},
00668 {"quat_exp", quat_exp},
00669 {"quat_log", quat_log},
00670 {0, 0}
00671 };
00672
00673 int
00674 bn_cmd_noise_perlin(ClientData clientData,
00675 Tcl_Interp *interp,
00676 int argc,
00677 char **argv)
00678 {
00679 point_t pt;
00680 double v;
00681
00682 if (argc != 4) {
00683 Tcl_AppendResult(interp, "wrong # args: should be \"",
00684 argv[0], " X Y Z \"",
00685 NULL);
00686 return TCL_ERROR;
00687 }
00688
00689 pt[X] = atof(argv[1]);
00690 pt[Y] = atof(argv[2]);
00691 pt[Z] = atof(argv[3]);
00692
00693 v = bn_noise_perlin( pt );
00694 sprintf(interp->result, "%g", v );
00695
00696 return TCL_OK;
00697 }
00698
00699
00700
00701
00702
00703 int
00704 bn_cmd_noise(ClientData clientData,
00705 Tcl_Interp *interp,
00706 int argc,
00707 char **argv)
00708 {
00709 point_t pt;
00710 double h_val;
00711 double lacunarity;
00712 double octaves;
00713 double val;
00714
00715 if (argc != 7) {
00716 Tcl_AppendResult(interp, "wrong # args: should be \"",
00717 argv[0], " X Y Z h_val lacunarity octaves\"",
00718 NULL);
00719 return TCL_ERROR;
00720 }
00721
00722 pt[0] = atof(argv[1]);
00723 pt[1] = atof(argv[2]);
00724 pt[2] = atof(argv[3]);
00725
00726 h_val = atof(argv[4]);
00727 lacunarity = atof(argv[5]);
00728 octaves = atof(argv[6]);
00729
00730
00731 if (!strcmp("bn_noise_turb", argv[0])) {
00732 val = bn_noise_turb(pt, h_val, lacunarity, octaves);
00733
00734 sprintf(interp->result, "%g", val );
00735 } else if (!strcmp("bn_noise_fbm", argv[0])) {
00736 val = bn_noise_fbm(pt, h_val, lacunarity, octaves);
00737 sprintf(interp->result, "%g", val );
00738 } else {
00739 Tcl_AppendResult(interp, "Unknown noise type \"",
00740 argv[0], "\"", NULL);
00741 return TCL_ERROR;
00742 }
00743 return TCL_OK;
00744 }
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754 int
00755 bn_cmd_noise_slice(ClientData clientData,
00756 Tcl_Interp *interp,
00757 int argc,
00758 char **argv)
00759 {
00760 double h_val;
00761 double lacunarity;
00762 double octaves;
00763
00764 vect_t delta;
00765 vect_t scale;
00766 unsigned xdim;
00767 unsigned ydim;
00768 unsigned xval, yval;
00769 #define NOISE_FBM 0
00770 #define NOISE_TURB 1
00771
00772 int noise_type = NOISE_FBM;
00773 double val;
00774 point_t pt;
00775
00776 if (argc != 7) {
00777 Tcl_AppendResult(interp, "wrong # args: should be \"",
00778 argv[0], " Xdim Ydim Zval h_val lacunarity octaves\"",
00779 NULL);
00780 return TCL_ERROR;
00781 }
00782
00783 xdim = atoi(argv[0]);
00784 ydim = atoi(argv[1]);
00785 VSETALL(delta, 0.0);
00786 VSETALL(scale, 1.);
00787 pt[Z] = delta[Z] = atof(argv[2]);
00788 h_val = atof(argv[3]);
00789 lacunarity = atof(argv[4]);
00790 octaves = atof(argv[5]);
00791
00792 switch (noise_type) {
00793 case NOISE_FBM:
00794 for (yval = 0 ; yval < ydim ; yval++) {
00795
00796 pt[Y] = yval * scale[Y] + delta[Y];
00797
00798 for (xval = 0 ; xval < xdim ; xval++) {
00799 pt[X] = xval * scale[X] + delta[X];
00800
00801 val = bn_noise_fbm(pt, h_val, lacunarity, octaves);
00802
00803 }
00804 }
00805 break;
00806 case NOISE_TURB:
00807 for (yval = 0 ; yval < ydim ; yval++) {
00808
00809 pt[Y] = yval * scale[Y] + delta[Y];
00810
00811 for (xval = 0 ; xval < xdim ; xval++) {
00812 pt[X] = xval * scale[X] + delta[X];
00813
00814 val = bn_noise_turb(pt, h_val, lacunarity, octaves);
00815
00816 }
00817 }
00818 break;
00819 }
00820
00821
00822 pt[0] = atof(argv[1]);
00823 pt[1] = atof(argv[2]);
00824 pt[2] = atof(argv[3]);
00825
00826 h_val = atof(argv[4]);
00827 lacunarity = atof(argv[5]);
00828 octaves = atof(argv[6]);
00829
00830
00831 if (!strcmp("bn_noise_turb", argv[0])) {
00832 val = bn_noise_turb(pt, h_val, lacunarity, octaves);
00833
00834 sprintf(interp->result, "%g", val );
00835 } else if (!strcmp("bn_noise_fbm", argv[0])) {
00836 val = bn_noise_fbm(pt, h_val, lacunarity, octaves);
00837 sprintf(interp->result, "%g", val );
00838 } else {
00839 Tcl_AppendResult(interp, "Unknown noise type \"",
00840 argv[0], "\"", NULL);
00841 return TCL_ERROR;
00842 }
00843 return TCL_OK;
00844 }
00845
00846
00847 int
00848 bn_cmd_random(ClientData clientData,
00849 Tcl_Interp *interp,
00850 int argc,
00851 char **argv)
00852 {
00853 int val;
00854 const char *str;
00855 double rnd;
00856 char buf[32];
00857
00858 if (argc != 2) {
00859 Tcl_AppendResult(interp, "Wrong # args: Should be \"",
00860 argv[0], " varname\"", NULL);
00861 return TCL_ERROR;
00862 }
00863
00864 if (! (str=Tcl_GetVar(interp, argv[1], 0))) {
00865 Tcl_AppendResult(interp, "Error getting variable ",
00866 argv[1], NULL);
00867 return TCL_ERROR;
00868 }
00869 val = atoi(str);
00870
00871 if (val < 0) val = 0;
00872
00873 rnd = BN_RANDOM(val);
00874
00875 sprintf(buf, "%d", val);
00876
00877 if (!Tcl_SetVar(interp, argv[1], buf, 0)) {
00878 Tcl_AppendResult(interp, "Error setting variable ",
00879 argv[1], NULL);
00880 return TCL_ERROR;
00881 }
00882
00883 sprintf(buf, "%g", rnd);
00884 Tcl_AppendResult(interp, buf, NULL);
00885 return TCL_OK;
00886 }
00887
00888
00889
00890
00891 void
00892 bn_tcl_mat_print(Tcl_Interp *interp,
00893 const char *title,
00894 const mat_t m)
00895 {
00896 char obuf[1024];
00897
00898 bn_mat_print_guts(title, m, obuf);
00899 Tcl_AppendResult(interp, obuf, "\n", (char *)NULL);
00900 }
00901
00902
00903
00904
00905
00906
00907
00908 void
00909 bn_tcl_setup(Tcl_Interp *interp)
00910 {
00911 struct math_func_link *mp;
00912
00913 for (mp = math_funcs; mp->name != NULL; mp++) {
00914 (void)Tcl_CreateCommand(interp, mp->name,
00915 (Tcl_CmdProc *)bn_math_cmd,
00916 (ClientData)mp->func,
00917 (Tcl_CmdDeleteProc *)NULL);
00918 }
00919
00920 (void)Tcl_CreateCommand(interp, "bn_noise_perlin",
00921 (Tcl_CmdProc *)bn_cmd_noise_perlin, (ClientData)NULL,
00922 (Tcl_CmdDeleteProc *)NULL);
00923
00924 (void)Tcl_CreateCommand(interp, "bn_noise_turb",
00925 (Tcl_CmdProc *)bn_cmd_noise, (ClientData)NULL,
00926 (Tcl_CmdDeleteProc *)NULL);
00927
00928 (void)Tcl_CreateCommand(interp, "bn_noise_fbm",
00929 (Tcl_CmdProc *)bn_cmd_noise, (ClientData)NULL,
00930 (Tcl_CmdDeleteProc *)NULL);
00931
00932 (void)Tcl_CreateCommand(interp, "bn_noise_slice",
00933 (Tcl_CmdProc *)bn_cmd_noise_slice, (ClientData)NULL,
00934 (Tcl_CmdDeleteProc *)NULL);
00935
00936 (void)Tcl_CreateCommand(interp, "bn_random",
00937 (Tcl_CmdProc *)bn_cmd_random, (ClientData)NULL,
00938 (Tcl_CmdDeleteProc *)NULL);
00939
00940
00941 Tcl_SetVar(interp, "bn_version", (char *)bn_version+5, TCL_GLOBAL_ONLY);
00942 }
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952 int
00953 #ifdef BRLCAD_DEBUG
00954 Bn_d_Init(Tcl_Interp *interp)
00955 #else
00956 Bn_Init(Tcl_Interp *interp)
00957 #endif
00958 {
00959 bn_tcl_setup(interp);
00960 return TCL_OK;
00961 }
00962
00963
00964 double bn_noise_fbm(point_t point,double h_val,double lacunarity,double octaves);
00965 double bn_noise_turb(point_t point,double h_val,double lacunarity,double octaves);
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975