38 #ifndef FCL_NARROWPHASE_DETAIL_HALFSPACE_INL_H 39 #define FCL_NARROWPHASE_DETAIL_HALFSPACE_INL_H 41 #include "fcl/narrowphase/detail/primitive_shape_algorithm/halfspace.h" 51 bool sphereHalfspaceIntersect(
52 const Sphere<double>& s1,
const Transform3<double>& tf1,
53 const Halfspace<double>& s2,
const Transform3<double>& tf2,
54 std::vector<ContactPoint<double>>* contacts);
58 bool ellipsoidHalfspaceIntersect(
59 const Ellipsoid<double>& s1,
const Transform3<double>& tf1,
60 const Halfspace<double>& s2,
const Transform3<double>& tf2,
61 std::vector<ContactPoint<double>>* contacts);
65 bool boxHalfspaceIntersect(
66 const Box<double>& s1,
const Transform3<double>& tf1,
67 const Halfspace<double>& s2,
const Transform3<double>& tf2);
71 bool boxHalfspaceIntersect(
72 const Box<double>& s1,
const Transform3<double>& tf1,
73 const Halfspace<double>& s2,
const Transform3<double>& tf2,
74 std::vector<ContactPoint<double>>* contacts);
78 bool capsuleHalfspaceIntersect(
79 const Capsule<double>& s1,
const Transform3<double>& tf1,
80 const Halfspace<double>& s2,
const Transform3<double>& tf2,
81 std::vector<ContactPoint<double>>* contacts);
85 bool cylinderHalfspaceIntersect(
86 const Cylinder<double>& s1,
const Transform3<double>& tf1,
87 const Halfspace<double>& s2,
const Transform3<double>& tf2,
88 std::vector<ContactPoint<double>>* contacts);
92 bool coneHalfspaceIntersect(
93 const Cone<double>& s1,
const Transform3<double>& tf1,
94 const Halfspace<double>& s2,
const Transform3<double>& tf2,
95 std::vector<ContactPoint<double>>* contacts);
99 bool convexHalfspaceIntersect(
100 const Convex<double>& s1,
const Transform3<double>& tf1,
101 const Halfspace<double>& s2,
const Transform3<double>& tf2,
102 Vector3<double>* contact_points,
double* penetration_depth, Vector3<double>* normal);
106 bool halfspaceTriangleIntersect(
107 const Halfspace<double>& s1,
const Transform3<double>& tf1,
108 const Vector3<double>& P1,
const Vector3<double>& P2,
const Vector3<double>& P3,
const Transform3<double>& tf2,
109 Vector3<double>* contact_points,
double* penetration_depth, Vector3<double>* normal);
113 bool planeHalfspaceIntersect(
114 const Plane<double>& s1,
const Transform3<double>& tf1,
115 const Halfspace<double>& s2,
const Transform3<double>& tf2,
117 Vector3<double>& p, Vector3<double>& d,
118 double& penetration_depth,
123 bool halfspacePlaneIntersect(
124 const Halfspace<double>& s1,
const Transform3<double>& tf1,
125 const Plane<double>& s2,
const Transform3<double>& tf2,
126 Plane<double>& pl, Vector3<double>& p, Vector3<double>& d,
127 double& penetration_depth,
132 bool halfspaceIntersect(
133 const Halfspace<double>& s1,
const Transform3<double>& tf1,
134 const Halfspace<double>& s2,
const Transform3<double>& tf2,
135 Vector3<double>& p, Vector3<double>& d,
136 Halfspace<double>& s,
137 double& penetration_depth,
141 template <
typename S>
142 S halfspaceIntersectTolerance()
148 template <
typename S>
149 bool sphereHalfspaceIntersect(
const Sphere<S>& s1,
const Transform3<S>& tf1,
150 const Halfspace<S>& s2,
const Transform3<S>& tf2,
151 std::vector<ContactPoint<S>>* contacts)
153 const Halfspace<S> new_s2 = transform(s2, tf2);
154 const Vector3<S>& center = tf1.translation();
155 const S depth = s1.radius - new_s2.signedDistance(center);
161 const Vector3<S> normal = -new_s2.n;
162 const Vector3<S>
point = center - new_s2.n * s1.radius + new_s2.n * (depth * 0.5);
163 const S penetration_depth = depth;
165 contacts->emplace_back(normal, point, penetration_depth);
177 template <
typename S>
178 bool ellipsoidHalfspaceIntersect(
const Ellipsoid<S>& s1,
const Transform3<S>& tf1,
179 const Halfspace<S>& s2,
const Transform3<S>& tf2,
180 std::vector<ContactPoint<S>>* contacts)
185 const Halfspace<S>& new_s2 = transform(s2, tf1.inverse(Eigen::Isometry) * tf2);
189 const Vector3<S> normal2(std::pow(new_s2.n[0], 2), std::pow(new_s2.n[1], 2), std::pow(new_s2.n[2], 2));
190 const Vector3<S> radii2(std::pow(s1.radii[0], 2), std::pow(s1.radii[1], 2), std::pow(s1.radii[2], 2));
191 const S center_to_contact_plane = std::sqrt(normal2.dot(radii2));
194 const S depth = center_to_contact_plane + new_s2.d;
201 const Vector3<S> normal = tf1.linear() * -new_s2.n;
202 const Vector3<S> support_vector = (1.0/center_to_contact_plane) * Vector3<S>(radii2[0]*new_s2.n[0], radii2[1]*new_s2.n[1], radii2[2]*new_s2.n[2]);
203 const Vector3<S> point_in_halfspace_coords = support_vector * (0.5 * depth / new_s2.n.dot(support_vector) - 1.0);
204 const Vector3<S>
point = tf1 * point_in_halfspace_coords;
205 const S penetration_depth = depth;
207 contacts->emplace_back(normal, point, penetration_depth);
219 template <
typename S>
220 bool boxHalfspaceIntersect(
const Box<S>& s1,
const Transform3<S>& tf1,
221 const Halfspace<S>& s2,
const Transform3<S>& tf2)
223 Halfspace<S> new_s2 = transform(s2, tf2);
225 const Matrix3<S>& R = tf1.linear();
226 const Vector3<S>& T = tf1.translation();
228 Vector3<S> Q = R.transpose() * new_s2.n;
229 Vector3<S> A(Q[0] * s1.side[0], Q[1] * s1.side[1], Q[2] * s1.side[2]);
230 Vector3<S> B = A.cwiseAbs();
232 S depth = 0.5 * (B[0] + B[1] + B[2]) - new_s2.signedDistance(T);
237 template <
typename S>
238 bool boxHalfspaceIntersect(
const Box<S>& s1,
const Transform3<S>& tf1,
239 const Halfspace<S>& s2,
const Transform3<S>& tf2,
240 std::vector<ContactPoint<S>>* contacts)
244 return boxHalfspaceIntersect(s1, tf1, s2, tf2);
248 const Halfspace<S> new_s2 = transform(s2, tf2);
250 const Matrix3<S>& R = tf1.linear();
251 const Vector3<S>& T = tf1.translation();
253 Vector3<S> Q = R.transpose() * new_s2.n;
254 Vector3<S> A(Q[0] * s1.side[0], Q[1] * s1.side[1], Q[2] * s1.side[2]);
255 Vector3<S> B = A.cwiseAbs();
257 S depth = 0.5 * (B[0] + B[1] + B[2]) - new_s2.signedDistance(T);
258 if(depth < 0)
return false;
269 if(std::abs(Q[0] - 1) < halfspaceIntersectTolerance<S>() || std::abs(Q[0] + 1) < halfspaceIntersectTolerance<S>())
271 sign = (A[0] > 0) ? -1 : 1;
272 p += axis[0] * (0.5 * s1.side[0] * sign);
274 else if(std::abs(Q[1] - 1) < halfspaceIntersectTolerance<S>() || std::abs(Q[1] + 1) < halfspaceIntersectTolerance<S>())
276 sign = (A[1] > 0) ? -1 : 1;
277 p += axis[1] * (0.5 * s1.side[1] * sign);
279 else if(std::abs(Q[2] - 1) < halfspaceIntersectTolerance<S>() || std::abs(Q[2] + 1) < halfspaceIntersectTolerance<S>())
281 sign = (A[2] > 0) ? -1 : 1;
282 p += axis[2] * (0.5 * s1.side[2] * sign);
286 for(std::size_t i = 0; i < 3; ++i)
288 sign = (A[i] > 0) ? -1 : 1;
289 p += axis[i] * (0.5 * s1.side[i] * sign);
296 const Vector3<S> normal = -new_s2.n;
297 const Vector3<S>
point = p + new_s2.n * (depth * 0.5);
298 const S penetration_depth = depth;
300 contacts->emplace_back(normal, point, penetration_depth);
308 template <
typename S>
309 bool capsuleHalfspaceIntersect(
const Capsule<S>& s1,
const Transform3<S>& tf1,
310 const Halfspace<S>& s2,
const Transform3<S>& tf2,
311 std::vector<ContactPoint<S>>* contacts)
313 Halfspace<S> new_s2 = transform(s2, tf2);
315 const Matrix3<S>& R = tf1.linear();
316 const Vector3<S>& T = tf1.translation();
318 Vector3<S> dir_z = R.col(2);
320 S cosa = dir_z.dot(new_s2.n);
321 if(std::abs(cosa) < halfspaceIntersectTolerance<S>())
323 S signed_dist = new_s2.signedDistance(T);
324 S depth = s1.radius - signed_dist;
325 if(depth < 0)
return false;
329 const Vector3<S> normal = -new_s2.n;
330 const Vector3<S>
point = T + new_s2.n * (0.5 * depth - s1.radius);
331 const S penetration_depth = depth;
333 contacts->emplace_back(normal, point, penetration_depth);
340 int sign = (cosa > 0) ? -1 : 1;
341 Vector3<S> p = T + dir_z * (s1.lz * 0.5 * sign);
343 S signed_dist = new_s2.signedDistance(p);
344 S depth = s1.radius - signed_dist;
345 if(depth < 0)
return false;
349 const Vector3<S> normal = -new_s2.n;
350 const Vector3<S>
point = p - new_s2.n * s1.radius + new_s2.n * (0.5 * depth);
351 const S penetration_depth = depth;
353 contacts->emplace_back(normal, point, penetration_depth);
361 template <
typename S>
362 bool cylinderHalfspaceIntersect(
const Cylinder<S>& s1,
const Transform3<S>& tf1,
363 const Halfspace<S>& s2,
const Transform3<S>& tf2,
364 std::vector<ContactPoint<S>>* contacts)
366 Halfspace<S> new_s2 = transform(s2, tf2);
368 const Matrix3<S>& R = tf1.linear();
369 const Vector3<S>& T = tf1.translation();
371 Vector3<S> dir_z = R.col(2);
372 S cosa = dir_z.dot(new_s2.n);
374 if(cosa < halfspaceIntersectTolerance<S>())
376 S signed_dist = new_s2.signedDistance(T);
377 S depth = s1.radius - signed_dist;
378 if(depth < 0)
return false;
382 const Vector3<S> normal = -new_s2.n;
383 const Vector3<S>
point = T + new_s2.n * (0.5 * depth - s1.radius);
384 const S penetration_depth = depth;
386 contacts->emplace_back(normal, point, penetration_depth);
393 Vector3<S> C = dir_z * cosa - new_s2.n;
394 if(std::abs(cosa + 1) < halfspaceIntersectTolerance<S>() || std::abs(cosa - 1) < halfspaceIntersectTolerance<S>())
395 C = Vector3<S>(0, 0, 0);
403 int sign = (cosa > 0) ? -1 : 1;
405 Vector3<S> p = T + dir_z * (s1.lz * 0.5 * sign) + C;
406 S depth = -new_s2.signedDistance(p);
407 if(depth < 0)
return false;
412 const Vector3<S> normal = -new_s2.n;
413 const Vector3<S>
point = p + new_s2.n * (0.5 * depth);
414 const S penetration_depth = depth;
416 contacts->emplace_back(normal, point, penetration_depth);
425 template <
typename S>
426 bool coneHalfspaceIntersect(
const Cone<S>& s1,
const Transform3<S>& tf1,
427 const Halfspace<S>& s2,
const Transform3<S>& tf2,
428 std::vector<ContactPoint<S>>* contacts)
430 Halfspace<S> new_s2 = transform(s2, tf2);
432 const Matrix3<S>& R = tf1.linear();
433 const Vector3<S>& T = tf1.translation();
435 Vector3<S> dir_z = R.col(2);
436 S cosa = dir_z.dot(new_s2.n);
438 if(cosa < halfspaceIntersectTolerance<S>())
440 S signed_dist = new_s2.signedDistance(T);
441 S depth = s1.radius - signed_dist;
442 if(depth < 0)
return false;
447 const Vector3<S> normal = -new_s2.n;
448 const Vector3<S>
point = T - dir_z * (s1.lz * 0.5) + new_s2.n * (0.5 * depth - s1.radius);
449 const S penetration_depth = depth;
451 contacts->emplace_back(normal, point, penetration_depth);
459 Vector3<S> C = dir_z * cosa - new_s2.n;
460 if(std::abs(cosa + 1) < halfspaceIntersectTolerance<S>() || std::abs(cosa - 1) < halfspaceIntersectTolerance<S>())
461 C = Vector3<S>(0, 0, 0);
469 Vector3<S> p1 = T + dir_z * (0.5 * s1.lz);
470 Vector3<S> p2 = T - dir_z * (0.5 * s1.lz) + C;
472 S d1 = new_s2.signedDistance(p1);
473 S d2 = new_s2.signedDistance(p2);
475 if(d1 > 0 && d2 > 0)
return false;
480 const S penetration_depth = -std::min(d1, d2);
481 const Vector3<S> normal = -new_s2.n;
482 const Vector3<S>
point = ((d1 < d2) ? p1 : p2) + new_s2.n * (0.5 * penetration_depth);
484 contacts->emplace_back(normal, point, penetration_depth);
493 template <
typename S>
494 bool convexHalfspaceIntersect(
const Convex<S>& s1,
const Transform3<S>& tf1,
495 const Halfspace<S>& s2,
const Transform3<S>& tf2,
496 Vector3<S>* contact_points, S* penetration_depth, Vector3<S>* normal)
498 Halfspace<S> new_s2 = transform(s2, tf2);
501 S depth = std::numeric_limits<S>::max();
503 for(
int i = 0; i < s1.num_points; ++i)
505 Vector3<S> p = tf1 * s1.points[i];
507 S d = new_s2.signedDistance(p);
517 if(contact_points) *contact_points = v - new_s2.n * (0.5 * depth);
518 if(penetration_depth) *penetration_depth = depth;
519 if(normal) *normal = -new_s2.n;
527 template <
typename S>
528 bool halfspaceTriangleIntersect(
const Halfspace<S>& s1,
const Transform3<S>& tf1,
529 const Vector3<S>& P1,
const Vector3<S>& P2,
const Vector3<S>& P3,
const Transform3<S>& tf2,
530 Vector3<S>* contact_points, S* penetration_depth, Vector3<S>* normal)
532 Halfspace<S> new_s1 = transform(s1, tf1);
534 Vector3<S> v = tf2 * P1;
535 S depth = new_s1.signedDistance(v);
537 Vector3<S> p = tf2 * P2;
538 S d = new_s1.signedDistance(p);
546 d = new_s1.signedDistance(p);
555 if(penetration_depth) *penetration_depth = -depth;
556 if(normal) *normal = new_s1.n;
557 if(contact_points) *contact_points = v - new_s1.n * (0.5 * depth);
565 template <
typename S>
566 bool planeHalfspaceIntersect(
const Plane<S>& s1,
const Transform3<S>& tf1,
567 const Halfspace<S>& s2,
const Transform3<S>& tf2,
569 Vector3<S>& p, Vector3<S>& d,
570 S& penetration_depth,
573 Plane<S> new_s1 = transform(s1, tf1);
574 Halfspace<S> new_s2 = transform(s2, tf2);
578 Vector3<S> dir = (new_s1.n).cross(new_s2.n);
579 S dir_norm = dir.squaredNorm();
580 if(dir_norm < std::numeric_limits<S>::epsilon())
582 if((new_s1.n).dot(new_s2.n) > 0)
584 if(new_s1.d < new_s2.d)
586 penetration_depth = new_s2.d - new_s1.d;
596 if(new_s1.d + new_s2.d > 0)
600 penetration_depth = -(new_s1.d + new_s2.d);
608 Vector3<S> n = new_s2.n * new_s1.d - new_s1.n * new_s2.d;
609 Vector3<S> origin = n.cross(dir);
610 origin *= (1.0 / dir_norm);
615 penetration_depth = std::numeric_limits<S>::max();
621 template <
typename S>
622 bool halfspacePlaneIntersect(
const Halfspace<S>& s1,
const Transform3<S>& tf1,
623 const Plane<S>& s2,
const Transform3<S>& tf2,
624 Plane<S>& pl, Vector3<S>& p, Vector3<S>& d,
625 S& penetration_depth,
628 return planeHalfspaceIntersect(s2, tf2, s1, tf1, pl, p, d, penetration_depth, ret);
632 template <
typename S>
633 bool halfspaceIntersect(
const Halfspace<S>& s1,
const Transform3<S>& tf1,
634 const Halfspace<S>& s2,
const Transform3<S>& tf2,
635 Vector3<S>& p, Vector3<S>& d,
637 S& penetration_depth,
640 Halfspace<S> new_s1 = transform(s1, tf1);
641 Halfspace<S> new_s2 = transform(s2, tf2);
645 Vector3<S> dir = (new_s1.n).cross(new_s2.n);
646 S dir_norm = dir.squaredNorm();
647 if(dir_norm < std::numeric_limits<S>::epsilon())
649 if((new_s1.n).dot(new_s2.n) > 0)
651 if(new_s1.d < new_s2.d)
654 penetration_depth = std::numeric_limits<S>::max();
660 penetration_depth = std::numeric_limits<S>::max();
667 if(new_s1.d + new_s2.d > 0)
672 penetration_depth = -(new_s1.d + new_s2.d);
678 Vector3<S> n = new_s2.n * new_s1.d - new_s1.n * new_s2.d;
679 Vector3<S> origin = n.cross(dir);
680 origin *= (1.0 / dir_norm);
685 penetration_depth = std::numeric_limits<S>::max();
Main namespace.
Definition: broadphase_bruteforce-inl.h:45
std::chrono::system_clock::time_point point
Representation of a point in time.
Definition: time.h:51