49 #define GEO_ALGORITHMS_C 53 #include "Algorithms.hh" 54 #include <ACG/Utils/NumLimitsT.hh> 55 #include <ACG/Utils/VSToolsT.hh> 56 #include <ACG/Math/GLMatrixT.hh> 81 template<
typename Scalar>
95 Scalar nx = vu[1]*wu[2] - vu[2]*wu[1],
96 ny = vu[2]*wu[0] - vu[0]*wu[2],
97 nz = vu[0]*wu[1] - vu[1]*wu[0],
103 unsigned char max_coord;
128 if (1.0+ax == 1.0)
return false;
129 _result[1] = 1.0 + (pu[1]*wu[2]-pu[2]*wu[1])/nx - 1.0;
130 _result[2] = 1.0 + (vu[1]*pu[2]-vu[2]*pu[1])/nx - 1.0;
131 _result[0] = 1.0 - _result[1] - _result[2];
137 if (1.0+ay == 1.0)
return false;
138 _result[1] = 1.0 + (pu[2]*wu[0]-pu[0]*wu[2])/ny - 1.0;
139 _result[2] = 1.0 + (vu[2]*pu[0]-vu[0]*pu[2])/ny - 1.0;
140 _result[0] = 1.0 - _result[1] - _result[2];
146 if (1.0+az == 1.0)
return false;
147 _result[1] = 1.0 + (pu[0]*wu[1]-pu[1]*wu[0])/nz - 1.0;
148 _result[2] = 1.0 + (vu[0]*pu[1]-vu[1]*pu[0])/nz - 1.0;
149 _result[0] = 1.0 - _result[1] - _result[2];
162 typename Vec::value_type
167 return 0.25 * ((_v1-_v0)%(_v2-_v0)).sqrnorm();
171 template<
typename Scalar>
177 if(_polygon_points.size() < 3)
184 for(
size_t i = 0; i<_polygon_points.size(); i++)
186 cog += _polygon_points[i];
188 cog /= ((Scalar)_polygon_points.size());
194 while((std::fabs(n[0])<1e-30) & (std::fabs(n[1])<1e-30) & (std::fabs(n[2])<1e-30))
196 n = ( _polygon_points[c] - cog )%(_polygon_points[(c+1)%_polygon_points.size()] - cog );
198 if(c == _polygon_points.size()+1)
200 std::cerr <<
"warning: no valid normal found \n";
208 std::cerr <<
"warning: no valid normal found normal"<< n<<
" norm "<<n.
norm()<<
" \n";
221 if((angle != 0.0) && rotation)
227 std::vector<VectorT<Scalar,2> > rotated_points;
228 for(
size_t i = 0; i<_polygon_points.size(); i++)
231 VectorT<Scalar,4> new_point_4(new_point_3[0], new_point_3[1], new_point_3[2], 0);
232 new_point_4 = R*new_point_4;
238 if((n|(_v1 - _v0)) == 0.0)
249 Scalar alpha = (d - (n|_v0))/(n|(_v1 - _v0));
250 _result = _v0 + alpha*(_v1 - _v0);
253 if(alpha > 1.0 || alpha < 0.0)
258 VectorT<Scalar,4> rotated_result(_result[0] - cog[0], _result[1] - cog[1], _result[2] - cog[2], 0);
259 rotated_result = R*rotated_result;
264 size_t points_count = rotated_points.size();
265 for(
size_t i = 0; i<points_count; i++)
269 VectorT<Scalar,2> mid_e = 0.5 * (rotated_points[((i+1)%points_count)] + rotated_points[i]);
272 int sgn0 = ((n_e|cmp0) < 0 )? -1 : ((n_e|cmp0) > 0);
273 int sgn1 = ((n_e|cmp1) < 0 )? -1 : ((n_e|cmp1) > 0);
275 if(sgn1 != sgn0 && sgn1 != 0)
289 typename Vec::value_type
295 Vec d1(_p-_v0), d2(_v1-_v0), min_v(_v0);
296 typename Vec::value_type t = (d1|d2)/ d2.sqrnorm();
298 if (t > 1.0) d1 = _p - (min_v = _v1);
299 else if (t > 0.0) d1 = _p - (min_v = _v0 + d2*t);
301 if (_min_v) *_min_v = min_v;
308 typename Vec::value_type
309 distPointTriangleSquared(
const Vec& _p,
316 Vec v0v1 = _v1 - _v0;
317 Vec v0v2 = _v2 - _v0;
319 typename Vec::value_type d = n.sqrnorm();
323 if (d < FLT_MIN && d > -FLT_MIN) {
325 const double l0 = v0v1.sqrnorm();
326 const double l1 = v0v2.sqrnorm();
327 const double l2 = (_v2 - _v1).sqrnorm();
328 if (l0 > l1 && l0 > l2) {
331 else if (l1 > l0 && l1 > l2) {
338 std::cerr <<
"distPointTriangleSquared: Degenerated triangle !\n";
342 typename Vec::value_type invD =
typename Vec::value_type(1.0) / d;
347 Vec v1v2 = _v2 - _v1;
348 typename Vec::value_type inv_v0v2_2 =
typename Vec::value_type(1.0) / v0v2.sqrnorm();
349 typename Vec::value_type inv_v0v1_2 =
typename Vec::value_type(1.0) / v0v1.sqrnorm();
350 typename Vec::value_type inv_v1v2_2 =
typename Vec::value_type(1.0) / v1v2.sqrnorm();
355 typename Vec::value_type s01, s02, s12;
356 typename Vec::value_type a = (t | v0v2) * -invD;
357 typename Vec::value_type b = (t | v0v1) * invD;
363 s02 = ( v0v2 | v0p ) * inv_v0v2_2;
366 s01 = ( v0v1 | v0p ) * inv_v0v1_2;
369 }
else if (s01 >= 1.0) {
372 v0p = _v0 + v0v1 * s01;
374 }
else if (s02 > 1.0) {
375 s12 = ( v1v2 | ( _p - _v1 )) * inv_v1v2_2;
378 }
else if (s12 <= 0.0) {
381 v0p = _v1 + v1v2 * s12;
384 v0p = _v0 + v0v2 * s02;
386 }
else if (b < 0.0) {
388 s01 = ( v0v1 | v0p ) * inv_v0v1_2;
391 s02 = ( v0v2 | v0p ) * inv_v0v2_2;
394 }
else if (s02 >= 1.0) {
397 v0p = _v0 + v0v2 * s02;
399 }
else if (s01 > 1.0) {
400 s12 = ( v1v2 | ( _p - _v1 )) * inv_v1v2_2;
403 }
else if (s12 <= 0.0) {
406 v0p = _v1 + v1v2 * s12;
409 v0p = _v0 + v0v1 * s01;
411 }
else if (a+b > 1.0) {
413 s12 = ( v1v2 | ( _p - _v1 )) * inv_v1v2_2;
415 s02 = ( v0v2 | v0p ) * inv_v0v2_2;
418 }
else if (s02 >= 1.0) {
421 v0p = _v0 + v0v2*s02;
423 }
else if (s12 <= 0.0) {
424 s01 = ( v0v1 | v0p ) * inv_v0v1_2;
427 }
else if (s01 >= 1.0) {
430 v0p = _v0 + v0v1 * s01;
433 v0p = _v1 + v1v2 * s12;
437 _nearestPoint = _p - n*((n|v0p) * invD);
438 return (_nearestPoint - _p).sqrnorm();
443 return (_nearestPoint - _p).sqrnorm();
450 typename Vec::value_type
451 distPointTriangleSquared(
const Vec& _p,
457 return distPointTriangleSquared(_p, _v0, _v1, _v2, _nearestPoint,
false);
465 typename Vec::value_type
472 return distPointTriangleSquared(_p, _v0, _v1, _v2, _nearestPoint,
true);
484 template<
typename Scalar>
499 Scalar fA01 = -(d0|d1);
501 Scalar fB0 = (kDiff|d0);
503 Scalar fDet = fabs(fA00*fA11-fA01*fA01);
504 Scalar fB1, fS, fT, fSqrDist, fTmp;
507 if ( fDet >= FLT_MIN )
511 fS = fA01*fB1-fA11*fB0;
512 fT = fA01*fB0-fA00*fB1;
518 if ( fS < 0.0 ) fS = 0.0;
519 else if ( fS > fDet ) fS = fDet;
520 if ( fT < 0.0 ) fT = 0.0;
521 else if ( fT > fDet ) fT = fDet;
534 Scalar fInvDet = 1.0/fDet;
537 fSqrDist = fS*(fA00*fS+fA01*fT+2.0*fB0) +
538 fT*(fA01*fS+fA11*fT+2.0*fB1)+fC;
547 fSqrDist = fA11+2.0*fB1+fC;
549 else if ( -fTmp >= fA00 )
552 fSqrDist = fA00+fA11+fC+2.0*(fB1+fTmp);
557 fSqrDist = fTmp*fS+fA11+2.0*fB1+fC;
569 else if ( -fB0 >= fA00 )
572 fSqrDist = fA00+2.0*fB0+fC;
577 fSqrDist = fB0*fS+fC;
592 fSqrDist = fA00+2.0*fB0+fC;
594 else if ( -fTmp >= fA11 )
597 fSqrDist = fA00+fA11+fC+2.0*(fB0+fTmp);
602 fSqrDist = fTmp*fT+fA00+2.0*fB0+fC;
614 fSqrDist = fA11+2.0*fB1+fC;
619 fSqrDist = fTmp*fS+fA11+2.0*fB1+fC;
629 fSqrDist = fA00+2.0*fB0+fC;
631 else if ( -fTmp >= fA11 )
634 fSqrDist = fA00+fA11+fC+2.0*(fB0+fTmp);
639 fSqrDist = fTmp*fT+fA00+2.0*fB0+fC;
657 fSqrDist = fB0*fS+fC;
667 fSqrDist = fA00+2.0*fB0+fC;
669 else if ( -fTmp >= fA11 )
672 fSqrDist = fA00+fA11+fC+2.0*(fB0+fTmp);
677 fSqrDist = fTmp*fT+fA00+2.0*fB0+fC;
695 else if ( -fB1 >= fA11 )
698 fSqrDist = fA11+2.0*fB1+fC;
703 fSqrDist = fB1*fT+fC;
715 fSqrDist = fA00+fA11+fC+2.0*(fB1+fTmp);
720 fSqrDist = fTmp*fS+fA11+2.0*fB1+fC;
731 else if ( -fB1 >= fA11 )
734 fSqrDist = fA11+2.0*fB1+fC;
739 fSqrDist = fB1*fT+fC;
752 fSqrDist = fA00+2.0*fB0+fC;
757 fSqrDist = fB0*fS+fC;
768 else if ( -fB1 >= fA11 )
771 fSqrDist = fA11+2.0*fB1+fC;
776 fSqrDist = fB1*fT+fC;
794 else if ( -fB0 <= fA00 )
798 fSqrDist = fB0*fS+fC;
808 fSqrDist = fA00+fA11+fC+2.0*(fA01+fB0+fB1);
813 fSqrDist = fA00+2.0*fB0+fC+fT*(fA11*fT+2.0*(fA01+fB1));
824 fSqrDist = fA00+2.0*fB0+fC;
826 else if ( fB0 <= 0.0 )
830 fSqrDist = fB0*fS+fC;
839 fSqrDist = fA11+2.0*fB1+fC;
844 fSqrDist = fC+fT*(2.0*fB1+fA11*fT);
851 if (_min_v0) *_min_v0 = _v00 + fS*d0;
852 if (_min_v1) *_min_v1 = _v10 + fT*d1;
854 return fabs(fSqrDist);
859 template <
typename VectorT ,
typename ValueT >
866 assert( fabs(_pnormal.
norm()) > 0.0000000001) ;
867 return( ( (_point - _porigin) | _pnormal ) );
873 template <
typename VectorT >
876 VectorT direction = ( _end - _start ).normalize();
877 assert( fabs(direction.
norm()) > 0.0000000001) ;
878 const VectorT projected_point = ( ( _point - _start ) | direction ) * direction + _start;
880 if ( ( ( projected_point - _start ) | direction ) > ( ( _end - _start ) | direction ) )
883 if ( ( ( projected_point - _start ) | direction ) < 0 )
886 return projected_point;
891 template <
typename VectorT >
898 return (_point - _pnormal * distPointPlane< VectorT , double >( _porigin , _pnormal , _point ) );
904 template<
typename Scalar>
914 G((_v0+_v1+_v2)/3.0);
928 _result = (Scalar)0.5 * ((Scalar)3.0*G - H);
938 template<
typename Scalar>
948 Scalar denom = 4.0*((v0v1%v0v2).sqrnorm());
953 return ( v0v1.sqrnorm() *
961 template<
typename Scalar>
978 _axis = (v0 % v1).normalize();
981 if ( std::isnan(_axis[0]) || std::isnan(_axis[1]) || std::isnan(_axis[2]) ) {
986 _angle = acos(v0 | v1);
989 if ( std::isnan(_angle) )
994 _angle *= 180.0 / M_PI;
1002 template<
class VectorT>
1007 const double a0 = ((_p1-_p0)|(_p2-_p0));
1009 if ( a0<0.0)
return 1;
1012 const double a1 = ((_p0-_p1)|(_p2-_p1));
1014 if (a1 < 0.0 )
return 2;
1017 const double a2 = ((_p0-_p2)|(_p1-_p2));
1019 if (a2 < 0.0 )
return 3;
1028 template<
typename Scalar>
1048 _center = (_v0+_v1)*0.5;
1049 _radius = 0.5 * c.
norm();
1054 _center = (_v1+_v2)*0.5;
1055 _radius = 0.5 * a.
norm();
1060 _center = (_v2+_v0)*0.5;
1061 _radius = 0.5 * b.
norm();
1078 _center = (Scalar)0.5 * ((Scalar)3.0*G - H);
1079 _radius = (_center-_v0).norm();
1088 template<
typename Scalar>
1098 Scalar denom = 4.0*((v0v1%v0v2).sqrnorm());
1103 Scalar l0 = v0v1.sqrnorm(),
1104 l1 = v0v2.sqrnorm(),
1106 l3 = l0*l1*l2/denom;
1108 return std::max(std::max(l0, l1), std::max(l2, l3));
1115 template<
typename Scalar>
1128 Scalar denom = ((v0v1[0]*v0v2[1]*v0v3[2] +
1129 v0v1[1]*v0v2[2]*v0v3[0] +
1130 v0v1[2]*v0v2[0]*v0v3[1]) -
1131 (v0v1[0]*v0v2[2]*v0v3[1] +
1132 v0v1[1]*v0v2[0]*v0v3[2] +
1133 v0v1[2]*v0v2[1]*v0v3[0])) * 2.0;
1139 _result = _v0 + (( v0v3.sqrnorm()*(v0v1%v0v2) +
1140 v0v2.sqrnorm()*(v0v3%v0v1) +
1141 v0v1.sqrnorm()*(v0v2%v0v3) ) / denom);
1150 template <
typename Scalar>
1154 if (fabs(v[0]) < fabs(v[1])) {
1155 if (fabs(v[0]) < fabs(v[2]))
1156 return VectorT<Scalar, 3>(Scalar(1.0) - v[0] * v[0], -v[0] * v[1], -v[0] * v[2]).normalize();
1158 if (fabs(v[1]) < fabs(v[2]))
1159 return VectorT<Scalar, 3>(-v[1] * v[0], Scalar(1.0) - v[1] * v[1], -v[1] * v[2]).normalize();
1162 return VectorT<Scalar, 3>(-v[2] * v[0], -v[2] * v[1], Scalar(1.0) - v[2] * v[2]).normalize();
1171 template<
typename Scalar>
1179 Scalar v0(_v[0]-_u[0]), v1(_v[1]-_u[1]),
1180 w0(_w[0]-_u[0]), w1(_w[1]-_u[1]),
1181 p0(_p[0]-_u[0]), p1(_p[1]-_u[1]),
1182 denom = v0*w1-v1*w0;
1184 if (1.0+fabs(denom) == 1.0) {
1185 std::cerr <<
"degen tri: (" 1192 _result[1] = 1.0 + ((p0*w1-p1*w0)/denom) - 1.0;
1193 _result[2] = 1.0 + ((v0*p1-v1*p0)/denom) - 1.0;
1194 _result[0] = 1.0 - _result[1] - _result[2];
1203 template<
typename Scalar>
1212 _t1 = ((_v0[1]-_v2[1])*(_v3[0]-_v2[0])-(_v0[0]-_v2[0])*(_v3[1]-_v2[1])) /
1213 ((_v1[0]-_v0[0])*(_v3[1]-_v2[1])-(_v1[1]-_v0[1])*(_v3[0]-_v2[0]));
1215 _t2 = ((_v0[1]-_v2[1])*(_v1[0]-_v0[0])-(_v0[0]-_v2[0])*(_v1[1]-_v0[1])) /
1216 ((_v1[0]-_v0[0])*(_v3[1]-_v2[1])-(_v1[1]-_v0[1])*(_v3[0]-_v2[0]));
1218 return ((_t1>0.0) && (_t1<1.0) && (_t2>0.0) && (_t2<1.0));
1224 template<
typename Scalar>
1231 Scalar x0(_v0[0]), y0(_v0[1]), xy0(x0*x0+y0*y0),
1232 x1(_v1[0]), y1(_v1[1]), xy1(x1*x1+y1*y1),
1233 x2(_v2[0]), y2(_v2[1]), xy2(x2*x2+y2*y2),
1234 a(x0*y1 - x0*y2 - x1*y0 + x1*y2 + x2*y0 - x2*y1),
1235 b(xy0*y1 - xy0*y2 - xy1*y0 + xy1*y2 + xy2*y0 - xy2*y1),
1236 c(xy0*x1 - xy0*x2 - xy1*x0 + xy1*x2 + xy2*x0 - xy2*x1);
1238 if (Scalar(1.0)+a == Scalar(1.0)) {
1239 std::cerr <<
"circumcircle: colinear points\n";
1243 _result[0] = 0.5*b/a;
1244 _result[1] = -0.5*c/a;
1254 template <
typename Scalar,
int N>
1264 Scalar l2, maxl2 = d0.
sqrnorm();
1265 if ((l2=d1.
sqrnorm()) > maxl2)
1269 if ((l2=d1.
sqrnorm()) > maxl2)
1273 Scalar a2 = (d0 % d1).sqrnorm();
1283 return sqrt( (maxl2 * maxl2) / a2 );
1290 template <
typename Scalar,
int N>
1296 const double FOUR_ROOT3 = 6.928203230275509;
1298 double area = 0.5*((_v1-_v0)%(_v2-_v0)).norm();
1300 return (Scalar) (FOUR_ROOT3 * area / ((_v0-_v1).sqrnorm() +
1301 (_v1-_v2).sqrnorm() +
1302 (_v2-_v0).sqrnorm() ));
1305 template<
typename Vec>
1312 typename Vec::value_type& _t,
1313 typename Vec::value_type& _u,
1314 typename Vec::value_type& _v )
1317 Vec edge1, edge2, tvec, pvec, qvec;
1318 typename Vec::value_type det, inv_det;
1325 pvec = _dir % edge2;
1330 static const typename Vec::value_type EPSILON = std::numeric_limits<typename Vec::value_type>::epsilon() * 1e2;
1331 if (det > -EPSILON && det < EPSILON) {
1334 inv_det =
typename Vec::value_type(1.0) / det;
1340 _u = (tvec | pvec) * inv_det;
1341 if (_u < 0.0 || _u > 1.0)
1345 qvec = tvec % edge1;
1348 _v = (_dir | qvec) * inv_det;
1349 if (_v < 0.0 || _u + _v > 1.0)
1353 _t = (edge2 | qvec) * inv_det;
1357 template<
typename Vec>
1363 typename Vec::value_type& tmin,
1364 typename Vec::value_type& tmax )
1375 typename Vec::value_type tymin, tymax, tzmin, tzmax;
1378 inv_dir[0] = 1/_dir[0];
1379 inv_dir[1] = 1/_dir[1];
1380 inv_dir[2] = 1/_dir[2];
1382 if (inv_dir[0] >= 0) {
1383 tmin = (_bbmin[0] - _o[0]) * inv_dir[0];
1384 tmax = (_bbmax[0] - _o[0]) * inv_dir[0];
1387 tmin = (_bbmax[0] - _o[0]) * inv_dir[0];
1388 tmax = (_bbmin[0] - _o[0]) * inv_dir[0];
1391 if (inv_dir[1] >= 0) {
1392 tymin = (_bbmin[1] - _o[1]) * inv_dir[1];
1393 tymax = (_bbmax[1] - _o[1]) * inv_dir[1];
1396 tymin = (_bbmax[1] - _o[1]) * inv_dir[1];
1397 tymax = (_bbmin[1] - _o[1]) * inv_dir[1];
1400 if ( (tmin > tymax) || (tymin > tmax) )
1407 if (inv_dir[2] >= 0) {
1408 tzmin = (_bbmin[2] - _o[2]) * inv_dir[2];
1409 tzmax = (_bbmax[2] - _o[2]) * inv_dir[2];
1412 tzmin = (_bbmax[2] - _o[2]) * inv_dir[2];
1413 tzmax = (_bbmin[2] - _o[2]) * inv_dir[2];
1416 if ( (tmin > tzmax) || (tzmin > tmax) )
void rotate(Scalar angle, Scalar x, Scalar y, Scalar z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
Vec::value_type distPointLineSquared(const Vec &_p, const Vec &_v0, const Vec &_v1, Vec *_min_v)
squared distance from point _p to line segment (_v0,_v1)
Scalar distLineLineSquared(const VectorT< Scalar, 3 > &_v00, const VectorT< Scalar, 3 > &_v01, const VectorT< Scalar, 3 > &_v10, const VectorT< Scalar, 3 > &_v11, VectorT< Scalar, 3 > *_min_v0, VectorT< Scalar, 3 > *_min_v1, bool _fastApprox)
squared distance of lines (_v00, _v01) and (_v10, _v11)
Vec::value_type triangleAreaSquared(const Vec &_v0, const Vec &_v1, const Vec &_v2)
return squared area of triangle (_v0, _v1, _v2)
Namespace providing different geometric functions concerning angles.
Scalar circumRadiusSquared(const VectorT< Scalar, 3 > &_v0, const VectorT< Scalar, 3 > &_v1, const VectorT< Scalar, 3 > &_v2)
return squared radius of circumcircle of triangle (_v0,_v1,_v2)
void identity()
setup an identity matrix
bool triangleIntersection(const Vec &_o, const Vec &_dir, const Vec &_v0, const Vec &_v1, const Vec &_v2, typename Vec::value_type &_t, typename Vec::value_type &_u, typename Vec::value_type &_v)
Intersect a ray and a triangle.
VectorT projectToEdge(const VectorT &_start, const VectorT &_end, const VectorT &_point)
bool lineIntersection(const VectorT< Scalar, 2 > &_v0, const VectorT< Scalar, 2 > &_v1, const VectorT< Scalar, 2 > &_v2, const VectorT< Scalar, 2 > &_v3, Scalar &_t1, Scalar &_t2)
intersect two line segments (_v0,_v1) and (_v2,_v3)
Scalar aspectRatio(const VectorT< Scalar, N > &_v0, const VectorT< Scalar, N > &_v1, const VectorT< Scalar, N > &_v2)
return aspect ratio (length/height) of triangle
bool edgeConvexPolygonIntersection(std::vector< VectorT< Scalar, 3 > > _polygon_points, VectorT< Scalar, 3 > _v0, VectorT< Scalar, 3 > _v1, VectorT< Scalar, 3 > &_result)
Get intersection point of a ray and a convex polygon.
bool circumCenter(const VectorT< Scalar, 3 > &_v0, const VectorT< Scalar, 3 > &_v1, const VectorT< Scalar, 3 > &_v2, VectorT< Scalar, 3 > &_result)
return circumcenter of triangle (_v0,_v1,_v2)
4x4 matrix implementing OpenGL commands.
ValueT distPointPlane(const VectorT &_porigin, const VectorT &_pnormal, const VectorT &_point)
Checks the distance from a point to a plane.
bool baryCoord(const VectorT< Scalar, 3 > &_p, const VectorT< Scalar, 3 > &_u, const VectorT< Scalar, 3 > &_v, const VectorT< Scalar, 3 > &_w, VectorT< Scalar, 3 > &_result)
auto norm() const -> decltype(std::sqrt(std::declval< VectorT< S, DIM >>().sqrnorm()))
compute euclidean norm
Vec::value_type distPointTriangleSquaredStable(const Vec &_p, const Vec &_v0, const Vec &_v1, const Vec &_v2, Vec &_nearestPoint)
squared distance from point _p to triangle (_v0, _v1, _v2)
bool minSphere(const VectorT< Scalar, 3 > &_v0, const VectorT< Scalar, 3 > &_v1, const VectorT< Scalar, 3 > &_v2, VectorT< Scalar, 3 > &_center, Scalar &_radius)
construct min. enclosing sphere
bool rotationOfTwoVectors(const VectorT< Scalar, 3 > &_v0, const VectorT< Scalar, 3 > &_v1, VectorT< Scalar, 3 > &_axis, Scalar &_angle, bool _degree)
Get rotation axis and signed angle of rotation between two vectors.
decltype(std::declval< S >() *std::declval< S >()) sqrnorm() const
compute squared euclidean norm
VectorT projectToPlane(const VectorT &_porigin, const VectorT &_pnormal, const VectorT &_point)
projects a point to a plane
static Scalar min()
Return the smallest absolte value a scalar type can store.
Scalar roundness(const VectorT< Scalar, N > &_v0, const VectorT< Scalar, N > &_v1, const VectorT< Scalar, N > &_v2)
return roundness of triangle: 1=equilateral, 0=colinear
Scalar minRadiusSquared(const VectorT< Scalar, 3 > &_v0, const VectorT< Scalar, 3 > &_v1, const VectorT< Scalar, 3 > &_v2)
return squared radius of min. enclosing circle of triangle (_v0,_v1,_v2)
auto normalize() -> decltype(*this/=std::declval< VectorT< S, DIM >>().norm())
VectorT< Scalar, 3 > perpendicular(const VectorT< Scalar, 3 > &v)
find a vector that's perpendicular to _v
bool axisAlignedBBIntersection(const Vec &_o, const Vec &_dir, const Vec &_bbmin, const Vec &_bbmax, typename Vec::value_type &tmin, typename Vec::value_type &tmax)
Intersect a ray and an axis aligned bounding box.
int isObtuse(const VectorT &_p0, const VectorT &_p1, const VectorT &_p2)