38 #ifndef FCL_BV_DETAIL_UTILITY_INL_H 39 #define FCL_BV_DETAIL_UTILITY_INL_H 41 #include "fcl/math/geometry.h" 47 void normalize(Vector3d& v,
bool* signal);
51 void hat(Matrix3d& mat,
const Vector3d& vec);
55 void eigen(
const Matrix3d& m, Vector3d& dout, Matrix3d& vout);
59 void eigen_old(
const Matrix3d& m, Vector3d& dout, Matrix3d& vout);
64 const Matrix3d& eigenV,
const Vector3d& eigenS, Matrix3d& axis);
68 void axisFromEigen(
const Matrix3d& eigenV,
69 const Vector3d& eigenS,
74 void generateCoordinateSystem(Matrix3d& axis);
78 void generateCoordinateSystem(Transform3d& tf);
82 void getRadiusAndOriginAndRectangleSize(
86 unsigned int* indices,
95 void getRadiusAndOriginAndRectangleSize(
99 unsigned int* indices,
107 void circumCircleComputation(
116 double maximumDistance(
120 unsigned int* indices,
122 const Vector3d& query);
126 void getExtentAndCenter(
130 unsigned int* indices,
132 const Matrix3d& axis,
142 unsigned int* indices,
150 template <
typename S>
151 S maximumDistance_mesh(
155 unsigned int* indices,
157 const Vector3<S>& query)
159 bool indirect_index =
true;
160 if(!indices) indirect_index =
false;
163 for(
int i = 0; i < n; ++i)
165 unsigned int index = indirect_index ? indices[i] : i;
166 const Triangle& t = ts[index];
168 for(
int j = 0; j < 3; ++j)
171 const Vector3<S>& p = ps[point_id];
173 S d = (p - query).squaredNorm();
174 if(d > maxD) maxD = d;
179 for(
int j = 0; j < 3; ++j)
182 const Vector3<S>& p = ps2[point_id];
184 S d = (p - query).squaredNorm();
185 if(d > maxD) maxD = d;
190 return std::sqrt(maxD);
194 template <
typename S>
195 S maximumDistance_pointcloud(
198 unsigned int* indices,
200 const Vector3<S>& query)
202 bool indirect_index =
true;
203 if(!indices) indirect_index =
false;
206 for(
int i = 0; i < n; ++i)
208 int index = indirect_index ? indices[i] : i;
210 const Vector3<S>& p = ps[index];
211 S d = (p - query).squaredNorm();
212 if(d > maxD) maxD = d;
216 const Vector3<S>& v = ps2[index];
217 S d = (v - query).squaredNorm();
218 if(d > maxD) maxD = d;
222 return std::sqrt(maxD);
228 template <
typename S>
229 void getExtentAndCenter_pointcloud(
232 unsigned int* indices,
234 const Matrix3<S>& axis,
238 bool indirect_index =
true;
239 if(!indices) indirect_index =
false;
241 auto real_max = std::numeric_limits<S>::max();
243 Vector3<S> min_coord = Vector3<S>::Constant(real_max);
244 Vector3<S> max_coord = Vector3<S>::Constant(-real_max);
246 for(
int i = 0; i < n; ++i)
248 int index = indirect_index ? indices[i] : i;
250 const Vector3<S>& p = ps[index];
256 for(
int j = 0; j < 3; ++j)
258 if(proj[j] > max_coord[j])
259 max_coord[j] = proj[j];
261 if(proj[j] < min_coord[j])
262 min_coord[j] = proj[j];
267 const Vector3<S>& v = ps2[index];
273 for(
int j = 0; j < 3; ++j)
275 if(proj[j] > max_coord[j])
276 max_coord[j] = proj[j];
278 if(proj[j] < min_coord[j])
279 min_coord[j] = proj[j];
284 const Vector3<S> o = (max_coord + min_coord) / 2;
285 center.noalias() = axis * o;
286 extent.noalias() = (max_coord - min_coord) * 0.5;
292 template <
typename S>
293 void getExtentAndCenter_mesh(
297 unsigned int* indices,
299 const Matrix3<S>& axis,
303 bool indirect_index =
true;
304 if(!indices) indirect_index =
false;
306 auto real_max = std::numeric_limits<S>::max();
308 Vector3<S> min_coord = Vector3<S>::Constant(real_max);
309 Vector3<S> max_coord = Vector3<S>::Constant(-real_max);
311 for(
int i = 0; i < n; ++i)
313 unsigned int index = indirect_index? indices[i] : i;
314 const Triangle& t = ts[index];
316 for(
int j = 0; j < 3; ++j)
319 const Vector3<S>& p = ps[point_id];
325 for(
int k = 0; k < 3; ++k)
327 if(proj[k] > max_coord[k])
328 max_coord[k] = proj[k];
330 if(proj[k] < min_coord[k])
331 min_coord[k] = proj[k];
337 for(
int j = 0; j < 3; ++j)
340 const Vector3<S>& p = ps2[point_id];
346 for(
int k = 0; k < 3; ++k)
348 if(proj[k] > max_coord[k])
349 max_coord[k] = proj[k];
351 if(proj[k] < min_coord[k])
352 min_coord[k] = proj[k];
358 const Vector3<S> o = (max_coord + min_coord) / 2;
359 center.noalias() = axis * o;
360 extent.noalias() = (max_coord - min_coord) / 2;
365 double maximumDistance_mesh(
369 unsigned int* indices,
371 const Vector3d& query);
375 double maximumDistance_pointcloud(
378 unsigned int* indices,
380 const Vector3d& query);
384 void getExtentAndCenter_pointcloud(
386 Vector3<double>* ps2,
387 unsigned int* indices,
389 const Matrix3<double>& axis,
390 Vector3<double>& center,
391 Vector3<double>& extent);
395 void getExtentAndCenter_mesh(
397 Vector3<double>* ps2,
399 unsigned int* indices,
401 const Matrix3<double>& axis,
402 Vector3<double>& center,
403 Vector3<double>& extent);
410 template <
typename S>
411 void normalize(Vector3<S>& v,
bool* signal)
413 S sqr_length = v.squaredNorm();
417 v /= std::sqrt(sqr_length);
427 template <
typename Derived>
428 typename Derived::RealScalar triple(
const Eigen::MatrixBase<Derived>& x,
429 const Eigen::MatrixBase<Derived>& y,
430 const Eigen::MatrixBase<Derived>& z)
432 return x.dot(y.cross(z));
436 template <
typename Derived>
437 void generateCoordinateSystem(
438 const Eigen::MatrixBase<Derived>& w,
439 Eigen::MatrixBase<Derived>& u,
440 Eigen::MatrixBase<Derived>& v)
442 typename Derived::RealScalar inv_length;
444 if(std::abs(w[0]) >= std::abs(w[1]))
446 inv_length = 1.0 / std::sqrt(w[0] * w[0] + w[2] * w[2]);
447 u[0] = -w[2] * inv_length;
449 u[2] = w[0] * inv_length;
451 v[1] = w[2] * u[0] - w[0] * u[2];
456 inv_length = 1.0 / std::sqrt(w[1] * w[1] + w[2] * w[2]);
458 u[1] = w[2] * inv_length;
459 u[2] = -w[1] * inv_length;
460 v[0] = w[1] * u[2] - w[2] * u[1];
467 template <
typename S,
int M,
int N>
468 VectorN<S, M+N> combine(
469 const VectorN<S, M>& v1,
const VectorN<S, N>& v2)
478 template <
typename S>
479 void hat(Matrix3<S>& mat,
const Vector3<S>& vec)
481 mat << 0, -vec[2], vec[1], vec[2], 0, -vec[0], -vec[1], vec[0], 0;
486 void eigen(
const Matrix3<S>& m, Vector3<S>& dout, Matrix3<S>& vout)
489 Eigen::SelfAdjointEigenSolver<Matrix3<S>> eigensolver(m);
490 if (eigensolver.info() != Eigen::Success)
492 std::cerr <<
"[eigen] Failed to compute eigendecomposition.\n";
495 dout = eigensolver.eigenvalues();
496 vout = eigensolver.eigenvectors();
501 void eigen_old(
const Matrix3<S>& m, Vector3<S>& dout, Matrix3<S>& vout)
506 S tresh, theta, tau, t, sm, s, h, g, c;
510 S v[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
513 for(ip = 0; ip < n; ++ip)
515 b[ip] = d[ip] = R(ip, ip);
521 for(i = 0; i < 50; ++i)
524 for(ip = 0; ip < n; ++ip)
525 for(iq = ip + 1; iq < n; ++iq)
526 sm += std::abs(R(ip, iq));
529 vout.col(0) << v[0][0], v[0][1], v[0][2];
530 vout.col(1) << v[1][0], v[1][1], v[1][2];
531 vout.col(2) << v[2][0], v[2][1], v[2][2];
532 dout[0] = d[0]; dout[1] = d[1]; dout[2] = d[2];
536 if(i < 3) tresh = 0.2 * sm / (n * n);
539 for(ip = 0; ip < n; ++ip)
541 for(iq= ip + 1; iq < n; ++iq)
543 g = 100.0 * std::abs(R(ip, iq));
545 std::abs(d[ip]) + g == std::abs(d[ip]) &&
546 std::abs(d[iq]) + g == std::abs(d[iq]))
548 else if(std::abs(R(ip, iq)) > tresh)
551 if(std::abs(h) + g == std::abs(h)) t = (R(ip, iq)) / h;
554 theta = 0.5 * h / (R(ip, iq));
555 t = 1.0 /(std::abs(theta) + std::sqrt(1.0 + theta * theta));
556 if(theta < 0.0) t = -t;
558 c = 1.0 / std::sqrt(1 + t * t);
567 for(j = 0; j < ip; ++j) { g = R(j, ip); h = R(j, iq); R(j, ip) = g - s * (h + g * tau); R(j, iq) = h + s * (g - h * tau); }
568 for(j = ip + 1; j < iq; ++j) { g = R(ip, j); h = R(j, iq); R(ip, j) = g - s * (h + g * tau); R(j, iq) = h + s * (g - h * tau); }
569 for(j = iq + 1; j < n; ++j) { g = R(ip, j); h = R(iq, j); R(ip, j) = g - s * (h + g * tau); R(iq, j) = h + s * (g - h * tau); }
570 for(j = 0; j < n; ++j) { g = v[j][ip]; h = v[j][iq]; v[j][ip] = g - s * (h + g * tau); v[j][iq] = h + s * (g - h * tau); }
575 for(ip = 0; ip < n; ++ip)
583 std::cerr <<
"eigen: too many iterations in Jacobi transform." << std::endl;
589 template <
typename S>
590 void axisFromEigen(
const Matrix3<S>& eigenV,
591 const Vector3<S>& eigenS,
596 if(eigenS[0] > eigenS[1])
607 if(eigenS[2] < eigenS[min])
612 else if(eigenS[2] > eigenS[max])
622 axis.col(0) = eigenV.row(max);
623 axis.col(1) = eigenV.row(mid);
624 axis.col(2).noalias() = axis.col(0).cross(axis.col(1));
628 template <
typename S>
629 void axisFromEigen(
const Matrix3<S>& eigenV,
630 const Vector3<S>& eigenS,
635 if(eigenS[0] > eigenS[1])
646 if(eigenS[2] < eigenS[min])
651 else if(eigenS[2] > eigenS[max])
661 tf.linear().col(0) = eigenV.col(max);
662 tf.linear().col(1) = eigenV.col(mid);
663 tf.linear().col(2).noalias() = tf.linear().col(0).cross(tf.linear().col(1));
667 template <
typename S>
668 void generateCoordinateSystem(Matrix3<S>& axis)
671 assert(axis.col(0).maxCoeff() == 2);
673 if(std::abs(axis(0, 0)) >= std::abs(axis(1, 0)))
681 S inv_length = 1.0 / sqrt(std::pow(axis(0, 0), 2) + std::pow(axis(2, 0), 2));
683 axis(0, 1) = -axis(2, 0) * inv_length;
685 axis(2, 1) = axis(0, 0) * inv_length;
687 axis(0, 2) = axis(1, 0) * axis(2, 1);
688 axis(1, 2) = axis(2, 0) * axis(0, 1) - axis(0, 0) * axis(2, 1);
689 axis(2, 2) = -axis(1, 0) * axis(0, 1);
699 S inv_length = 1.0 / sqrt(std::pow(axis(1, 0), 2) + std::pow(axis(2, 0), 2));
702 axis(1, 1) = axis(2, 0) * inv_length;
703 axis(2, 1) = -axis(1, 0) * inv_length;
705 axis(0, 2) = axis(1, 0) * axis(2, 1) - axis(2, 0) * axis(1, 1);
706 axis(1, 2) = -axis(0, 0) * axis(2, 1);
707 axis(2, 2) = axis(0, 0) * axis(1, 1);
712 template <
typename S>
713 void generateCoordinateSystem(Transform3<S>& tf)
716 assert(tf.linear().col(0).maxCoeff() == 2);
718 if(std::abs(tf.linear()(0, 0)) >= std::abs(tf.linear()(1, 0)))
726 S inv_length = 1.0 / sqrt(std::pow(tf.linear()(0, 0), 2) + std::pow(tf.linear()(2, 0), 2));
728 tf.linear()(0, 1) = -tf.linear()(2, 0) * inv_length;
729 tf.linear()(1, 1) = 0;
730 tf.linear()(2, 1) = tf.linear()(0, 0) * inv_length;
732 tf.linear()(0, 2) = tf.linear()(1, 0) * tf.linear()(2, 1);
733 tf.linear()(1, 2) = tf.linear()(2, 0) * tf.linear()(0, 1) - tf.linear()(0, 0) * tf.linear()(2, 1);
734 tf.linear()(2, 2) = -tf.linear()(1, 0) * tf.linear()(0, 1);
744 S inv_length = 1.0 / sqrt(std::pow(tf.linear()(1, 0), 2) + std::pow(tf.linear()(2, 0), 2));
746 tf.linear()(0, 1) = 0;
747 tf.linear()(1, 1) = tf.linear()(2, 0) * inv_length;
748 tf.linear()(2, 1) = -tf.linear()(1, 0) * inv_length;
750 tf.linear()(0, 2) = tf.linear()(1, 0) * tf.linear()(2, 1) - tf.linear()(2, 0) * tf.linear()(1, 1);
751 tf.linear()(1, 2) = -tf.linear()(0, 0) * tf.linear()(2, 1);
752 tf.linear()(2, 2) = tf.linear()(0, 0) * tf.linear()(1, 1);
757 template <
typename DerivedA,
typename DerivedB,
typename DerivedC,
typename DerivedD>
758 void relativeTransform(
759 const Eigen::MatrixBase<DerivedA>& R1,
const Eigen::MatrixBase<DerivedB>& t1,
760 const Eigen::MatrixBase<DerivedA>& R2,
const Eigen::MatrixBase<DerivedB>& t2,
761 Eigen::MatrixBase<DerivedC>& R, Eigen::MatrixBase<DerivedD>& t)
764 DerivedA::RowsAtCompileTime == 3
765 && DerivedA::ColsAtCompileTime == 3,
766 THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE);
769 DerivedB::RowsAtCompileTime == 3
770 && DerivedB::ColsAtCompileTime == 1,
771 THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE);
774 DerivedC::RowsAtCompileTime == 3
775 && DerivedC::ColsAtCompileTime == 3,
776 THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE);
779 DerivedD::RowsAtCompileTime == 3
780 && DerivedD::ColsAtCompileTime == 1,
781 THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE);
783 R.noalias() = R1.transpose() * R2;
784 t.noalias() = R1.transpose() * (t2 - t1);
788 template <
typename S,
typename DerivedA,
typename DerivedB>
789 void relativeTransform(
790 const Transform3<S>& T1,
791 const Transform3<S>& T2,
792 Eigen::MatrixBase<DerivedA>& R, Eigen::MatrixBase<DerivedB>& t)
795 DerivedA::RowsAtCompileTime == 3
796 && DerivedA::ColsAtCompileTime == 3,
797 THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE);
800 DerivedB::RowsAtCompileTime == 3
801 && DerivedB::ColsAtCompileTime == 1,
802 THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE);
804 R.noalias() = T1.linear().transpose() * T2.linear();
805 t.noalias() = T1.linear().transpose() * (T2.translation() - T1.translation());
809 template <
typename S>
810 void getRadiusAndOriginAndRectangleSize(
814 unsigned int* indices,
816 const Matrix3<S>& axis,
821 bool indirect_index =
true;
822 if(!indices) indirect_index =
false;
824 int size_P = ((ps2) ? 2 : 1) * ((ts) ? 3 : 1) * n;
826 std::vector<Vector3<S>> P(size_P);
832 for(
int i = 0; i < n; ++i)
834 int index = indirect_index ? indices[i] : i;
837 for(
int j = 0; j < 3; ++j)
840 const Vector3<S>& p = ps[point_id];
841 P[P_id][0] = axis.col(0).dot(p);
842 P[P_id][1] = axis.col(1).dot(p);
843 P[P_id][2] = axis.col(2).dot(p);
849 for(
int j = 0; j < 3; ++j)
852 const Vector3<S>& p = ps2[point_id];
853 P[P_id][0] = axis.col(0).dot(p);
854 P[P_id][1] = axis.col(1).dot(p);
855 P[P_id][2] = axis.col(2).dot(p);
863 for(
int i = 0; i < n; ++i)
865 int index = indirect_index ? indices[i] : i;
867 const Vector3<S>& p = ps[index];
868 P[P_id][0] = axis.col(0).dot(p);
869 P[P_id][1] = axis.col(1).dot(p);
870 P[P_id][2] = axis.col(2).dot(p);
875 const Vector3<S>& v = ps2[index];
876 P[P_id][0] = axis.col(0).dot(v);
877 P[P_id][1] = axis.col(1).dot(v);
878 P[P_id][2] = axis.col(2).dot(v);
884 S minx, maxx, miny, maxy, minz, maxz;
888 minz = maxz = P[0][2];
890 for(
int i = 1; i < size_P; ++i)
893 if(z_value < minz) minz = z_value;
894 else if(z_value > maxz) maxz = z_value;
897 r = (S)0.5 * (maxz - minz);
899 cz = (S)0.5 * (maxz + minz);
905 int minindex, maxindex;
906 minindex = maxindex = 0;
908 mintmp = maxtmp = P[0][0];
910 for(
int i = 1; i < size_P; ++i)
918 else if(x_value > maxtmp)
926 dz = P[minindex][2] - cz;
927 minx = P[minindex][0] + std::sqrt(std::max<S>(radsqr - dz * dz, 0));
928 dz = P[maxindex][2] - cz;
929 maxx = P[maxindex][0] - std::sqrt(std::max<S>(radsqr - dz * dz, 0));
934 for(
int i = 0; i < size_P; ++i)
939 x = P[i][0] + std::sqrt(std::max<S>(radsqr - dz * dz, 0));
940 if(x < minx) minx = x;
946 for(
int i = 0; i < size_P; ++i)
951 x = P[i][0] - std::sqrt(std::max<S>(radsqr - dz * dz, 0));
952 if(x > maxx) maxx = x;
960 minindex = maxindex = 0;
961 mintmp = maxtmp = P[0][1];
962 for(
int i = 1; i < size_P; ++i)
970 else if(y_value > maxtmp)
978 dz = P[minindex][2] - cz;
979 miny = P[minindex][1] + std::sqrt(std::max<S>(radsqr - dz * dz, 0));
980 dz = P[maxindex][2] - cz;
981 maxy = P[maxindex][1] - std::sqrt(std::max<S>(radsqr - dz * dz, 0));
985 for(
int i = 0; i < size_P; ++i)
990 y = P[i][1] + std::sqrt(std::max<S>(radsqr - dz * dz, 0));
991 if(y < miny) miny = y;
997 for(
int i = 0; i < size_P; ++i)
1002 y = P[i][1] - std::sqrt(std::max<S>(radsqr - dz * dz, 0));
1003 if(y > maxy) maxy = y;
1010 S a = std::sqrt((S)0.5);
1011 for(
int i = 0; i < size_P; ++i)
1017 dx = P[i][0] - maxx;
1018 dy = P[i][1] - maxy;
1019 u = dx * a + dy * a;
1020 t = (a*u - dx)*(a*u - dx) +
1021 (a*u - dy)*(a*u - dy) +
1022 (cz - P[i][2])*(cz - P[i][2]);
1023 u = u - std::sqrt(std::max<S>(radsqr - t, 0));
1030 else if(P[i][1] < miny)
1032 dx = P[i][0] - maxx;
1033 dy = P[i][1] - miny;
1034 u = dx * a - dy * a;
1035 t = (a*u - dx)*(a*u - dx) +
1036 (-a*u - dy)*(-a*u - dy) +
1037 (cz - P[i][2])*(cz - P[i][2]);
1038 u = u - std::sqrt(std::max<S>(radsqr - t, 0));
1046 else if(P[i][0] < minx)
1050 dx = P[i][0] - minx;
1051 dy = P[i][1] - maxy;
1052 u = dy * a - dx * a;
1053 t = (-a*u - dx)*(-a*u - dx) +
1054 (a*u - dy)*(a*u - dy) +
1055 (cz - P[i][2])*(cz - P[i][2]);
1056 u = u - std::sqrt(std::max<S>(radsqr - t, 0));
1063 else if(P[i][1] < miny)
1065 dx = P[i][0] - minx;
1066 dy = P[i][1] - miny;
1067 u = -dx * a - dy * a;
1068 t = (-a*u - dx)*(-a*u - dx) +
1069 (-a*u - dy)*(-a*u - dy) +
1070 (cz - P[i][2])*(cz - P[i][2]);
1071 u = u - std::sqrt(std::max<S>(radsqr - t, 0));
1081 origin = axis.col(0) * minx + axis.col(1) * miny + axis.col(2) * cz;
1084 if(l[0] < 0) l[0] = 0;
1086 if(l[1] < 0) l[1] = 0;
1091 template <
typename S>
1092 void getRadiusAndOriginAndRectangleSize(
1096 unsigned int* indices,
1102 bool indirect_index =
true;
1103 if(!indices) indirect_index =
false;
1105 int size_P = ((ps2) ? 2 : 1) * ((ts) ? 3 : 1) * n;
1107 std::vector<Vector3<S>> P(size_P);
1113 for(
int i = 0; i < n; ++i)
1115 int index = indirect_index ? indices[i] : i;
1118 for(
int j = 0; j < 3; ++j)
1120 int point_id = t[j];
1121 const Vector3<S>& p = ps[point_id];
1122 P[P_id][0] = tf.linear().col(0).dot(p);
1123 P[P_id][1] = tf.linear().col(1).dot(p);
1124 P[P_id][2] = tf.linear().col(2).dot(p);
1130 for(
int j = 0; j < 3; ++j)
1132 int point_id = t[j];
1133 const Vector3<S>& p = ps2[point_id];
1134 P[P_id][0] = tf.linear().col(0).dot(p);
1135 P[P_id][1] = tf.linear().col(1).dot(p);
1136 P[P_id][2] = tf.linear().col(2).dot(p);
1144 for(
int i = 0; i < n; ++i)
1146 int index = indirect_index ? indices[i] : i;
1148 const Vector3<S>& p = ps[index];
1149 P[P_id][0] = tf.linear().col(0).dot(p);
1150 P[P_id][1] = tf.linear().col(1).dot(p);
1151 P[P_id][2] = tf.linear().col(2).dot(p);
1156 P[P_id][0] = tf.linear().col(0).dot(ps2[index]);
1157 P[P_id][1] = tf.linear().col(1).dot(ps2[index]);
1158 P[P_id][2] = tf.linear().col(2).dot(ps2[index]);
1164 S minx, maxx, miny, maxy, minz, maxz;
1168 minz = maxz = P[0][2];
1170 for(
int i = 1; i < size_P; ++i)
1172 S z_value = P[i][2];
1173 if(z_value < minz) minz = z_value;
1174 else if(z_value > maxz) maxz = z_value;
1177 r = (S)0.5 * (maxz - minz);
1179 cz = (S)0.5 * (maxz + minz);
1185 int minindex, maxindex;
1186 minindex = maxindex = 0;
1188 mintmp = maxtmp = P[0][0];
1190 for(
int i = 1; i < size_P; ++i)
1192 S x_value = P[i][0];
1193 if(x_value < mintmp)
1198 else if(x_value > maxtmp)
1206 dz = P[minindex][2] - cz;
1207 minx = P[minindex][0] + std::sqrt(std::max<S>(radsqr - dz * dz, 0));
1208 dz = P[maxindex][2] - cz;
1209 maxx = P[maxindex][0] - std::sqrt(std::max<S>(radsqr - dz * dz, 0));
1214 for(
int i = 0; i < size_P; ++i)
1219 x = P[i][0] + std::sqrt(std::max<S>(radsqr - dz * dz, 0));
1220 if(x < minx) minx = x;
1226 for(
int i = 0; i < size_P; ++i)
1231 x = P[i][0] - std::sqrt(std::max<S>(radsqr - dz * dz, 0));
1232 if(x > maxx) maxx = x;
1240 minindex = maxindex = 0;
1241 mintmp = maxtmp = P[0][1];
1242 for(
int i = 1; i < size_P; ++i)
1244 S y_value = P[i][1];
1245 if(y_value < mintmp)
1250 else if(y_value > maxtmp)
1258 dz = P[minindex][2] - cz;
1259 miny = P[minindex][1] + std::sqrt(std::max<S>(radsqr - dz * dz, 0));
1260 dz = P[maxindex][2] - cz;
1261 maxy = P[maxindex][1] - std::sqrt(std::max<S>(radsqr - dz * dz, 0));
1265 for(
int i = 0; i < size_P; ++i)
1270 y = P[i][1] + std::sqrt(std::max<S>(radsqr - dz * dz, 0));
1271 if(y < miny) miny = y;
1277 for(
int i = 0; i < size_P; ++i)
1282 y = P[i][1] - std::sqrt(std::max<S>(radsqr - dz * dz, 0));
1283 if(y > maxy) maxy = y;
1290 S a = std::sqrt((S)0.5);
1291 for(
int i = 0; i < size_P; ++i)
1297 dx = P[i][0] - maxx;
1298 dy = P[i][1] - maxy;
1299 u = dx * a + dy * a;
1300 t = (a*u - dx)*(a*u - dx) +
1301 (a*u - dy)*(a*u - dy) +
1302 (cz - P[i][2])*(cz - P[i][2]);
1303 u = u - std::sqrt(std::max<S>(radsqr - t, 0));
1310 else if(P[i][1] < miny)
1312 dx = P[i][0] - maxx;
1313 dy = P[i][1] - miny;
1314 u = dx * a - dy * a;
1315 t = (a*u - dx)*(a*u - dx) +
1316 (-a*u - dy)*(-a*u - dy) +
1317 (cz - P[i][2])*(cz - P[i][2]);
1318 u = u - std::sqrt(std::max<S>(radsqr - t, 0));
1326 else if(P[i][0] < minx)
1330 dx = P[i][0] - minx;
1331 dy = P[i][1] - maxy;
1332 u = dy * a - dx * a;
1333 t = (-a*u - dx)*(-a*u - dx) +
1334 (a*u - dy)*(a*u - dy) +
1335 (cz - P[i][2])*(cz - P[i][2]);
1336 u = u - std::sqrt(std::max<S>(radsqr - t, 0));
1343 else if(P[i][1] < miny)
1345 dx = P[i][0] - minx;
1346 dy = P[i][1] - miny;
1347 u = -dx * a - dy * a;
1348 t = (-a*u - dx)*(-a*u - dx) +
1349 (-a*u - dy)*(-a*u - dy) +
1350 (cz - P[i][2])*(cz - P[i][2]);
1351 u = u - std::sqrt(std::max<S>(radsqr - t, 0));
1361 tf.translation().noalias() = tf.linear().col(0) * minx;
1362 tf.translation().noalias() += tf.linear().col(1) * miny;
1363 tf.translation().noalias() += tf.linear().col(2) * cz;
1366 if(l[0] < 0) l[0] = 0;
1368 if(l[1] < 0) l[1] = 0;
1372 template <
typename S>
1373 void circumCircleComputation(
1374 const Vector3<S>& a,
1375 const Vector3<S>& b,
1376 const Vector3<S>& c,
1380 Vector3<S> e1 = a - c;
1381 Vector3<S> e2 = b - c;
1382 S e1_len2 = e1.squaredNorm();
1383 S e2_len2 = e2.squaredNorm();
1384 Vector3<S> e3 = e1.cross(e2);
1385 S e3_len2 = e3.squaredNorm();
1386 radius = e1_len2 * e2_len2 * (e1 - e2).squaredNorm() / e3_len2;
1387 radius = std::sqrt(radius) * 0.5;
1390 center.noalias() += (e2 * e1_len2 - e1 * e2_len2).cross(e3) * (0.5 * 1 / e3_len2);
1396 template <
typename S>
1401 unsigned int* indices,
1403 const Vector3<S>& query)
1406 return detail::maximumDistance_mesh(ps, ps2, ts, indices, n, query);
1408 return detail::maximumDistance_pointcloud(ps, ps2, indices, n, query);
1412 template <
typename S>
1413 void getExtentAndCenter(
1417 unsigned int* indices,
1419 const Matrix3<S>& axis,
1424 detail::getExtentAndCenter_mesh(ps, ps2, ts, indices, n, axis, center, extent);
1426 detail::getExtentAndCenter_pointcloud(ps, ps2, indices, n, axis, center, extent);
1430 template <
typename S>
1431 void getCovariance(Vector3<S>* ps,
1434 unsigned int* indices,
1435 int n, Matrix3<S>& M)
1437 Vector3<S> S1 = Vector3<S>::Zero();
1438 Vector3<S> S2[3] = {
1439 Vector3<S>::Zero(), Vector3<S>::Zero(), Vector3<S>::Zero()
1444 for(
int i = 0; i < n; ++i)
1446 const Triangle& t = (indices) ? ts[indices[i]] : ts[i];
1448 const Vector3<S>& p1 = ps[t[0]];
1449 const Vector3<S>& p2 = ps[t[1]];
1450 const Vector3<S>& p3 = ps[t[2]];
1452 S1 += (p1 + p2 + p3).eval();
1454 S2[0][0] += (p1[0] * p1[0] + p2[0] * p2[0] + p3[0] * p3[0]);
1455 S2[1][1] += (p1[1] * p1[1] + p2[1] * p2[1] + p3[1] * p3[1]);
1456 S2[2][2] += (p1[2] * p1[2] + p2[2] * p2[2] + p3[2] * p3[2]);
1457 S2[0][1] += (p1[0] * p1[1] + p2[0] * p2[1] + p3[0] * p3[1]);
1458 S2[0][2] += (p1[0] * p1[2] + p2[0] * p2[2] + p3[0] * p3[2]);
1459 S2[1][2] += (p1[1] * p1[2] + p2[1] * p2[2] + p3[1] * p3[2]);
1463 const Vector3<S>& p1 = ps2[t[0]];
1464 const Vector3<S>& p2 = ps2[t[1]];
1465 const Vector3<S>& p3 = ps2[t[2]];
1467 S1 += (p1 + p2 + p3).eval();
1469 S2[0][0] += (p1[0] * p1[0] + p2[0] * p2[0] + p3[0] * p3[0]);
1470 S2[1][1] += (p1[1] * p1[1] + p2[1] * p2[1] + p3[1] * p3[1]);
1471 S2[2][2] += (p1[2] * p1[2] + p2[2] * p2[2] + p3[2] * p3[2]);
1472 S2[0][1] += (p1[0] * p1[1] + p2[0] * p2[1] + p3[0] * p3[1]);
1473 S2[0][2] += (p1[0] * p1[2] + p2[0] * p2[2] + p3[0] * p3[2]);
1474 S2[1][2] += (p1[1] * p1[2] + p2[1] * p2[2] + p3[1] * p3[2]);
1480 for(
int i = 0; i < n; ++i)
1482 const Vector3<S>& p = (indices) ? ps[indices[i]] : ps[i];
1484 S2[0][0] += (p[0] * p[0]);
1485 S2[1][1] += (p[1] * p[1]);
1486 S2[2][2] += (p[2] * p[2]);
1487 S2[0][1] += (p[0] * p[1]);
1488 S2[0][2] += (p[0] * p[2]);
1489 S2[1][2] += (p[1] * p[2]);
1493 const Vector3<S>& p = (indices) ? ps2[indices[i]] : ps2[i];
1495 S2[0][0] += (p[0] * p[0]);
1496 S2[1][1] += (p[1] * p[1]);
1497 S2[2][2] += (p[2] * p[2]);
1498 S2[0][1] += (p[0] * p[1]);
1499 S2[0][2] += (p[0] * p[2]);
1500 S2[1][2] += (p[1] * p[2]);
1505 int n_points = ((ps2) ? 2 : 1) * ((ts) ? 3 : 1) * n;
1507 M(0, 0) = S2[0][0] - S1[0]*S1[0] / n_points;
1508 M(1, 1) = S2[1][1] - S1[1]*S1[1] / n_points;
1509 M(2, 2) = S2[2][2] - S1[2]*S1[2] / n_points;
1510 M(0, 1) = S2[0][1] - S1[0]*S1[1] / n_points;
1511 M(1, 2) = S2[1][2] - S1[1]*S1[2] / n_points;
1512 M(0, 2) = S2[0][2] - S1[0]*S1[2] / n_points;
Main namespace.
Definition: broadphase_bruteforce-inl.h:45
Triangle with 3 indices for points.
Definition: triangle.h:47