83
double myatan2(double a, double b)
85
if(a == 0.0 && b == 0)
90
double myasin(double a)
100
double myacos(double a)
110
void prodve(double a[3], double b[3], double c[3])
112
c[2] = a[0] * b[1] - a[1] * b[0];
113
c[1] = -a[0] * b[2] + a[2] * b[0];
114
c[0] = a[1] * b[2] - a[2] * b[1];
117
void matvec(double mat[3][3], double vec[3], double res[3])
119
res[0] = mat[0][0] * vec[0] + mat[0][1] * vec[1] + mat[0][2] * vec[2];
120
res[1] = mat[1][0] * vec[0] + mat[1][1] * vec[1] + mat[1][2] * vec[2];
121
res[2] = mat[2][0] * vec[0] + mat[2][1] * vec[1] + mat[2][2] * vec[2];
124
void prosca(double a[3], double b[3], double *c)
126
*c = a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
129
double norm3(double a[3])
131
return sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
134
double norme(double a[3])
136
double mod = norm3(a);
145
void normal3points(double x0, double y0, double z0,
146
double x1, double y1, double z1,
147
double x2, double y2, double z2,
150
double t1[3] = {x1 - x0, y1 - y0, z1 - z0};
151
double t2[3] = {x2 - x0, y2 - y0, z2 - z0};
156
int sys2x2(double mat[2][2], double b[2], double res[2])
158
double det, ud, norm;
161
norm = DSQR(mat[0][0]) + DSQR(mat[1][1]) + DSQR(mat[0][1]) + DSQR(mat[1][0]);
162
det = mat[0][0] * mat[1][1] - mat[1][0] * mat[0][1];
165
// TOLERANCE ! WARNING WARNING
166
if(norm == 0.0 || fabs(det) / norm < 1.e-12) {
168
Msg(DEBUG, "Assuming 2x2 matrix is singular (det/norm == %.16g)",
170
res[0] = res[1] = 0.0;
175
res[0] = b[0] * mat[1][1] - mat[0][1] * b[1];
176
res[1] = mat[0][0] * b[1] - mat[1][0] * b[0];
178
for(i = 0; i < 2; i++)
184
double det3x3(double mat[3][3])
186
return (mat[0][0] * (mat[1][1] * mat[2][2] - mat[1][2] * mat[2][1]) -
187
mat[0][1] * (mat[1][0] * mat[2][2] - mat[1][2] * mat[2][0]) +
188
mat[0][2] * (mat[1][0] * mat[2][1] - mat[1][1] * mat[2][0]));
191
double trace3x3(double mat[3][3])
193
return mat[0][0] + mat[1][1] + mat[2][2];
196
double trace2 (double mat[3][3])
198
double a00 = mat[0][0] * mat[0][0] + mat[1][0] * mat[0][1] + mat[2][0] * mat[0][2];
199
double a11 = mat[1][0] * mat[0][1] + mat[1][1] * mat[1][1] + mat[1][2] * mat[2][1];
200
double a22 = mat[2][0] * mat[0][2] + mat[2][1] * mat[1][2] + mat[2][2] * mat[2][2];
202
return a00 + a11 + a22;
205
int sys3x3(double mat[3][3], double b[3], double res[3], double *det)
213
res[0] = res[1] = res[2] = 0.0;
219
res[0] = b[0] * (mat[1][1] * mat[2][2] - mat[1][2] * mat[2][1]) -
220
mat[0][1] * (b[1] * mat[2][2] - mat[1][2] * b[2]) +
221
mat[0][2] * (b[1] * mat[2][1] - mat[1][1] * b[2]);
223
res[1] = mat[0][0] * (b[1] * mat[2][2] - mat[1][2] * b[2]) -
224
b[0] * (mat[1][0] * mat[2][2] - mat[1][2] * mat[2][0]) +
225
mat[0][2] * (mat[1][0] * b[2] - b[1] * mat[2][0]);
227
res[2] = mat[0][0] * (mat[1][1] * b[2] - b[1] * mat[2][1]) -
228
mat[0][1] * (mat[1][0] * b[2] - b[1] * mat[2][0]) +
229
b[0] * (mat[1][0] * mat[2][1] - mat[1][1] * mat[2][0]);
231
for(i = 0; i < 3; i++)
237
int sys3x3_with_tol(double mat[3][3], double b[3], double res[3], double *det)
242
out = sys3x3(mat, b, res, det);
244
DSQR(mat[0][0]) + DSQR(mat[0][1]) + DSQR(mat[0][2]) +
245
DSQR(mat[1][0]) + DSQR(mat[1][1]) + DSQR(mat[1][2]) +
246
DSQR(mat[2][0]) + DSQR(mat[2][1]) + DSQR(mat[2][2]);
248
// TOLERANCE ! WARNING WARNING
249
if(norm == 0.0 || fabs(*det) / norm < 1.e-12) {
251
Msg(DEBUG, "Assuming 3x3 matrix is singular (det/norm == %.16g)",
253
res[0] = res[1] = res[2] = 0.0;
260
double det2x2(double mat[2][2])
262
return mat[0][0] *mat[1][1] -mat[1][0] *mat[0][1];
265
double inv2x2(double mat[2][2], double inv[2][2])
267
const double det = det2x2 ( mat );
269
double ud = 1. / det;
270
inv[0][0] = ( mat[1][1] ) * ud ;
271
inv[1][0] = -( mat[1][0] ) * ud ;
272
inv[0][1] = -( mat[0][1] ) * ud ;
273
inv[1][1] = ( mat[0][0] ) * ud ;
276
Msg(GERROR, "Singular matrix");
277
for(int i = 0; i < 2; i++)
278
for(int j = 0; j < 2; j++)
284
double inv3x3(double mat[3][3], double inv[3][3])
286
double det = det3x3(mat);
288
double ud = 1. / det;
289
inv[0][0] = ( mat[1][1] * mat[2][2] - mat[1][2] * mat[2][1] ) * ud ;
290
inv[1][0] = -( mat[1][0] * mat[2][2] - mat[1][2] * mat[2][0] ) * ud ;
291
inv[2][0] = ( mat[1][0] * mat[2][1] - mat[1][1] * mat[2][0] ) * ud ;
292
inv[0][1] = -( mat[0][1] * mat[2][2] - mat[0][2] * mat[2][1] ) * ud ;
293
inv[1][1] = ( mat[0][0] * mat[2][2] - mat[0][2] * mat[2][0] ) * ud ;
294
inv[2][1] = -( mat[0][0] * mat[2][1] - mat[0][1] * mat[2][0] ) * ud ;
295
inv[0][2] = ( mat[0][1] * mat[1][2] - mat[0][2] * mat[1][1] ) * ud ;
296
inv[1][2] = -( mat[0][0] * mat[1][2] - mat[0][2] * mat[1][0] ) * ud ;
297
inv[2][2] = ( mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0] ) * ud ;
300
Msg(GERROR, "Singular matrix");
301
for(int i = 0; i < 3; i++)
302
for(int j = 0; j < 3; j++)
308
80
void invert_singular_matrix3x3(double MM[3][3], double II[3][3])
310
82
int i, j, k, n = 3;
377
149
free_dvector(W, 1, n);
381
double angle_02pi(double A3)
384
while(A3 > DP || A3 < 0.) {
393
double angle_plan(double V[3], double P1[3], double P2[3], double n[3])
395
double PA[3], PB[3], angplan;
396
double cosc, sinc, c[3];
398
PA[0] = P1[0] - V[0];
399
PA[1] = P1[1] - V[1];
400
PA[2] = P1[2] - V[2];
402
PB[0] = P2[0] - V[0];
403
PB[1] = P2[1] - V[1];
404
PB[2] = P2[2] - V[2];
411
prosca(PA, PB, &cosc);
413
angplan = myatan2(sinc, cosc);
418
double triangle_area(double p0[3], double p1[3], double p2[3])
420
double a[3], b[3], c[3];
422
a[0] = p2[0] - p1[0];
423
a[1] = p2[1] - p1[1];
424
a[2] = p2[2] - p1[2];
426
b[0] = p0[0] - p1[0];
427
b[1] = p0[1] - p1[1];
428
b[2] = p0[2] - p1[2];
431
return (0.5 * sqrt(c[0] * c[0] + c[1] * c[1] + c[2] * c[2]));
434
char float2char(float f)
436
// f is supposed to be normalized in [-1, 1]
437
f = (f > 1.) ? 1. : (f < -1.) ? -1 : f;
438
// char is in [-128, 127]
439
return (char)(-128 + (f + 1.)/2. * 255);
442
float char2float(char c)
444
return -1. + (float)(c + 128)/255. * 2.;
447
double InterpolateIso(double *X, double *Y, double *Z,
448
double *Val, double V, int I1, int I2,
449
double *XI, double *YI, double *ZI)
451
if(Val[I1] == Val[I2]) {
458
double coef = (V - Val[I1]) / (Val[I2] - Val[I1]);
459
*XI = coef * (X[I2] - X[I1]) + X[I1];
460
*YI = coef * (Y[I2] - Y[I1]) + Y[I1];
461
*ZI = coef * (Z[I2] - Z[I1]) + Z[I1];
466
void gradSimplex(double *x, double *y, double *z, double *v, double *grad)
468
// p = p1 * (1-u-v-w) + p2 u + p3 v + p4 w
472
mat[0][0] = x[1] - x[0];
473
mat[1][0] = x[2] - x[0];
474
mat[2][0] = x[3] - x[0];
475
mat[0][1] = y[1] - y[0];
476
mat[1][1] = y[2] - y[0];
477
mat[2][1] = y[3] - y[0];
478
mat[0][2] = z[1] - z[0];
479
mat[1][2] = z[2] - z[0];
480
mat[2][2] = z[3] - z[0];
484
sys3x3(mat, b, grad, &det);
487
void eigenvalue(double mat[3][3], double v[3])
489
// characteristic polynomial of T : find v root of
490
// v^3 - I1 v^2 + I2 T - I3 = 0
491
// I1 : first invariant , trace(T)
492
// I2 : second invariant , 1/2 (I1^2 -trace(T^2))
493
// I3 : third invariant , det T
497
c[2] = - trace3x3(mat);
498
c[1] = 0.5 * (c[2]*c[2] - trace2(mat));
499
c[0] = - det3x3(mat);
501
//printf("%g %g %g\n", mat[0][0], mat[0][1], mat[0][2]);
502
//printf("%g %g %g\n", mat[1][0], mat[1][1], mat[1][2]);
503
//printf("%g %g %g\n", mat[2][0], mat[2][1], mat[2][2]);
504
//printf("%g x^3 + %g x^2 + %g x + %g = 0\n", c[3], c[2], c[1], c[0]);
507
FindCubicRoots(c, v, imag);
511
void FindCubicRoots(const double coef[4], double real[3], double imag[3])
519
Msg(GERROR, "Degenerate cubic: use a second degree solver!");
527
double q = (3.0*c - (b*b))/9.0;
528
double r = -(27.0*d) + b*(9.0*c - 2.0*(b*b));
531
double discrim = q*q*q + r*r;
532
imag[0] = 0.0; // The first root is always real.
533
double term1 = (b/3.0);
535
if (discrim > 0) { // one root is real, two are complex
536
double s = r + sqrt(discrim);
537
s = ((s < 0) ? -pow(-s, (1.0/3.0)) : pow(s, (1.0/3.0)));
538
double t = r - sqrt(discrim);
539
t = ((t < 0) ? -pow(-t, (1.0/3.0)) : pow(t, (1.0/3.0)));
540
real[0] = -term1 + s + t;
541
term1 += (s + t)/2.0;
542
real[1] = real[2] = -term1;
543
term1 = sqrt(3.0)*(-t + s)/2;
549
// The remaining options are all real
550
imag[1] = imag[2] = 0.0;
553
if (discrim == 0){ // All roots real, at least two are equal.
554
r13 = ((r < 0) ? -pow(-r,(1.0/3.0)) : pow(r,(1.0/3.0)));
555
real[0] = -term1 + 2.0*r13;
556
real[1] = real[2] = -(r13 + term1);
560
// Only option left is that all roots are real and unequal (to get
564
dum1 = acos(r/sqrt(dum1));
566
real[0] = -term1 + r13*cos(dum1/3.0);
567
real[1] = -term1 + r13*cos((dum1 + 2.0*M_PI)/3.0);
568
real[2] = -term1 + r13*cos((dum1 + 4.0*M_PI)/3.0);
571
void eigsort(double d[3])
576
for (i=0; i<3; i++) {
579
if (d[j] >= p) p=d[k=j];