38 #ifndef FCL_MATH_BV_UTILITY_INL_H 39 #define FCL_MATH_BV_UTILITY_INL_H 41 #include "fcl/math/bv/utility.h" 43 #include "fcl/math/bv/AABB.h" 44 #include "fcl/math/bv/kDOP.h" 45 #include "fcl/math/bv/kIOS.h" 46 #include "fcl/math/bv/OBB.h" 47 #include "fcl/math/bv/OBBRSS.h" 48 #include "fcl/math/bv/RSS.h" 58 namespace OBB_fit_functions {
63 void fit1(Vector3<S>* ps, OBB<S>& bv)
66 bv.axis.setIdentity();
72 void fit2(Vector3<S>* ps, OBB<S>& bv)
74 const Vector3<S>& p1 = ps[0];
75 const Vector3<S>& p2 = ps[1];
76 Vector3<S> p1p2 = p1 - p2;
77 S len_p1p2 = p1p2.norm();
80 bv.axis.col(0) = p1p2;
81 generateCoordinateSystem(bv.axis);
83 bv.extent << len_p1p2 * 0.5, 0, 0;
84 bv.To.noalias() = 0.5 * (p1 + p2);
89 void fit3(Vector3<S>* ps, OBB<S>& bv)
91 const Vector3<S>& p1 = ps[0];
92 const Vector3<S>& p2 = ps[1];
93 const Vector3<S>& p3 = ps[2];
99 len[0] = e[0].squaredNorm();
100 len[1] = e[1].squaredNorm();
101 len[2] = e[2].squaredNorm();
104 if(len[1] > len[0]) imax = 1;
105 if(len[2] > len[imax]) imax = 2;
107 bv.axis.col(2).noalias() = e[0].cross(e[1]);
108 bv.axis.col(2).normalize();
109 bv.axis.col(0) = e[imax];
110 bv.axis.col(0).normalize();
111 bv.axis.col(1).noalias() = bv.axis.col(2).cross(bv.axis.col(0));
113 getExtentAndCenter<S>(ps,
nullptr,
nullptr,
nullptr, 3, bv.axis, bv.To, bv.extent);
117 template <
typename S>
118 void fit6(Vector3<S>* ps, OBB<S>& bv)
127 template <
typename S>
128 void fitn(Vector3<S>* ps,
int n, OBB<S>& bv)
132 Vector3<S> s = Vector3<S>::Zero();
134 getCovariance<S>(ps,
nullptr,
nullptr,
nullptr, n, M);
136 axisFromEigen(E, s, bv.axis);
139 getExtentAndCenter<S>(ps,
nullptr,
nullptr,
nullptr, n, bv.axis, bv.To, bv.extent);
144 void fit1(Vector3<double>* ps, OBB<double>& bv);
148 void fit2(Vector3<double>* ps, OBB<double>& bv);
152 void fit3(Vector3<double>* ps, OBB<double>& bv);
156 void fit6(Vector3<double>* ps, OBB<double>& bv);
160 void fitn(Vector3<double>* ps,
int n, OBB<double>& bv);
167 namespace RSS_fit_functions {
171 template <
typename S>
172 void fit1(Vector3<S>* ps, RSS<S>& bv)
175 bv.axis.setIdentity();
182 template <
typename S>
183 void fit2(Vector3<S>* ps, RSS<S>& bv)
185 const Vector3<S>& p1 = ps[0];
186 const Vector3<S>& p2 = ps[1];
187 Vector3<S> p1p2 = p1 - p2;
188 S len_p1p2 = p1p2.norm();
191 bv.axis.col(0) = p1p2;
192 generateCoordinateSystem(bv.axis);
201 template <
typename S>
202 void fit3(Vector3<S>* ps, RSS<S>& bv)
204 const Vector3<S>& p1 = ps[0];
205 const Vector3<S>& p2 = ps[1];
206 const Vector3<S>& p3 = ps[2];
212 len[0] = e[0].squaredNorm();
213 len[1] = e[1].squaredNorm();
214 len[2] = e[2].squaredNorm();
217 if(len[1] > len[0]) imax = 1;
218 if(len[2] > len[imax]) imax = 2;
220 bv.axis.col(2).noalias() = e[0].cross(e[1]).normalized();
221 bv.axis.col(0).noalias() = e[imax].normalized();
222 bv.axis.col(1).noalias() = bv.axis.col(2).cross(bv.axis.col(0));
224 getRadiusAndOriginAndRectangleSize<S>(ps,
nullptr,
nullptr,
nullptr, 3, bv.axis, bv.To, bv.l, bv.r);
228 template <
typename S>
229 void fit6(Vector3<S>* ps, RSS<S>& bv)
238 template <
typename S>
239 void fitn(Vector3<S>* ps,
int n, RSS<S>& bv)
243 Vector3<S> s = Vector3<S>::Zero();
245 getCovariance<S>(ps,
nullptr,
nullptr,
nullptr, n, M);
247 axisFromEigen(E, s, bv.axis);
250 getRadiusAndOriginAndRectangleSize<S>(ps,
nullptr,
nullptr,
nullptr, n, bv.axis, bv.To, bv.l, bv.r);
255 void fit1(Vector3<double>* ps, RSS<double>& bv);
259 void fit2(Vector3<double>* ps, RSS<double>& bv);
263 void fit3(Vector3<double>* ps, RSS<double>& bv);
267 void fit6(Vector3<double>* ps, RSS<double>& bv);
271 void fitn(Vector3<double>* ps,
int n, RSS<double>& bv);
278 namespace kIOS_fit_functions {
282 template <
typename S>
283 void fit1(Vector3<S>* ps, kIOS<S>& bv)
286 bv.spheres[0].o = ps[0];
289 bv.obb.axis.setIdentity();
290 bv.obb.extent.setZero();
295 template <
typename S>
296 void fit2(Vector3<S>* ps, kIOS<S>& bv)
300 const Vector3<S>& p1 = ps[0];
301 const Vector3<S>& p2 = ps[1];
302 Vector3<S> p1p2 = p1 - p2;
303 S len_p1p2 = p1p2.norm();
306 bv.obb.axis.col(0) = p1p2;
307 generateCoordinateSystem(bv.obb.axis);
309 S r0 = len_p1p2 * 0.5;
310 bv.obb.extent << r0, 0, 0;
311 bv.obb.To.noalias() = (p1 + p2) * 0.5;
313 bv.spheres[0].o = bv.obb.To;
314 bv.spheres[0].r = r0;
316 S r1 = r0 * kIOS<S>::invSinA();
317 S r1cosA = r1 * kIOS<S>::cosA();
318 bv.spheres[1].r = r1;
319 bv.spheres[2].r = r1;
320 Vector3<S> delta = bv.obb.axis.col(1) * r1cosA;
321 bv.spheres[1].o = bv.spheres[0].o - delta;
322 bv.spheres[2].o = bv.spheres[0].o + delta;
324 bv.spheres[3].r = r1;
325 bv.spheres[4].r = r1;
326 delta.noalias() = bv.obb.axis.col(2) * r1cosA;
327 bv.spheres[3].o = bv.spheres[0].o - delta;
328 bv.spheres[4].o = bv.spheres[0].o + delta;
332 template <
typename S>
333 void fit3(Vector3<S>* ps, kIOS<S>& bv)
337 const Vector3<S>& p1 = ps[0];
338 const Vector3<S>& p2 = ps[1];
339 const Vector3<S>& p3 = ps[2];
345 len[0] = e[0].squaredNorm();
346 len[1] = e[1].squaredNorm();
347 len[2] = e[2].squaredNorm();
350 if(len[1] > len[0]) imax = 1;
351 if(len[2] > len[imax]) imax = 2;
353 bv.obb.axis.col(2).noalias() = e[0].cross(e[1]).normalized();
354 bv.obb.axis.col(0) = e[imax].normalized();
355 bv.obb.axis.col(1).noalias() = bv.obb.axis.col(2).cross(bv.obb.axis.col(0));
357 getExtentAndCenter<S>(ps,
nullptr,
nullptr,
nullptr, 3, bv.obb.axis, bv.obb.To, bv.obb.extent);
362 circumCircleComputation(p1, p2, p3, center, r0);
364 bv.spheres[0].o = center;
365 bv.spheres[0].r = r0;
367 S r1 = r0 * kIOS<S>::invSinA();
368 Vector3<S> delta = bv.obb.axis.col(2) * (r1 * kIOS<S>::cosA());
370 bv.spheres[1].r = r1;
371 bv.spheres[1].o = center - delta;
372 bv.spheres[2].r = r1;
373 bv.spheres[2].o = center + delta;
377 template <
typename S>
378 void fitn(Vector3<S>* ps,
int n, kIOS<S>& bv)
382 Vector3<S> s = Vector3<S>::Zero();
384 getCovariance<S>(ps,
nullptr,
nullptr,
nullptr, n, M);
386 axisFromEigen(E, s, bv.obb.axis);
388 getExtentAndCenter<S>(ps,
nullptr,
nullptr,
nullptr, n, bv.obb.axis, bv.obb.To, bv.obb.extent);
391 const Vector3<S>& center = bv.obb.To;
392 const Vector3<S>& extent = bv.obb.extent;
393 S r0 = maximumDistance<S>(ps,
nullptr,
nullptr,
nullptr, n, center);
396 if(extent[0] > kIOS<S>::ratio() * extent[2])
398 if(extent[0] > kIOS<S>::ratio() * extent[1]) bv.num_spheres = 5;
399 else bv.num_spheres = 3;
401 else bv.num_spheres = 1;
404 bv.spheres[0].o = center;
405 bv.spheres[0].r = r0;
407 if(bv.num_spheres >= 3)
409 S r10 = sqrt(r0 * r0 - extent[2] * extent[2]) * kIOS<S>::invSinA();
410 Vector3<S> delta = bv.obb.axis.col(2) * (r10 * kIOS<S>::cosA() - extent[2]);
411 bv.spheres[1].o = center - delta;
412 bv.spheres[2].o = center + delta;
415 r11 = maximumDistance<S>(ps,
nullptr,
nullptr,
nullptr, n, bv.spheres[1].o);
416 r12 = maximumDistance<S>(ps,
nullptr,
nullptr,
nullptr, n, bv.spheres[2].o);
417 bv.spheres[1].o.noalias() += bv.obb.axis.col(2) * (-r10 + r11);
418 bv.spheres[2].o.noalias() += bv.obb.axis.col(2) * (r10 - r12);
420 bv.spheres[1].r = r10;
421 bv.spheres[2].r = r10;
424 if(bv.num_spheres >= 5)
426 S r10 = bv.spheres[1].r;
427 Vector3<S> delta = bv.obb.axis.col(1) * (sqrt(r10 * r10 - extent[0] * extent[0] - extent[2] * extent[2]) - extent[1]);
428 bv.spheres[3].o = bv.spheres[0].o - delta;
429 bv.spheres[4].o = bv.spheres[0].o + delta;
432 r21 = maximumDistance<S>(ps,
nullptr,
nullptr,
nullptr, n, bv.spheres[3].o);
433 r22 = maximumDistance<S>(ps,
nullptr,
nullptr,
nullptr, n, bv.spheres[4].o);
435 bv.spheres[3].o.noalias() += bv.obb.axis.col(1) * (-r10 + r21);
436 bv.spheres[4].o.noalias() += bv.obb.axis.col(1) * (r10 - r22);
438 bv.spheres[3].r = r10;
439 bv.spheres[4].r = r10;
445 void fit1(Vector3<double>* ps, kIOS<double>& bv);
449 void fit2(Vector3<double>* ps, kIOS<double>& bv);
453 void fit3(Vector3<double>* ps, kIOS<double>& bv);
457 void fitn(Vector3<double>* ps,
int n, kIOS<double>& bv);
464 namespace OBBRSS_fit_functions {
468 template <
typename S>
469 void fit1(Vector3<S>* ps, OBBRSS<S>& bv)
471 OBB_fit_functions::fit1(ps, bv.obb);
472 RSS_fit_functions::fit1(ps, bv.rss);
476 template <
typename S>
477 void fit2(Vector3<S>* ps, OBBRSS<S>& bv)
479 OBB_fit_functions::fit2(ps, bv.obb);
480 RSS_fit_functions::fit2(ps, bv.rss);
484 template <
typename S>
485 void fit3(Vector3<S>* ps, OBBRSS<S>& bv)
487 OBB_fit_functions::fit3(ps, bv.obb);
488 RSS_fit_functions::fit3(ps, bv.rss);
492 template <
typename S>
493 void fitn(Vector3<S>* ps,
int n, OBBRSS<S>& bv)
495 OBB_fit_functions::fitn(ps, n, bv.obb);
496 RSS_fit_functions::fitn(ps, n, bv.rss);
501 void fit1(Vector3<double>* ps, OBBRSS<double>& bv);
505 void fit2(Vector3<double>* ps, OBBRSS<double>& bv);
509 void fit3(Vector3<double>* ps, OBBRSS<double>& bv);
513 void fitn(Vector3<double>* ps,
int n, OBBRSS<double>& bv);
520 template <
typename S,
typename BV>
523 static void fit(Vector3<S>* ps,
int n, BV& bv)
525 for(
int i = 0; i < n; ++i)
531 template <
typename S>
534 static void fit(Vector3<S>* ps,
int n,
OBB<S>& bv)
539 OBB_fit_functions::fit1(ps, bv);
542 OBB_fit_functions::fit2(ps, bv);
545 OBB_fit_functions::fit3(ps, bv);
548 OBB_fit_functions::fit6(ps, bv);
551 OBB_fit_functions::fitn(ps, n, bv);
557 template <
typename S>
560 static void fit(Vector3<S>* ps,
int n,
RSS<S>& bv)
565 RSS_fit_functions::fit1(ps, bv);
568 RSS_fit_functions::fit2(ps, bv);
571 RSS_fit_functions::fit3(ps, bv);
574 RSS_fit_functions::fitn(ps, n, bv);
580 template <
typename S>
583 static void fit(Vector3<S>* ps,
int n,
kIOS<S>& bv)
588 kIOS_fit_functions::fit1(ps, bv);
591 kIOS_fit_functions::fit2(ps, bv);
594 kIOS_fit_functions::fit3(ps, bv);
597 kIOS_fit_functions::fitn(ps, n, bv);
603 template <
typename S>
611 OBBRSS_fit_functions::fit1(ps, bv);
614 OBBRSS_fit_functions::fit2(ps, bv);
617 OBBRSS_fit_functions::fit3(ps, bv);
620 OBBRSS_fit_functions::fitn(ps, n, bv);
646 template <
typename BV>
647 void fit(Vector3<typename BV::S>* ps,
int n, BV& bv)
658 template <
typename S,
typename BV1,
typename BV2>
662 static void run(
const BV1& bv1,
const Transform3<S>& tf1, BV2& bv2)
670 template <
typename S>
674 static void run(
const AABB<S>& bv1,
const Transform3<S>& tf1,
AABB<S>& bv2)
676 const Vector3<S> center = bv1.
center();
677 S r = (bv1.
max_ - bv1.
min_).norm() * 0.5;
678 Vector3<S> center2 = tf1 * center;
679 Vector3<S> delta(r, r, r);
680 bv2.
min_ = center2 - delta;
681 bv2.
max_ = center2 + delta;
686 template <
typename S>
690 static void run(
const AABB<S>& bv1,
const Transform3<S>& tf1,
OBB<S>& bv2)
728 bv2.
To.noalias() = tf1 * bv1.
center();
730 bv2.
axis = tf1.linear();
735 template <
typename S>
739 static void run(
const OBB<S>& bv1,
const Transform3<S>& tf1,
OBB<S>& bv2)
742 bv2.
To.noalias() = tf1 * bv1.
To;
743 bv2.
axis.noalias() = tf1.linear() * bv1.
axis;
748 template <
typename S>
752 static void run(
const OBBRSS<S>& bv1,
const Transform3<S>& tf1,
OBB<S>& bv2)
759 template <
typename S>
763 static void run(
const RSS<S>& bv1,
const Transform3<S>& tf1,
OBB<S>& bv2)
765 bv2.
extent << bv1.
l[0] * 0.5 + bv1.
r, bv1.
l[1] * 0.5 + bv1.
r, bv1.
r;
766 bv2.
To.noalias() = tf1 * bv1.
To;
767 bv2.
axis.noalias() = tf1.linear() * bv1.
axis;
772 template <
typename S,
typename BV1>
776 static void run(
const BV1& bv1,
const Transform3<S>& tf1,
AABB<S>& bv2)
778 const Vector3<S> center = bv1.
center();
779 S r = Vector3<S>(bv1.width(), bv1.height(), bv1.depth()).norm() * 0.5;
780 Vector3<S> delta(r, r, r);
781 Vector3<S> center2 = tf1 * center;
782 bv2.
min_ = center2 - delta;
783 bv2.
max_ = center2 + delta;
788 template <
typename S,
typename BV1>
792 static void run(
const BV1& bv1,
const Transform3<S>& tf1,
OBB<S>& bv2)
801 template <
typename S>
805 static void run(
const OBB<S>& bv1,
const Transform3<S>& tf1,
RSS<S>& bv2)
807 bv2.
To.noalias() = tf1 * bv1.
To;
808 bv2.
axis.noalias() = tf1.linear() * bv1.
axis;
811 bv2.
l[0] = 2 * (bv1.
extent[0] - bv2.
r);
812 bv2.
l[1] = 2 * (bv1.
extent[1] - bv2.
r);
817 template <
typename S>
821 static void run(
const RSS<S>& bv1,
const Transform3<S>& tf1,
RSS<S>& bv2)
823 bv2.
To.noalias() = tf1 * bv1.
To;
824 bv2.
axis.noalias() = tf1.linear() * bv1.
axis;
833 template <
typename S>
837 static void run(
const OBBRSS<S>& bv1,
const Transform3<S>& tf1,
RSS<S>& bv2)
844 template <
typename S>
850 bv2.
To.noalias() = tf1 * bv1.
center();
854 std::size_t
id[3] = {0, 1, 2};
856 for(std::size_t i = 1; i < 3; ++i)
858 for(std::size_t j = i; j > 0; --j)
868 std::size_t tmp =
id[j];
876 Vector3<S> extent = (bv1.
max_ - bv1.
min_) * 0.5;
877 bv2.
r = extent[
id[2]];
878 bv2.
l[0] = (extent[
id[0]] - bv2.
r) * 2;
879 bv2.
l[1] = (extent[
id[1]] - bv2.
r) * 2;
881 const Matrix3<S>& R = tf1.linear();
882 bool left_hand = (
id[0] == (
id[1] + 1) % 3);
884 bv2.
axis.col(0) = -R.col(
id[0]);
886 bv2.
axis.col(0) = R.col(
id[0]);
887 bv2.
axis.col(1) = R.col(
id[1]);
888 bv2.
axis.col(2) = R.col(
id[2]);
933 template <
typename BV1,
typename BV2>
935 const BV1& bv1,
const Transform3<typename BV1::S>& tf1, BV2& bv2)
937 static_assert(std::is_same<typename BV1::S, typename BV2::S>::value,
938 "The scalar type of BV1 and BV2 should be the same");
void convertBV(const BV1 &bv1, const Transform3< typename BV1::S > &tf1, BV2 &bv2)
Convert a bounding volume of type BV1 in configuration tf1 to bounding volume of type BV2 in identity...
Definition: utility-inl.h:934
Main namespace.
Definition: broadphase_bruteforce-inl.h:45
S height() const
Height of the AABB.
Definition: AABB-inl.h:195
A class describing the AABB collision structure, which is a box in 3D space determined by two diagona...
Definition: AABB.h:49
Definition: utility-inl.h:521
Vector3< S > max_
The max point in the AABB.
Definition: AABB.h:59
Vector3< S > center() const
Center of the AABB.
Definition: AABB-inl.h:230
void fit(Vector3< typename BV::S > *ps, int n, BV &bv)
Compute a bounding volume that fits a set of n points.
Definition: utility-inl.h:647
Vector3< S > min_
The min point in the AABB.
Definition: AABB.h:56
Convert a bounding volume of type BV1 in configuration tf1 to a bounding volume of type BV2 in I conf...
Definition: utility-inl.h:659
S depth() const
Depth of the AABB.
Definition: AABB-inl.h:202
Vector3< S > extent
Half dimensions of OBB.
Definition: OBB.h:68
Matrix3< S > axis
Orientation of OBB. The axes of the rotation matrix are the principle directions of the box...
Definition: OBB.h:62
Vector3< S > To
Center of OBB.
Definition: OBB.h:65
S width() const
Width of the AABB.
Definition: AABB-inl.h:188
A class describing the kIOS collision structure, which is a set of spheres.
Definition: kIOS.h:48