7 #include "GmshConfig.h"
14 if(a == 0.0 && b == 0)
return 0.0;
41 std::pow(a[0][0], 2) + std::pow(a[0][1], 2) + std::pow(a[0][2], 2) +
42 std::pow(a[1][0], 2) + std::pow(a[1][1], 2) + std::pow(a[1][2], 2) +
43 std::pow(a[2][0], 2) + std::pow(a[2][1], 2) + std::pow(a[2][2], 2);
44 return std::sqrt(norm2sq);
47 void matvec(
double mat[3][3],
double vec[3],
double res[3])
49 res[0] = mat[0][0] * vec[0] + mat[0][1] * vec[1] + mat[0][2] * vec[2];
50 res[1] = mat[1][0] * vec[0] + mat[1][1] * vec[1] + mat[1][2] * vec[2];
51 res[2] = mat[2][0] * vec[0] + mat[2][1] * vec[1] + mat[2][2] * vec[2];
54 void matmat(
double mat1[3][3],
double mat2[3][3],
double res[3][3])
57 mat1[0][0] * mat2[0][0] + mat1[0][1] * mat2[1][0] + mat1[0][2] * mat2[2][0];
59 mat1[0][0] * mat2[0][1] + mat1[0][1] * mat2[1][1] + mat1[0][2] * mat2[2][1];
61 mat1[0][0] * mat2[0][2] + mat1[0][1] * mat2[1][2] + mat1[0][2] * mat2[2][2];
63 mat1[1][0] * mat2[0][0] + mat1[1][1] * mat2[1][0] + mat1[1][2] * mat2[2][0];
65 mat1[1][0] * mat2[0][1] + mat1[1][1] * mat2[1][1] + mat1[1][2] * mat2[2][1];
67 mat1[1][0] * mat2[0][2] + mat1[1][1] * mat2[1][2] + mat1[1][2] * mat2[2][2];
69 mat1[2][0] * mat2[0][0] + mat1[2][1] * mat2[1][0] + mat1[2][2] * mat2[2][0];
71 mat1[2][0] * mat2[0][1] + mat1[2][1] * mat2[1][1] + mat1[2][2] * mat2[2][1];
73 mat1[2][0] * mat2[0][2] + mat1[2][1] * mat2[1][2] + mat1[2][2] * mat2[2][2];
76 void normal3points(
double x0,
double y0,
double z0,
double x1,
double y1,
77 double z1,
double x2,
double y2,
double z2,
double n[3])
79 double t1[3] = {x1 - x0, y1 - y0, z1 - z0};
80 double t2[3] = {x2 - x0, y2 - y0, z2 - z0};
85 void normal2points(
double x0,
double y0,
double z0,
double x1,
double y1,
86 double z1,
double n[3])
89 double t[3] = {x1 - x0, y1 - y0, z1 - z0};
90 double ex[3] = {0., 0., 0.};
101 int sys2x2(
double mat[2][2],
double b[2],
double res[2])
103 double const norm = std::pow(mat[0][0], 2) + std::pow(mat[1][1], 2) +
104 std::pow(mat[0][1], 2) + std::pow(mat[1][0], 2);
106 double const det = mat[0][0] * mat[1][1] - mat[1][0] * mat[0][1];
109 if(
norm == 0.0 || std::abs(det) /
norm < 1.e-16) {
113 res[0] = res[1] = 0.0;
116 double const ud = 1.0 / det;
118 res[0] = b[0] * mat[1][1] - mat[0][1] * b[1];
119 res[1] = mat[0][0] * b[1] - mat[1][0] * b[0];
121 for(
int i = 0; i < 2; i++) res[i] *= ud;
128 return (mat[0][0] * (mat[1][1] * mat[2][2] - mat[1][2] * mat[2][1]) -
129 mat[0][1] * (mat[1][0] * mat[2][2] - mat[1][2] * mat[2][0]) +
130 mat[0][2] * (mat[1][0] * mat[2][1] - mat[1][1] * mat[2][0]));
133 double trace3x3(
double mat[3][3]) {
return mat[0][0] + mat[1][1] + mat[2][2]; }
138 mat[0][0] * mat[0][0] + mat[1][0] * mat[0][1] + mat[2][0] * mat[0][2];
140 mat[1][0] * mat[0][1] + mat[1][1] * mat[1][1] + mat[1][2] * mat[2][1];
142 mat[2][0] * mat[0][2] + mat[2][1] * mat[1][2] + mat[2][2] * mat[2][2];
144 return a00 + a11 + a22;
147 int sys3x3(
double mat[3][3],
double b[3],
double res[3],
double *det)
155 res[0] = res[1] = res[2] = 0.0;
161 res[0] = b[0] * (mat[1][1] * mat[2][2] - mat[1][2] * mat[2][1]) -
162 mat[0][1] * (b[1] * mat[2][2] - mat[1][2] * b[2]) +
163 mat[0][2] * (b[1] * mat[2][1] - mat[1][1] * b[2]);
165 res[1] = mat[0][0] * (b[1] * mat[2][2] - mat[1][2] * b[2]) -
166 b[0] * (mat[1][0] * mat[2][2] - mat[1][2] * mat[2][0]) +
167 mat[0][2] * (mat[1][0] * b[2] - b[1] * mat[2][0]);
169 res[2] = mat[0][0] * (mat[1][1] * b[2] - b[1] * mat[2][1]) -
170 mat[0][1] * (mat[1][0] * b[2] - b[1] * mat[2][0]) +
171 b[0] * (mat[1][0] * mat[2][1] - mat[1][1] * mat[2][0]);
173 for(i = 0; i < 3; i++) res[i] *= ud;
182 out =
sys3x3(mat, b, res, det);
184 std::pow(mat[0][0], 2) + std::pow(mat[0][1], 2) + std::pow(mat[0][2], 2) +
185 std::pow(mat[1][0], 2) + std::pow(mat[1][1], 2) + std::pow(mat[1][2], 2) +
186 std::pow(mat[2][0], 2) + std::pow(mat[2][1], 2) + std::pow(mat[2][2], 2);
189 if(
norm == 0.0 || std::abs(*det) /
norm < 1.e-12) {
191 Msg::Debug(
"Assuming 3x3 matrix is singular (det/norm == %.16g)",
192 std::abs(*det) /
norm);
193 res[0] = res[1] = res[2] = 0.0;
201 return mat[0][0] * mat[1][1] - mat[1][0] * mat[0][1];
206 double v1[3] = {mat[0][0], mat[0][1], mat[0][2]};
207 double v2[3] = {mat[1][0], mat[1][1], mat[1][2]};
214 double inv2x2(
double mat[2][2],
double inv[2][2])
216 const double det =
det2x2(mat);
218 double ud = 1. / det;
219 inv[0][0] = mat[1][1] * ud;
220 inv[1][0] = -mat[1][0] * ud;
221 inv[0][1] = -mat[0][1] * ud;
222 inv[1][1] = mat[0][0] * ud;
226 for(
int i = 0; i < 2; i++)
227 for(
int j = 0; j < 2; j++) inv[i][j] = 0.;
232 double inv3x3(
double mat[3][3],
double inv[3][3])
236 double ud = 1. / det;
237 inv[0][0] = (mat[1][1] * mat[2][2] - mat[1][2] * mat[2][1]) * ud;
238 inv[1][0] = -(mat[1][0] * mat[2][2] - mat[1][2] * mat[2][0]) * ud;
239 inv[2][0] = (mat[1][0] * mat[2][1] - mat[1][1] * mat[2][0]) * ud;
240 inv[0][1] = -(mat[0][1] * mat[2][2] - mat[0][2] * mat[2][1]) * ud;
241 inv[1][1] = (mat[0][0] * mat[2][2] - mat[0][2] * mat[2][0]) * ud;
242 inv[2][1] = -(mat[0][0] * mat[2][1] - mat[0][1] * mat[2][0]) * ud;
243 inv[0][2] = (mat[0][1] * mat[1][2] - mat[0][2] * mat[1][1]) * ud;
244 inv[1][2] = -(mat[0][0] * mat[1][2] - mat[0][2] * mat[1][0]) * ud;
245 inv[2][2] = (mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0]) * ud;
249 for(
int i = 0; i < 3; i++)
250 for(
int j = 0; j < 3; j++) inv[i][j] = 0.;
257 double DP = 2 * M_PI;
258 while(A3 > DP || A3 < 0.) {
267 double angle_plan(
double v[3],
double p1[3],
double p2[3],
double n[3])
269 double PA[3], PB[3], angplan;
271 PA[0] = p1[0] - v[0];
272 PA[1] = p1[1] - v[1];
273 PA[2] = p1[2] - v[2];
275 PB[0] = p2[0] - v[0];
276 PB[1] = p2[1] - v[1];
277 PB[2] = p2[2] - v[2];
285 double const cosc =
prosca(PA, PB);
286 double const sinc =
prosca(
c, n);
295 double a[3], b[3],
c[3];
297 a[0] = p2[0] - p1[0];
298 a[1] = p2[1] - p1[1];
299 a[2] = p2[2] - p1[2];
301 b[0] = p0[0] - p1[0];
302 b[1] = p0[1] - p1[1];
303 b[2] = p0[2] - p1[2];
306 return 0.5 * std::sqrt(
c[0] *
c[0] +
c[1] *
c[1] +
c[2] *
c[2]);
312 (p2[0] - p1[0]) * (p0[1] - p1[1]) - (p2[1] - p1[1]) * (p0[0] - p1[0]);
314 return 0.5 * std::sqrt(
c *
c);
319 double d,
a1,
a2, a3;
321 const double x1 = p1[0];
322 const double x2 = p2[0];
323 const double x3 = p3[0];
324 const double y1 = p1[1];
325 const double y2 = p2[1];
326 const double y3 = p3[1];
328 d = 2. * (double)(y1 * (x2 - x3) + y2 * (x3 - x1) + y3 * (x1 - x2));
331 res[0] = res[1] = -99999.;
335 a1 = x1 * x1 + y1 * y1;
336 a2 = x2 * x2 + y2 * y2;
337 a3 = x3 * x3 + y3 * y3;
338 res[0] = (double)((
a1 * (y3 - y2) +
a2 * (y1 - y3) + a3 * (y2 - y1)) / d);
339 res[1] = (double)((
a1 * (x2 - x3) +
a2 * (x3 - x1) + a3 * (x1 - x2)) / d);
345 double v1[3] = {p2[0] - p1[0], p2[1] - p1[1], p2[2] - p1[2]};
346 double v2[3] = {p3[0] - p1[0], p3[1] - p1[1], p3[2] - p1[2]};
347 double vx[3] = {p2[0] - p1[0], p2[1] - p1[1], p2[2] - p1[2]};
348 double vy[3] = {p3[0] - p1[0], p3[1] - p1[1], p3[2] - p1[2]};
356 double p1P[2] = {0.0, 0.0};
365 double mat[2][2] = {{p2P[0] - p1P[0], p3P[0] - p1P[0]},
366 {p2P[1] - p1P[1], p3P[1] - p1P[1]}};
367 double rhs[2] = {resP[0] - p1P[0], resP[1] - p1P[1]};
371 res[0] = p1[0] + resP[0] * vx[0] + resP[1] * vy[0];
372 res[1] = p1[1] + resP[0] * vx[1] + resP[1] * vy[1];
373 res[2] = p1[2] + resP[0] * vx[2] + resP[1] * vy[2];
378 double v1[3] = {x[1] - x[0], y[1] - y[0],
z[1] -
z[0]};
379 double v2[3] = {x[2] - x[0], y[2] - y[0],
z[2] -
z[0]};
380 double v3[3] = {x[3] - x[0], y[3] - y[0],
z[3] -
z[0]};
382 double vx[3] = {x[1] - x[0], y[1] - y[0],
z[1] -
z[0]};
383 double vy[3] = {x[2] - x[0], y[2] - y[0],
z[2] -
z[0]};
392 double p1P[2] = {0.0, 0.0};
410 double a1 = y[(4 + i) % 4] - y[(5 + i) % 4];
411 double a2 = y[(5 + i) % 4] - y[(6 + i) % 4];
412 double a3 = y[(6 + i) % 4] - y[(7 + i) % 4];
414 double b1 = x[(5 + i) % 4] - x[(4 + i) % 4];
415 double b2 = x[(6 + i) % 4] - x[(5 + i) % 4];
416 double b3 = x[(7 + i) % 4] - x[(6 + i) % 4];
418 double c1 = y[(5 + i) % 4] * x[(4 + i) % 4] - y[(4 + i) % 4] * x[(5 + i) % 4];
419 double c2 = y[(6 + i) % 4] * x[(5 + i) % 4] - y[(5 + i) % 4] * x[(6 + i) % 4];
420 double c3 = y[(7 + i) % 4] * x[(6 + i) % 4] - y[(6 + i) % 4] * x[(7 + i) % 4];
423 double l1 = std::sqrt(
a1 *
a1 +
b1 *
b1);
424 double l2 = std::sqrt(
a2 *
a2 + b2 * b2);
425 double l3 = std::sqrt(a3 * a3 + b3 * b3);
428 double a12 =
a1 / l1 -
a2 / l2;
429 double a23 =
a2 / l2 - a3 / l3;
431 double b12 =
b1 / l1 - b2 / l2;
432 double b23 = b2 / l2 - b3 / l3;
434 double c12 =
c1 / l1 - c2 / l2;
435 double c23 = c2 / l2 - c3 / l3;
439 double x_s = (c12 * b23 - c23 * b12) / (a23 * b12 - a12 * b23);
441 if(b12 != 0) { y_s = -a12 / b12 * x_s - c12 / b12; }
443 y_s = -a23 / b23 * x_s - c23 / b23;
447 double r = (
a1 * x_s +
b1 * y_s +
c1) / l1;
475 void gradSimplex(
double *x,
double *y,
double *
z,
double *v,
double *grad)
481 mat[0][0] = x[1] - x[0];
482 mat[1][0] = x[2] - x[0];
483 mat[2][0] = x[3] - x[0];
484 mat[0][1] = y[1] - y[0];
485 mat[1][1] = y[2] - y[0];
486 mat[2][1] = y[3] - y[0];
487 mat[0][2] =
z[1] -
z[0];
488 mat[1][2] =
z[2] -
z[0];
489 mat[2][2] =
z[3] -
z[0];
493 sys3x3(mat, b, grad, &det);
498 double tr = (V[0] + V[4] + V[8]) / 3.;
499 double v11 = V[0] - tr, v12 = V[1], v13 = V[2];
500 double v21 = V[3], v22 = V[4] - tr, v23 = V[5];
501 double v31 = V[6], v32 = V[7], v33 = V[8] - tr;
502 return sqrt(1.5 * (v11 * v11 + v12 * v12 + v13 * v13 + v21 * v21 + v22 * v22 +
503 v23 * v23 + v31 * v31 + v32 * v32 + v33 * v33));
510 else if(numComp == 3)
511 return sqrt(val[0] * val[0] + val[1] * val[1] + val[2] * val[2]);
512 else if(numComp == 9) {
521 for(
int j = 0; j < 3; j++) {
522 tensor(j, 0) = val[0 + j * 3];
523 tensor(j, 1) = val[1 + j * 3];
524 tensor(j, 2) = val[2 + j * 3];
526 tensor.
eig(
S, imS, V, rightV,
true);
541 double b = -(mat[0][0] + mat[1][1]);
542 double c = (mat[0][0] * mat[1][1]) - (mat[0][1] * mat[1][0]);
544 double det = b * b - 4. * a *
c;
546 v[0] = (-b + sqrt(det)) / (2 * a);
547 v[1] = (-b - sqrt(det)) / (2 * a);
561 c[1] = 0.5 * (
c[2] *
c[2] -
trace2(mat));
590 double q = (3.0 *
c - (b * b)) / 9.0;
591 double r = -(27.0 * d) + b * (9.0 *
c - 2.0 * (b * b));
594 double discrim = q * q * q + r * r;
596 double term1 = (b / 3.0);
599 double s = r + sqrt(discrim);
600 s = ((s < 0) ? -pow(-s, (1.0 / 3.0)) : pow(s, (1.0 / 3.0)));
601 double t = r - sqrt(discrim);
602 t = ((t < 0) ? -pow(-t, (1.0 / 3.0)) : pow(t, (1.0 / 3.0)));
603 real[0] = -term1 + s + t;
604 term1 += (s + t) / 2.0;
605 real[1] = real[2] = -term1;
606 term1 = sqrt(3.0) * (-t + s) / 2;
613 imag[1] = imag[2] = 0.0;
617 r13 = ((r < 0) ? -pow(-r, (1.0 / 3.0)) : pow(r, (1.0 / 3.0)));
618 real[0] = -term1 + 2.0 * r13;
619 real[1] = real[2] = -(r13 + term1);
626 double dum1 = q * q * q;
627 dum1 = acos(r / sqrt(dum1));
629 real[0] = -term1 + r13 * cos(dum1 / 3.0);
630 real[1] = -term1 + r13 * cos((dum1 + 2.0 * M_PI) / 3.0);
631 real[2] = -term1 + r13 * cos((dum1 + 4.0 * M_PI) / 3.0);
639 for(i = 0; i < 3; i++) {
641 for(j = i + 1; j < 3; j++)
642 if(d[j] >= p) p = d[k = j];
655 for(i = 1; i <= n; i++) {
656 for(j = 1; j <= n; j++) {
657 II[i - 1][j - 1] = 0.0;
658 TT[i - 1][j - 1] = 0.0;
664 for(i = 1; i <= n; i++) {
665 for(j = 1; j <= n; j++) { M(i - 1, j - 1) = MM[i - 1][j - 1]; }
668 for(i = 1; i <= n; i++) {
669 for(j = 1; j <= n; j++) {
670 double ww = W(i - 1);
671 if(fabs(ww) > 1.e-16) {
672 TT[i - 1][j - 1] += M(j - 1, i - 1) / ww;
676 for(i = 1; i <= n; i++) {
677 for(j = 1; j <= n; j++) {
678 for(k = 1; k <= n; k++) {
679 II[i - 1][j - 1] += V(i - 1, k - 1) * TT[k - 1][j - 1];
688 const int MAXIT = 100;
689 const double EPS = 1.e-4;
690 const int N = x.
size();
695 for(
int iter = 0; iter < MAXIT; iter++) {
696 if(x.
norm() > 1.e6)
return false;
697 if(!func(x,
f, data)) {
return false; }
700 for(
int k = 0; k < N; k++) {
705 if(isZero ==
false)
break;
709 for(
int j = 0; j < N; j++) {
710 double h = EPS * fabs(x(j));
713 if(!func(x, feps, data)) {
return false; }
714 for(
int i = 0; i < N; i++) { J(i, j) = (feps(i) -
f(i)) / h; }
719 dx(0) =
f(0) / J(0, 0);
724 for(
int i = 0; i < N; i++) x(i) -= relax * dx(i);
726 if(dx.norm() < tolx) {
return true; }
767 const double n2t1 =
dot(t1, t1);
768 const double n2t2 =
dot(t2, t2);
769 const double n2t3 =
dot(t3, t3);
770 double mat[3][3] = {{t1.
x(), t2.
x(), -n.
x()},
771 {t1.
y(), t2.
y(), -n.
y()},
772 {t1.
z(), t2.
z(), -n.
z()}};
774 double det =
inv3x3(mat, inv);
775 if(det == 0.0)
return;
779 u = (inv[0][0] * pp1.
x() + inv[0][1] * pp1.
y() + inv[0][2] * pp1.
z());
780 v = (inv[1][0] * pp1.
x() + inv[1][1] * pp1.
y() + inv[1][2] * pp1.
z());
781 d = (inv[2][0] * pp1.
x() + inv[2][1] * pp1.
y() + inv[2][2] * pp1.
z());
782 double sign = (d > 0) ? 1. : -1.;
783 if(d == 0.) sign = 1.;
784 if(u >= 0. && v >= 0. && 1. - u - v >= 0.0) {
785 closePt = p1 + (p2 - p1) * u + (p3 - p1) * v;
788 const double t12 =
dot(pp1, t1) / n2t1;
789 const double t13 =
dot(pp1, t2) / n2t2;
791 const double t23 =
dot(pp2, t3) / n2t3;
793 if(t12 >= 0 && t12 <= 1.) {
794 d = sign * std::min(fabs(d), p.
distance(p1 + (p2 - p1) * t12));
795 closePt = p1 + (p2 - p1) * t12;
797 if(t13 >= 0 && t13 <= 1.) {
798 if(p.
distance(p1 + (p3 - p1) * t13) < fabs(d))
799 closePt = p1 + (p3 - p1) * t13;
800 d = sign * std::min(fabs(d), p.
distance(p1 + (p3 - p1) * t13));
802 if(t23 >= 0 && t23 <= 1.) {
803 if(p.
distance(p2 + (p3 - p2) * t23) < fabs(d))
804 closePt = p2 + (p3 - p2) * t23;
805 d = sign * std::min(fabs(d), p.
distance(p2 + (p3 - p2) * t23));
809 d = sign * std::min(fabs(d), p.
distance(p1));
813 d = sign * std::min(fabs(d), p.
distance(p2));
817 d = sign * std::min(fabs(d), p.
distance(p3));
823 std::vector<SPoint3> &closePts,
824 const std::vector<SPoint3> &pts,
828 const unsigned pts_size = pts.size();
830 distances.resize(pts_size);
832 closePts.resize(pts_size);
834 for(std::size_t i = 0; i < pts_size; ++i) distances[i] = 1.e22;
841 const double n2t1 =
dot(t1, t1);
842 const double n2t2 =
dot(t2, t2);
843 const double n2t3 =
dot(t3, t3);
844 double mat[3][3] = {{t1.
x(), t2.
x(), -n.
x()},
845 {t1.
y(), t2.
y(), -n.
y()},
846 {t1.
z(), t2.
z(), -n.
z()}};
848 double det =
inv3x3(mat, inv);
849 if(det == 0.0)
return;
851 for(std::size_t i = 0; i < pts.size(); i++) {
859 u = (inv[0][0] * pp1.
x() + inv[0][1] * pp1.
y() + inv[0][2] * pp1.
z());
860 v = (inv[1][0] * pp1.
x() + inv[1][1] * pp1.
y() + inv[1][2] * pp1.
z());
861 d = (inv[2][0] * pp1.
x() + inv[2][1] * pp1.
y() + inv[2][2] * pp1.
z());
862 double sign = (d > 0) ? 1. : -1.;
863 if(d == 0.) sign = 1.;
864 if(u >= 0 && v >= 0 && 1. - u - v >= 0.0) {
868 const double t12 =
dot(pp1, t1) / n2t1;
869 const double t13 =
dot(pp1, t2) / n2t2;
871 const double t23 =
dot(pp2, t3) / n2t3;
874 if(t12 >= 0 && t12 <= 1.) {
875 d = sign * std::min(fabs(d), p.
distance(p1 + (p2 - p1) * t12));
876 closePt = p1 + (p2 - p1) * t12;
878 if(t13 >= 0 && t13 <= 1.) {
879 if(p.
distance(p1 + (p3 - p1) * t13) < fabs(d))
880 closePt = p1 + (p3 - p1) * t13;
881 d = sign * std::min(fabs(d), p.
distance(p1 + (p3 - p1) * t13));
883 if(t23 >= 0 && t23 <= 1.) {
884 if(p.
distance(p2 + (p3 - p2) * t23) < fabs(d))
885 closePt = p2 + (p3 - p2) * t23;
886 d = sign * std::min(fabs(d), p.
distance(p2 + (p3 - p2) * t23));
890 d = sign * std::min(fabs(d), p.
distance(p1));
894 d = sign * std::min(fabs(d), p.
distance(p2));
898 d = sign * std::min(fabs(d), p.
distance(p3));
904 closePts[i] = closePt;
913 const double alpha =
dot(v1p, v12) /
dot(v12, v12);
919 closePt = p1 + (p2 - p1) * alpha;
924 std::vector<SPoint3> &closePts,
925 const std::vector<SPoint3> &pts,
929 distances.resize(pts.size());
931 closePts.resize(pts.size());
932 for(std::size_t i = 0; i < pts.size(); i++) {
938 closePts[i] = closePt;
944 const SPoint3 &p2,
double *xp,
double *yp,
945 double *otherp,
double *x,
double *y,
double *other)
951 double norm = sqrt(d.
x() * d.
x() + d.
y() * d.
y() + d.
z() * d.
z());
954 d1.
z() * dn.
x() - d1.
x() * dn.
z(),
955 d1.
x() * dn.
y() - d1.
y() * dn.
x());
956 norm = sqrt(d3.
x() * d3.
x() + d3.
y() * d3.
y() + d3.
z() * d3.
z());
959 d3n.
z() * d1.
x() - d3n.
x() * d1.
z(),
960 d3n.
x() * d1.
y() - d3n.
y() * d1.
x());
961 norm = sqrt(d2.
x() * d2.
x() + d2.
y() * d2.
y() + d2.
z() * d2.
z());
963 *xp = p.
x() * d1.
x() + p.
y() * d1.
y() + p.
z() * d1.
z();
964 *yp = p.
x() * d3n.
x() + p.
y() * d3n.
y() + p.
z() * d3n.
z();
965 *otherp = p.
x() * d2n.
x() + p.
y() * d2n.
y() + p.
z() * d2n.
z();
966 *x = closePt.
x() * d1.
x() + closePt.
y() * d1.
y() + closePt.
z() * d1.
z();
967 *y = closePt.
x() * d3n.
x() + closePt.
y() * d3n.
y() + closePt.
z() * d3n.
z();
969 closePt.
x() * d2n.
x() + closePt.
y() * d2n.
y() + closePt.
z() * d2n.
z();
975 double norm = sqrt(d.
x() * d.
x() + d.
y() * d.
y() + d.
z() * d.
z());
978 dn.
z() * d2.
x() - dn.
x() * d2.
z(),
979 dn.
x() * d2.
y() - dn.
y() * d2.
x());
980 norm = sqrt(d3.
x() * d3.
x() + d3.
y() * d3.
y() + d3.
z() * d3.
z());
983 d2.
z() * d3n.
x() - d2.
x() * d3n.
z(),
984 d2.
x() * d3n.
y() - d2.
y() * d3n.
x());
985 norm = sqrt(d1.
x() * d1.
x() + d1.
y() * d1.
y() + d1.
z() * d1.
z());
987 *xp = p.
x() * d2.
x() + p.
y() * d2.
y() + p.
z() * d2.
z();
988 *yp = p.
x() * d3n.
x() + p.
y() * d3n.
y() + p.
z() * d3n.
z();
989 *otherp = p.
x() * d1n.
x() + p.
y() * d1n.
y() + p.
z() * d1n.
z();
990 *x = closePt.
x() * d2.
x() + closePt.
y() * d2.
y() + closePt.
z() * d2.
z();
991 *y = closePt.
x() * d3n.
x() + closePt.
y() * d3n.
y() + closePt.
z() * d3n.
z();
993 closePt.
x() * d1n.
x() + closePt.
y() * d1n.
y() + closePt.
z() * d1n.
z();
998 const double &xp,
double *
distance,
const double &r1,
1013 b = (xp * y - x * yp) / (yp - y);
1014 if(yp == 0.0) { a = -(b + x) / y; }
1023 double da = r1 * r1;
1024 double db = r2 * r2;
1028 ce = (x * x / da) - 1.0;
1033 be = -(2.0 * y) / db;
1034 ce = (y * y / db) - 1.0;
1037 if(fabs(a) < 0.00001) {
1039 be = -(2.0 * y) / db;
1040 ce = (y * y / db) - 1.0;
1044 ae = (1.0 / da) + (1.0 / (db *
a2));
1045 be = (2.0 * y) / (db * a) + (2.0 * b) / (
a2 * db) - ((2.0 * x) / da);
1046 ce = (x * x) / da + (b * b) / (db *
a2) + (2.0 * b * y) / (a * db) +
1051 double rho = be * be - 4 * ae * ce;
1052 double x1, x2, y1, y2, propdist;
1053 if(rho < 0) {
return 1; }
1055 x1 = -(be + sqrt(rho)) / (2.0 * ae);
1056 x2 = (-be + sqrt(rho)) / (2.0 * ae);
1069 if(fabs(a) < 0.00001) {
1082 propdist = (y1 - y) / (yp - y);
1083 if(propdist < 0.0) { propdist = (y2 - y) / (yp - y); }
1087 propdist = (x1 - x) / (xp - x);
1088 if(propdist < 0.0) { propdist = (x2 - x) / (xp - x); }
1092 propdist = (y1 - y) / (yp - y);
1093 if(propdist < 0.0) { propdist = (y2 - y) / (yp - y); }
1106 std::vector<double> &distancesE,
1107 std::vector<int> &isInYarn,
1108 std::vector<SPoint3> &closePts,
1109 const std::vector<SPoint3> &pts,
1111 const double radius)
1114 distances.resize(pts.size());
1116 distancesE.resize(pts.size());
1118 isInYarn.resize(pts.size());
1120 closePts.resize(pts.size());
1122 for(std::size_t i = 0; i < pts.size(); i++) {
1126 closePts[i] = closePt;
1130 distancesE[i] = radius - d;
1134 distancesE[i] = d - radius;
1140 std::vector<double> &distances, std::vector<double> &distancesE,
1141 std::vector<int> &isInYarn, std::vector<SPoint3> &closePts,
1142 const std::vector<SPoint3> &pts,
const SPoint3 &p1,
const SPoint3 &p2,
1143 const double maxA,
const double minA,
const double maxB,
const double minB,
1144 const int typeLevelSet)
1147 distances.resize(pts.size());
1149 distancesE.resize(pts.size());
1151 isInYarn.resize(pts.size());
1153 closePts.resize(pts.size());
1155 for(std::size_t i = 0; i < pts.size(); i++) {
1161 closePts[i] = closePt;
1163 if(!(p.
x() == closePt.
x() && p.
y() == closePt.
y() &&
1164 p.
z() == closePt.
z())) {
1165 double xp, yp, x, y, otherp, other, propdist;
1166 if(typeLevelSet == 2) {
1167 if(p1.
x() == p2.
x()) {
1169 if(fabs(closePt.
x() - 0.0) < 0.00000001) isInYarn[i] = 1;
1170 if(fabs(closePt.
x() - 2.2) < 0.00000001) isInYarn[i] = 1;
1173 if(p1.
y() == p2.
y()) {
1175 if(fabs(closePt.
y() - 0.0) < 0.00000001) isInYarn[i] = 6;
1176 if(fabs(closePt.
y() - 2.2) < 0.00000001) isInYarn[i] = 6;
1179 printf(
"Error %lf %lf\n", closePt.
x(), closePt.
y());
1183 if(typeLevelSet == 1) {
1184 if(p1.
x() == p2.
x()) {
1187 if(fabs(closePt.
x() - 2.2) < 0.00000001) isInYarn[i] = 4;
1194 if(p1.
y() == p2.
y()) {
1197 if(fabs(closePt.
y() - 2.2) < 0.00000001) isInYarn[i] = 7;
1204 printf(
"Error %lf %lf\n", closePt.
x(), closePt.
y());
1208 if(typeLevelSet == 4) {
1209 if(p1.
x() == p2.
x()) {
1211 if(fabs(closePt.
x() - 0.0) < 0.00000001 && closePt.
z() <= 0.35)
1213 if(fabs(closePt.
x() - 2.2) < 0.00000001 && closePt.
z() <= 0.35)
1215 if(fabs(closePt.
x() - 4.4) < 0.00000001 && closePt.
z() <= 0.35)
1217 if(fabs(closePt.
x() - 6.6) < 0.00000001 && closePt.
z() <= 0.35)
1219 if(fabs(closePt.
x() - 8.8) < 0.00000001 && closePt.
z() <= 0.35)
1221 if(fabs(closePt.
x() - 11.0) < 0.00000001 && closePt.
z() <= 0.35)
1223 if(fabs(closePt.
x() - 0.0) < 0.00000001 && closePt.
z() > 0.35)
1225 if(fabs(closePt.
x() - 2.2) < 0.00000001 && closePt.
z() > 0.35)
1227 if(fabs(closePt.
x() - 4.4) < 0.00000001 && closePt.
z() > 0.35)
1229 if(fabs(closePt.
x() - 6.6) < 0.00000001 && closePt.
z() > 0.35)
1231 if(fabs(closePt.
x() - 8.8) < 0.00000001 && closePt.
z() > 0.35)
1233 if(fabs(closePt.
x() - 11.0) < 0.00000001 && closePt.
z() > 0.35)
1237 if(p1.
y() == p2.
y()) {
1239 if(fabs(closePt.
y() - 0.0) < 0.00000001 && closePt.
z() <= 0.35)
1241 if(fabs(closePt.
y() - 2.2) < 0.00000001 && closePt.
z() <= 0.35)
1243 if(fabs(closePt.
y() - 4.4) < 0.00000001 && closePt.
z() <= 0.35)
1245 if(fabs(closePt.
y() - 6.6) < 0.00000001 && closePt.
z() <= 0.35)
1247 if(fabs(closePt.
y() - 8.8) < 0.00000001 && closePt.
z() <= 0.35)
1249 if(fabs(closePt.
y() - 11.0) < 0.00000001 && closePt.
z() <= 0.35)
1251 if(fabs(closePt.
y() - 0.0) < 0.00000001 && closePt.
z() > 0.35)
1253 if(fabs(closePt.
y() - 2.2) < 0.00000001 && closePt.
z() > 0.35)
1255 if(fabs(closePt.
y() - 4.4) < 0.00000001 && closePt.
z() > 0.35)
1257 if(fabs(closePt.
y() - 6.6) < 0.00000001 && closePt.
z() > 0.35)
1259 if(fabs(closePt.
y() - 8.8) < 0.00000001 && closePt.
z() > 0.35)
1261 if(fabs(closePt.
y() - 11.0) < 0.00000001 && closePt.
z() > 0.35)
1265 printf(
"Error %lf %lf\n", closePt.
x(), closePt.
y());
1269 if(typeLevelSet == 3) {
1273 if(typeLevelSet == 5) {
1274 if(p1.
x() == p2.
x()) {
1276 if(fabs(closePt.
x() - 0.0) < 0.00000001) isInYarn[i] = 1;
1277 if(fabs(closePt.
x() - 3.225) < 0.00000001) isInYarn[i] = 2;
1278 if(fabs(closePt.
x() - 6.45) < 0.00000001) isInYarn[i] = 3;
1279 if(fabs(closePt.
x() - 9.675) < 0.00000001) isInYarn[i] = 4;
1280 if(fabs(closePt.
x() - 12.9) < 0.00000001) isInYarn[i] = 1;
1283 if(p1.
y() == p2.
y()) {
1285 if(fabs(closePt.
y() - 0.0) < 0.00000001) isInYarn[i] = 5;
1286 if(fabs(closePt.
y() - 1.665) < 0.00000001) isInYarn[i] = 6;
1287 if(fabs(closePt.
y() - 3.33) < 0.00000001) isInYarn[i] = 7;
1288 if(fabs(closePt.
y() - 4.995) < 0.00000001) isInYarn[i] = 8;
1289 if(fabs(closePt.
y() - 6.66) < 0.00000001) isInYarn[i] = 5;
1292 printf(
"Error %lf %lf\n", closePt.
x(), closePt.
y());
1299 if(fabs(other - otherp) > 0.01) { result = 1; }
1311 distancesE[i] = 1.e10;
1315 if(propdist < 1.0) {
1317 distancesE[i] = (1.0 / propdist) - 1.0;
1320 distancesE[i] = (1.0 - (1.0 / propdist));
1326 distancesE[i] = 1000000.0;
1334 double xp_max = std::max(p1.
x(), p2.
x());
1335 double yp_max = std::max(p1.
y(), p2.
y());
1336 double xq_max = std::max(q1.
x(), q2.
x());
1337 double yq_max = std::max(q1.
y(), q2.
y());
1339 double xp_min = std::min(p1.
x(), p2.
x());
1340 double yp_min = std::min(p1.
y(), p2.
y());
1341 double xq_min = std::min(q1.
x(), q2.
x());
1342 double yq_min = std::min(q1.
y(), q2.
y());
1343 if(yq_min > yp_max || xq_min > xp_max || yq_max < yp_min || xq_max < xp_min) {
1348 A[0][0] = p2.
x() - p1.
x();
1349 A[0][1] = q1.
x() - q2.
x();
1350 A[1][0] = p2.
y() - p1.
y();
1351 A[1][1] = q1.
y() - q2.
y();
1352 double b[2] = {q1.
x() - p1.
x(), q1.
y() - p1.
y()};
1354 return (x[0] >= 0.0 && x[0] <= 1. && x[1] >= 0.0 && x[1] <= 1.);
1362 double n1 = v1.norm();
1363 double n2 = v2.
norm();
1364 double EPS = 1.e-10 * std::max(n1, n2);
1366 A[0][0] = p2.
x() - p1.
x();
1367 A[0][1] = q1.
x() - q2.
x();
1368 A[1][0] = p2.
y() - p1.
y();
1369 A[1][1] = q1.
y() - q2.
y();
1370 double a[2] = {q1.
x() - p1.
x(), q1.
y() - p1.
y()};
1372 B[0][0] = p2.
z() - p1.
z();
1373 B[0][1] = q1.
z() - q2.
z();
1374 B[1][0] = p2.
y() - p1.
y();
1375 B[1][1] = q1.
y() - q2.
y();
1376 double b[2] = {q1.
z() - p1.
z(), q1.
y() - p1.
y()};
1378 C[0][0] = p2.
z() - p1.
z();
1379 C[0][1] = q1.
z() - q2.
z();
1380 C[1][0] = p2.
x() - p1.
x();
1381 C[1][1] = q1.
x() - q2.
x();
1382 double c[2] = {q1.
z() - p1.
z(), q1.
x() - p1.
x()};
1383 double detA = fabs(
det2x2(A));
1384 double detB = fabs(
det2x2(B));
1385 double detC = fabs(
det2x2(C));
1387 if(detA > detB && detA > detC)
1389 else if(detB > detA && detB > detC)
1393 if(x[0] >= 0.0 && x[0] <= 1. && x[1] >= 0.0 && x[1] <= 1.) {
1394 SPoint3 x1(p1.
x() * (1. - x[0]) + p2.
x() * x[0],
1395 p1.
y() * (1. - x[0]) + p2.
y() * x[0],
1396 p1.
z() * (1. - x[0]) + p2.
z() * x[0]);
1397 SPoint3 x2(q1.
x() * (1. - x[1]) + q2.
x() * x[1],
1398 q1.
y() * (1. - x[1]) + q2.
y() * x[1],
1399 q1.
z() * (1. - x[1]) + q2.
z() * x[1]);
1402 double nd =
norm(d);
1404 x[0] = x[1] = 1.e22;
1415 for(
int i = 0; i < 3; i++) meanPlane.
plan[0][i] = t1[i];
1416 for(
int i = 0; i < 3; i++) meanPlane.
plan[1][i] = t2[i];
1417 for(
int i = 0; i < 3; i++) meanPlane.
plan[2][i] = res[i];
1419 meanPlane.
a = res[0];
1420 meanPlane.
b = res[1];
1421 meanPlane.
c = res[2];
1422 meanPlane.
d = res[3];
1424 meanPlane.
x = meanPlane.
y = meanPlane.
z = 0.;
1425 if(fabs(meanPlane.
a) >= fabs(meanPlane.
b) &&
1426 fabs(meanPlane.
a) >= fabs(meanPlane.
c)) {
1427 meanPlane.
x = meanPlane.
d / meanPlane.
a;
1429 else if(fabs(meanPlane.
b) >= fabs(meanPlane.
a) &&
1430 fabs(meanPlane.
b) >= fabs(meanPlane.
c)) {
1431 meanPlane.
y = meanPlane.
d / meanPlane.
b;
1434 meanPlane.
z = meanPlane.
d / meanPlane.
c;
1441 double xm = 0., ym = 0., zm = 0.;
1442 int ndata = points.size();
1444 for(
int i = 0; i < ndata; i++) {
1445 xm += points[i].x();
1446 ym += points[i].y();
1447 zm += points[i].z();
1449 xm /= (double)ndata;
1450 ym /= (double)ndata;
1451 zm /= (double)ndata;
1455 for(
int i = 0; i < ndata; i++) {
1456 U(i, 0) = points[i].x() - xm;
1457 U(i, 1) = points[i].y() - ym;
1458 U(i, 2) = points[i].z() - zm;
1461 double res[4], svd[3];
1466 if(fabs(svd[0]) < fabs(svd[1]) && fabs(svd[0]) < fabs(svd[2]))
1468 else if(fabs(svd[1]) < fabs(svd[0]) && fabs(svd[1]) < fabs(svd[2]))
1477 double ex[3], t1[3], t2[3];
1479 ex[0] = ex[1] = ex[2] = 0.0;
1482 else if(res[1] == 0.)
1492 res[3] = (xm * res[0] + ym * res[1] + zm * res[2]);
1503 double a = meanPlane.
a;
1504 double b = meanPlane.
b;
1505 double c = meanPlane.
c;
1506 double d = meanPlane.
d;
1507 double t0 = -(a * u + b * v +
c * w + d) / (a * a + b * b +
c *
c);
1509 ptProj[0] = u + a * t0;
1510 ptProj[1] = v + b * t0;
1511 ptProj[2] = w +
c * t0;
1515 std::vector<SPoint3> &ptsProj,
1518 ptsProj.resize(pts.size());
1519 for(std::size_t i = 0; i < pts.size(); i++) {
1525 std::vector<SPoint3> &pointsUV,
1529 pointsUV.resize(ptsProj.size());
1530 SVector3 normal(meanPlane.
a, meanPlane.
b, meanPlane.
c);
1534 for(std::size_t i = 0; i < ptsProj.size(); i++) {
1535 SVector3 pp(ptsProj[i][0] - ptCG[0], ptsProj[i][1] - ptCG[1],
1536 ptsProj[i][2] - ptCG[2]);
1537 pointsUV[i][0] =
dot(pp, tangent);
1538 pointsUV[i][1] =
dot(pp, binormal);
1539 pointsUV[i][2] =
dot(pp, normal);
1546 double *param = (
double *)data;
1547 double x0 = param[0], x1 = param[1], y0 = param[2], y1 = param[3],
1549 res(0) = (ys - 1 / x(0)) + 1 / x(0) * cosh(x(0) * (x0 - x(1))) - y0;
1550 res(1) = (ys - 1 / x(0)) + 1 / x(0) * cosh(x(0) * (x1 - x(1))) - y1;
1554 bool catenary(
double x0,
double x1,
double y0,
double y1,
double ys,
int N,
1568 double param[5] = {x0, x1, y0, y1, ys};
1570 bool success =
false, physical =
true;
1571 double tolx = 1e-6 * fabs(x1 - x0);
1572 double toly = 1e-6 * fabs(std::max(y0, y1) - ys);
1574 x(0) = 1. / (x1 - x0);
1575 x(1) = (x0 + x1) / 2.;
1579 double a = ys - 1 / x(0);
1580 for(
int i = 0; i < N; i++) {
1581 double r = x0 + (i + 1) * (x1 - x0) / (N + 1);
1582 yp[i] = a + 1 / x(0) * cosh(x(0) * (r - x(1)));
1583 if(yp[i] > std::max(y0, y1) + toly || yp[i] < ys - toly) {
1589 if(physical)
return true;
1592 for(
int i = 0; i < N; i++) { yp[i] = y0 + (i + 1) * (y1 - y0) / (N + 1); }