iMSTK
Interactive Medical Simulation Toolkit
Docs/Collision/Collision_Detection.md
1 # Collision Detection
2 
3 A collision detection method in iMSTK is defined through the `CollisionDetectionAlgorithm` base class. This class assumes two input geometries and produces a CollisionData output. `CollisionDetectionAlgorithm` accepts geometries in either order, the output will be flipped if inputs are flipped. For example:
4 
5 ```cpp
6 SurfaceMeshToSphereCD myCollisionDetection;
7 myCollisionDetection.setInput(myGeomA, 0);
8 myCollisionDetection.setInput(myGeomB, 1);
9 myCollisionDetection.update();
10 
11 std::shared_ptr<CollisionData> cdData = myCollisionDetection.getCollisionData();
12 cdData->elementsA; // Refers to input 0 geometry/myGeomA
13 cdData->elementsB; // Refers to input 1 geometry/myGeomB
14 ```
15 
16 ## Supported Collision Detection
17 ------
18 
19 ### Legend
20 
21  - `-`: Not collidable, unimplemented.
22  - X: Collidable, implemented.
23  - N/A: Not collidable, not applicable.
24 
25 ### Matrix
26 
27 | | Capsule | Cylinder | ImplicitGeometry | LineMesh | OrientedBox | Plane | PointSet | Sphere | SurfaceMesh |
28 | :--- | :----: | :----: | :----: | :----: | :----: | :----: | :----: | :----: | :----: |
29 | Capsule | X | | | | | | | | |
30 | Cylinder | `-` | `-` | | | | | | | |
31 | ImplicitGeometry | `-` | `-` | `-` | | | | | | |
32 | LineMesh | X | `-` | `-` | X | | | | | |
33 | OrientedBox | `-` | `-` | `-` | `-` | `-` | | | | |
34 | Plane | X | `-` | `-` | `-` | `-` | N/A | | | |
35 | PointSet | X | X | X | N/A | X | X | N/A | | |
36 | Sphere | X | X | `-` | X | `-` | X | X | X | |
37 | SurfaceMesh | X | `-` | `-` | X | `-` | X | X | X | X |
38 
39 ### Notes
40 
41  - Fluid collision is available but not through a generalized PointSetvsPointSetCD.
42  - SurfaceMesh & LineMesh extend PointSet. So PointSet to X may give sufficient behaviour.
43  - SurfaceMeshToPlaneCD covered by PointSetPlaneCD
44 
45 There are two approaches to collision detection.
46 
47 ## Static Collision Detection
48 
49 Given a snapshot of two already overlapping geometries, find the best solution to separate them. This normally involves resolving the geometry along directions that produce minimal movement. Often objects in physics simulations move small amounts so one can reliably resolve along this direction to get believable behavior.
50 
51 - Objects moving too fast may produce strange results. Such as objects tunneling through each other without ever observing a collision or geometry resolving to the wrong feature of another. This also effects the maximum allowed velocity or force of a simulation. Which can make a simulation harder to tune (smaller stable parameter space).
52 
53 ## Dynamic Collision Detection
54 
55 Given two overlapping geometries and their dynamics (or two cached snapshots of them over time). Find the intersections a-priori and deal with them. Almost 100% of the time dynamic CD methods are paired with static CD methods as a fallback. This allows solvers to not guarantee non-intersecting states at the end of a timestep which may be difficult (for example, in an over constrained system).
56 
57 ## Continuous Collision Detection
58 
59 Continuous collision detection is a form of dynamic CD. It uses the dynamics of the object to compute exact time of impact. The usual solution is to linear interpolate elements of a geometry over time and find the time at which the elements are coplanar. For example, a vertex and a triangle moving. When the vertex and triangle are coplanar they intersect so long as the vertex still lies in the triangle. CCD can often be hard to tune and deal with floating point error. This can be alleviated with static CD as a fallback.
60 
61 ## Collision Manifolds
62 
63 Collision manifolds define the areas/points/patches of contact should two bodies be separated and *just* touch. From contacts or whatever is needed for the solver to separate may be computed. These manifolds are made up of N or more types of contacts. With various types of contacts for shapes.
64 
65 <p align="center">
66  <img src="Collision_Detection/contactManifolds.png" alt="various contact manifolds"/>
67 </p>
68 
69 * Face-Vertex:
70  * For triangle meshes, popularly just called vertex-triangle or VT/TV contact.
71 
72 * Face-Face:
73  * Ignored, covered with Face-Vertex
74 
75 * Face-Edge:
76  * Ignored, covered with Face-Vertex.
77 
78 * Edge-Edge:
79  * Required for line mesh vs line mesh (polylines).
80 
81 * Edge-Vertex:
82  * Ignored, covered with Face-Vertex.
83  * Required when using curved surface vs meshes.
84 
85 * Vertex-Vertex:
86  * Ignored, covered with Face-Vertex.
87  * Required when using curved surface vs meshes.
88 
89 How a collision manifold is specified varies a lot among collision systems. The solution can get ambigious when only looking at a snapshot of overlapping geometries. It may not be clear what the **best** manifold would be.
90 
91 <p align="center">
92  <img src="Collision_Detection/edgeContactOverlap.png" alt="manifold when overlapping" width="200"/>
93 </p>
94 
95 <p align="center">
96  <img src="Collision_Detection/edgeContact.png" alt="manifold when separated" width="200"/>
97 </p>
98 
99 It becomes of a problem of specifying this to the solver. Some collision systems report intersecting elements (ie: This triangle touched this edge, or this edge touched this point). Others report per contact points where N point-based contacts need to be used to support a face.
100 
101 <p align="center">
102  <img src="Collision_Detection/edgeContactResolve.png" alt="Two point,direction,depth contacts required to support the box" width="300"/>
103 </p>
104 
105 Instead of subbing points for faces though, a constraint can be formulated between two elements in contact. For example, Vertex-Triangle as mentioned earlier, shown below:
106 
107 <p align="center">
108  <img src="Collision_Detection/vertexTriangle.png" alt="vertex triangle manifold" width="300"/>
109 </p>
110 
111 ## Collision Data
112 ------
113 
114 With this approach it is required to store contact pairs of elements. Vertex-triangle, edge-edge. Whereas in the previous approach the system can only store point-based contacts. iMSTK supports both methods providing the following element types.
115 
116 * **PointDirectionElement**: Gives point, normal, and depth contact
117 * **CellIndexElement**: Gives the id of a cell or the id of a cells vertices. Check count to tell which.
118 
119  * If idCount==1. The id refers to a cell given by type.
120 
121  * IMSTK_VERTEX
122  * IMSTK_EDGE
123  * IMSTK_TRIANGLE
124  * IMSTK_TETRA
125 
126  * If idCount > 1. The id refers to the vertex indices of the cell.
127 
128  * ex: idCount==3, means 3 vertex ids of the triangle.
129  * The ability to give cells via vertex ids is useful to avoid assigning ids to cells of cells. ie: edges of triangles, triangle faces of a tetrahedron, edges of a tetrahedron.
130 
131  * parentId is provided and optional. When possible it will refer to the highest dimensional cell containing the vertex. For a SurfaceMesh this would be a triangle id, for a TetrahedralMesh this would be a tetrahedron id. For a LineMesh this would be a line id.
132 
133 * **CellVertexElement**: Same as a CellIndexElement but gives the vertices by value instead.
134 
135  * Useful when the other geometry doesn't contain vertices with ids (implicit geometry).
136 
137 * **TransientCellIndexElement**: Encapsulates one CellVertexElement and one CellIndexElement to store a transient (moving in time) cell required by CCD algorithms.
138 
139  * The CellVertexElement stores the previous time state of the cell directly in terms of 3D points.
140  * The CellIndexElement stores the current time state of the cell using cell ids from the colliding geometries.
141 
142 iMSTK collision methods prefer to produce contact element pairs over point-based contacts. This is because point-based contacts can be computed from element pairs when needed. But element pairs cannot so easily be computed from point-based contacts.
143 
144 ## Collision Resolution
145 
146 Resolving collision can be classified into two categories.
147 
148 * Matrix-Free: Normally resolve collisions at the moment of finding or in later iterations over all contacts found during collision.
149 
150  * Ex1: A point lies under a plane 50 units. At the moment of noticing, move it up 50 units.
151  * Ex2: A point lies under a plane 50 units. Add a contact that informs to move it up 50 units. Later resolve all contacts.
152  * If all contacts resolved, later another could be created. For example, stacked cubes A, B, & C. Resolving A-B might move B into C. This would normally require another collision detection pass (likely next step of the simulation). Ex1 may not require another CD iteration as it does CD while resolving. Given the correct order of CD testing, they would actually resolve.
153 
154 * Matrix: These approaches assemble matrices to resolve them all in a semi-implicit or implicit manner.
155 
156  * Non-penetration equations are solved in iterative manners
157  * Often "constraint" based
158 
159 ## Collision Constraints
160 
161 The matrix ones are often "constraint based". The constraints giving a single scalar and gradient for which to solve. Often represented as a single row in a system. For a non-penetration constraint the scalar should be 0 when separated. The gradient then gives the direction to change the inputs such that the scalar becomes 0 (the root). This gives a bit better generalization to apply to a lot of things, perhaps not even non-penetration constraints (springs, joints, etc).
162 
163 * PBDCollisionConstraints: Given positions of geometry, computes a gradient and scalar to reach zero/non-penetration.
164 * RBDConstraint: Given position and orientation of body, computes a jacobian (linear and angular gradient) and scalar to reach zero/non-penetration.
165 
166 A pbd constraint to keep a point to a plane:
167 
168 * Scalar = distance between the plane and point
169 * Gradient = the plane normal (direction to resolve, direction to get to a scalar of 0)
170 
171 .. image:: Collision_Detection/constraintEx1.png
172  :width: 300
173  :alt: Alternative text
174  :align: center
175 
176 A rbd constraint to keep a box above a plane by adding a constraint per vertex corner.
177 
178 * Scalar = distance between plane and vertex/corner of box.
179 * Jacobian
180 
181  * Linear Gradient = plane normal (direction to resolve linearly)
182  * Angular Gradient = plane normal crossed with the distance between contact point and center of body mass (direction to resolve angularly)
183 
184 A useful function of these constraints is reprojection. In the PbdConstraint example, as the vertex resolves closer to the triangle the distance to the triangle is recomputed. While this isn't as foolproof as recomputing collision, it does allow better solutions at a cheaper cost (especially on overconstrained systems).
185 
186 Lastly the signs of the constraints matter. Unsigned constraints gradients flip.
187 
188 ## Persistent Contacts
189 ------
190 
191 Persistent contacts are those that persist over time. Often these are brought up with resting contacts keeping track of the same contacts frame-to-frame. The schemes for persistent contacts vary.
192 
193 * A common implementation is to build up contacts over time. Instead of computing a full new set of contacts every frame. Keep around contacts from previous frames according to a heurisitc. Some implementations afford only reporting few contacts in one frame while ending up with N contacts to support whatever minimum number of contacts is required.
194 * Another such implementation is in ImplicitGeoetryToPointSetCCD. This CD will remember that last point outside of the implicit geometry before entering and recycle it to update the existing contact should the corresponding vertex still be inside the implicit geometry.
195 
196 ## Collision Detection Types
197 
198 ### BidirectionalPlaneToSphereCD
199 ------
200 
201 * Static Collision Method
202 
203 **Method**
204 
205 <p align="center">
206  <img src="Collision_Detection/sphereToPlane.png" width="300"/>
207 </p>
208 
209 * Projects the sphere center onto the plane to compute distance to the plane. If the distance exceeds radius then it is not touching the plane. The direction to resolve is then computed from the difference between the nearest point on the plane and the sphere center.
210 
211 **Additional Notes**
212 
213 * If the sphere crosses the center of the plane it will resolve to the opposite side. Thus not working bidirectionally but suffers from easy tunneling depending on the sphere size and displacement.
214 * This method produces 1 PointDirectionElement for the sphere.
215 * This method produces 1 PointDirectionElement for the plane.
216 * Only on contact is required for sphere on a plane.
217 
218 ### UnidirectionalPlaneToSphereCD
219 ------
220 
221 * Static Collision Method
222 
223 **Method**
224 
225 <p align="center">
226  <img src="Collision_Detection/sphereToPlane.png" width="300"/>
227 </p>
228 
229 * Projects the sphere center onto the plane to compute distance to the plane. If the distance exceeds the radius then it is not touching the plane. The direction to resolve is always the normal of the plane.
230 
231 **Additional Notes**
232 
233 * One side of the plane is considered "in" the other "out".
234 * Only requires one contact point.
235 
236 ### ImplicitGeometryToPointSetCCD
237 ------
238 
239 * Dynamic Collision Method
240 
241 **Method**
242 
243 <p align="center">
244  <img src="Collision_Detection/pointCCD.png" width="300"/>
245 </p>
246 
247 * This method traces the displacement of a point from previous to current position sampling the implicit geometry looking for the first sign change/root. This point is recorded as the contact point.
248 * It then computes the normalized gradient at the contact point from the implicit geometry. This is used as the contact normal.
249 * Lastly it projects the (current position - contact position).dot(contact normal) to produce the depth to resolve it along the contact normal for the point to arrive on the plane of the normal which should minimize.
250 
251 **Additional Notes**
252 
253 * This method is very unique it that it saves the last contact point outside the shape. Should a point not exit/resolve within a frame it will retrace the displacement, find the root, contact point, contact normal, and reproject to produce an updated contact using the old one.
254 * This method is important as it avoids sampling the interior of the implicit geometry which is useful for levelsets and non-SDF implicit geometries.
255 
256 ### ImplicitGeometryToPointSetCD
257 ------
258 
259 * Static Collision Method
260 
261 **Method**
262 
263 <p align="center">
264  <img src="Collision_Detection/pointToImplicit.png" width="300"/>
265 </p>
266 
267 * This method samples the implicit geometry for distance and then computes the normalized gradient for the direction to resolve a point (see gradient computation in diagram via central finite difference).
268 
269 **Additional Notes**
270 
271 * This is traditional point vs SDF collision resolution.
272 * This method produces N PointIndexDirectionElements for every point.
273 
274 ### ClosedSurfaceMeshToMeshCD
275 ------
276 
277 * Static Collision Method
278 
279 **Method**
280 
281 * This method computes collision for SurfaceMesh vs PointSet/LineMesh/SurfaceMesh. It works best for closed surfaces with an inside/outside. It also works for non-closed geometry but will still assume sides. For example, it would still work for a plane mesh.
282 * This method works with two brute force expensive passes:
283 
284 <p align="center">
285  <img src="Collision_Detection/pointInPolygon.png" width="300"/>
286 </p>
287 
288 For a curved surface this point in polygon strategy works well.
289 
290 * Vertex Pass: For every point compute the nearest point on the other mesh. That point may be on a vertex, edge, or triangle. Then the angled-weighted pseudonormal is computed on that element. This normal is used to compute the sign in order to tell if inside/outside the SurfaceMesh. Finally mark which vertices lie inside/outside during this pass for later.
291 
292 <p align="center">
293  <img src="Collision_Detection/psuedonormalProblem.png" width="300"/>
294 </p>
295 
296 For meshes using the normal of the element will produce incorrect results (see above where point is inside according to one face, outside according to the other). This is where the angle-weighted pseudonormal comes in.
297 
298 * Edge Pass: For every edge that still lies outside the SurfaceMesh (with previously computed inside/outside mask). Compute the closest point on that edge with every edge in the SurfaceMesh. Then compute if that closest point lies inside the SurfaceMesh via another point in polygon test.
299 
300 <p align="center">
301  <img src="Collision_Detection/edgeToEdge.png" width="300"/>
302 </p>
303 
304 **Additional Notes**
305 
306 * This method may produce vertex-triangle, vertex-edge, or vertex-vertex collision data.
307 * It can resolve completely deep penetrations of meshes similar to SDF collision.
308 * It's tougher to spatially accelerate as it requires global queries rather than bounded ones. Specify a bound/maximum radius to search. This would establish a maximum penetration depth. This fact heavily influences what type of spatial acceleration possible. Kdtree's, for instance, may be a bad idea.
309 
310 ### PointSetToCapsuleCD
311 ------
312 
313 * Static Collision Method
314 
315 **Method**
316 
317 <p align="center">
318  <img src="Collision_Detection/capsuleToPoint.png" width="300"/>
319 </p>
320 
321 * Given the line segment that forms the center/medial of the capsule, compute the closest poitn on it via projection. Computing both orthogonal (a) and parallel distance (b). Should the distance to this closest point exceed radius then it is outside the capsule.
322 
323 **Additional Notes**
324 
325 * This method may also be used to compute signed distances of a capsule.
326 * This method produces N PointIndexDirectionElements for each point.
327 * This method produces N PointDirectionElements for the capsule given each point.
328 * Only one contact point is required for a single point on a capsule.
329 
330 ### PointSetToOrientedBoxCD
331 ------
332 
333 * Static Collision Method
334 
335 **Method**
336 
337 <p align="center">
338  <img src="Collision_Detection/obbToPoint.png" width="300"/>
339 </p>
340 
341 * To compute the resolution vectors (shown in pink). First project the point along each axes of the oriented box. These axes can be acquired from the inverse (transpose) of the oriented box rotation matrix (each column).
342 * If within these bounds, finding if inside the box is trivial.
343 * To then find the direction and amount to minimally resolve, find the nearest point on the box.
344 
345  * If the point is inside the box:
346 
347  * Compute the distance to each face of the box by subtracting the distance along the orienetation axes from the extent (half length, width, height). If width is 5 and is 6 units along the axes. Then it is 1 unit in front of the face.
348  * Then compute point on that face.
349 
350  * If the point outside the box (not required for contact put part of the standard computation to find closest point):
351 
352  * Sum the vectors from each face to the point so long as they lie outside the plane of the face. The resulting vector will give distance to point on nearest face, edge, or vertex of the box.
353 
354 **Additional Notes**
355 
356 * This method may also be used to compute signed distance of an oriented box.
357 * This method produces N PointIndexDirectionElements for each point.
358 * This method produces N PointDirectionElements for the box.
359 * Only one contact is required for a single point on a box.
360 
361 ### PointSetToPlaneCD
362 ------
363 
364 * Static Collision Method
365 
366 **Method**
367 
368 <p align="center">
369  <img src="Collision_Detection/pointPlaneProj.png" width="300"/>
370 </p>
371 
372 * Projects the point (in green) to the plane given the plane normal and origin (red). Resolution vector shown in pink.
373 
374 **Additional Notes**
375 
376 * This method produces N PointIndexDirectionElements for each point.
377 * This method produces N PointDirectionElements for the plane given each point.
378 * This method may also be used to compute signed distances to plane.
379 * Only one contact is required for a single point on plane.
380 
381 ### PointSetToSphereCD
382 ------
383 
384 * Static Collision Method
385 
386 **Method**
387 
388 <p align="center">
389  <img src="Collision_Detection/pointToSphere.png" width="300"/>
390 </p>
391 
392 * Compute the squared distance to the center of the sphere from the point. Check it against radius.
393 * Penetration vector direction given by the normalized difference between the sphere center and point.
394 * Penetration vector magnitude given by the difference between the radius and distance (distance required to separate along that direction).
395 
396 **Additional Notes**
397 
398 * This method may also be used to compute signed distances to sphere.
399 * Only one contact required for a single point on a sphere.
400 
401 ### SphereToCylinderCD
402 ------
403 
404 * Static Collision Method
405 
406 **Method**
407 
408 * There are 3 cases. Proceed in a point vs cylinder like fashion.
409 * Case 1: Nearest point on the wall of the cylinder.
410 
411 <p align="center">
412  <img src="Collision_Detection/cylinderToPoint.png" width="300"/>
413 </p>
414 
415  * Project the sphere center along the cylinder axes to get distance along the axes. If the center lies outside of the half heights of the cylinder, proceed to the other 2 cases. If it lies within the range of the cylinder. The shortest way out is the wall of the cylinder.
416 
417 * For the other two cases, look at the projected distance along the orthogonal axes. If the orthogonal distance is larger than the radius of the cylinder then the nearest point must be on the edge/rim of the cylinder. If smaller then the nearest point must be on the cap.
418 
419  * Case 2: Nearest point on the face of the cap.
420  * The normal of the cap is used to resolve.
421  * Case 3: Nearest point on the edge/rim of the cap.
422  * The difference between the nearest point and sphere center is used as the normal.
423 
424 **Additional Notes**
425 
426 * One of the more expensive primitives to use.
427 * This primitive has sharp edges & curved surfaces. However only one contact point is needed for a sphere vs convex shape.
428 
429 ### SphereToSphereCD
430 ------
431 
432 * Static Collision Method
433 
434 **Method**
435 
436 <p align="center">
437  <img src="Collision_Detection/sphereToSphere.png" width="300"/>
438 </p>
439 
440 * To compute intersections between spheres, compute the distance between them and then check if it's less than the sum of the radii. The direction to resolve is given by the normalized difference between the centers.
441 
442 **Additional Notes**
443 
444 * Only one contact is needed.
445 
446 ### CapsuleToCapsuleCD
447 ------
448 
449 * Static Collision Method
450 
451 **Method**
452 
453 * To compute intersection between two capsules, find the nearest point on the edges/centerlines of the capsules. Then perform sphere to sphere intersection between two spheres of capsules radius at these two points.
454 
455 ### BidirectionalSurfaceMeshToSphereCD
456 ------
457 
458 * Static Collision Method
459 
460 **Method**
461 
462 <p align="center">
463  <img src="Collision_Detection/sphereToTriangle.png" width="300"/>
464 </p>
465 
466 * For every triangle compute the closest point on the triangle to the sphere center. There are then 3 cases:
467 
468  * Case 1: Closest point on triangle lies on an edge. Just an edge is touching the sphere.
469  * Case 2: Closest point on triangle lies on a vertex. Just a vertex is touching the sphere.
470  * Case 3: Closest point on triangle lies no its face. The face is touching the sphere
471 
472 **Additional Notes**
473 
474 * A unidirectionl one for closed surfaces could be done via pseudonormal calculation on the sphere center.
475 * Only one contact required per triangle touching.
476 
477 ### TetraToLineMeshCD
478 ------
479 
480 * Static Collision Method
481 
482 **Method**
483 
484 * For every line segment, check intersection with every triangle face of every tetrahedron.
485 
486 **Additional Notes**
487 
488 * This method misses the case of the line segment being entirely inside of the tetrahedron. It avoids doing a line vs tet SAT like solution.
489 
490 ### TetraToPointSetCD
491 ------
492 
493 * Static Collision Method
494 
495 **Method**
496 
497 * For every point compute the barycentric coordinates (u,v,w,y) of it to test if inside or out of the tetrahedron.
498 
499 **Additional Notes**
500 
501 * This CD, at the moment, uses a built in spatial hashing for intersection tests.
502 
503 ### SurfaceMeshToCapsuleCD
504 ------
505 
506 * Static Collision Method
507 
508 **Method**
509 
510 * Works just like SurfaceMeshToSphereCD but computes the nearest point on the axes of the capsule to the triangle and creates a "virtual sphere" to then do CD with.
511 
512 <p align="center">
513  <img src="Collision_Detection/capsuleToTriangle.png" width="300"/>
514 </p>
515 
516 * It does this by first computing the nearest points on the triangle to the two vertices of the segment (purple dotted lines). Then computing the nearest point on the segment to the nearest point on the triangle (orange dotted line). Choosing the closest gives us the closest point on edge to triangle. If this point is within the bounds of the capsule height, treat the CD as sphere-triangle at that point with the capsule's radius.
517 
518 **Additional Notes**
519 
520 * Completely embedded triangles aren't handle well.
521 * Only one PointDirection contact is currently generated at the center of the triangle edge, when that edge is parallel with the capsule.
522 
523 ### LineMeshToLineMeshCCD
524 ------
525 
526 * Continuous collision detection for LineMesh vs LineMesh including self-collision. Self collision is indicated by `input0 == input1` to the algorithm.
527 
528 * The implementation uses Algorithm 1 described by Qi et al [[lfs]](#lfs) in Section 4.
529 
530 * This has a thickness parameter found in [imstkEdgeEdgeCCDState.h](https://gitlab.kitware.com/iMSTK/iMSTK/-/blob/master/Source/CollisionDetection/CollisionDetection/imstkEdgeEdgeCCDState.h#L128)
531 
532 # References & Resources
533 
534 Much of the math for geometric intersections can be derived from SAT and GJK.
535 
536 * [SAT](https://en.wikipedia.org/wiki/Hyperplane_separation_theorem) (Seperating Axis Theorem): Projects geometry along numerous axes in an aim to find a axes fo separation between the two. It also works for certain curved surfaces such as spheres.
537 
538  * May also be used to find the axes of minimal separation. Useful for contact generation.
539 
540 * [GJK](https://en.wikipedia.org/wiki/Gilbert%E2%80%93Johnson%E2%80%93Keerthi_distance_algorithm): Aims to find the closest points and distance between two convex geometries by minkowski summing one geometry with the other and checking if the origin lies in the summed geometry.
541 
542  * Works with any convex shape so long `minkowski sum` and `point-in-convex-polygon check` are implemented.
543 
544  * Often combined with EPA (expanding polytope algorithm) to find minimal separation.
545 
546 <a id="gpp">[gpp]</a>
547 den, B. G. van. (2010). Game physics pearls. A.K. Peters.
548 
549 <a id="rcd">[rcd]</a>
550 Ericson, C. (n.d.). Real-time collision detection. Elsevier.
551 
552 <a id="lfs">[lfs]</a>
553 Qi, Di, Karthikeyan Panneerselvam, Woojin Ahn, Venkata Arikatla, Andinet Enquobahrie, and Suvranu De. "Virtual interactive suturing for the Fundamentals of Laparoscopic Surgery (FLS)." Journal of biomedical informatics 75 (2017): 48-62.