I'm interested in the relatively precise point (not line) of collision for calculating angular velocity on impact for use in a impulse calculation. At first I thought, perhaps naively, that I could use the closest point along the shortest overlapping axis, but closest to what exactly?
-
\$\begingroup\$ Maybe I don't understand the theorem, but how can a point tell you anything about a collision? Seems to me that you require a line, or technically a vector, if calculating angular velocity. If you have the vector, I guess technically you'd have a point (if there is a singular point) along the vector where the collision first occurs. \$\endgroup\$– Jesse WilliamsOct 19, 2018 at 15:07
-
1\$\begingroup\$ Possible duplicate of Finding the contact point with SAT \$\endgroup\$– TheraotAug 26, 2019 at 7:35
2 Answers
The axis with the smallest overlap is not necessarily a good guide to where the collision occurred.
Imagine a small cube translating to the right at high speed, entering a larger prism from the side and penetrating a fair distance into the middle:
┌──────┐ ┌──────┐
│ │ ---------→ │ │
│ │ ┌──────┼──────┼───────┐ ↑
└──────┘ │ └──────┘ │ ↓
└─────────────────────┘
Here the smallest overlapping axis is vertical, perpendicular to the incident velocity. Displacing the cube according to this penetration axis will resolve the overlap, but it won't tell us where the collision occurred (ie. on the left side of the object). The behaviour will look like the cube nicked the corner of the platform and skipped upward, rather than slamming into it side-on as it should have.
Many physics engines deem this result "good enough," and leave it up to devs to use a shorter timestep, continuous collision detection methods, or explicit raycast/sweep tests to get finer precision for the cases where they're needed.
What you can do instead is compute, for each axis, the (signed) speed of approach along that axis. Then you can look at the projections you get along that axis, and measure how much time you'd need to rewind at that speed until the two intervals just kiss.
The smallest such result tells you the last axis to lose its separation during the approach along this velocity vector. Backtrack along the velocity vector by this time-since-penetration you've calculated to position the objects the way they were at the moment of contact. You can then find the point, line, or surface common to both shapes at this moment.
(Assuming neither object is rotating relative to the other - if they are, then the axis overlaps you computed for the end of the movement aren't necessarily valid for moments earlier in the movement, and things get more complicated still... The best approach I can think of there is to use the method above as an estimate of contact time, then re-run your overlap checks at the estimated timestamp to get a refined estimate, and close in by binary search. There are probably more sophisticated approaches you could use though.)
I ended up taking one vertex from each shape that provided the maximum part of the smallest overlapping axis. Then, I subtracting one from another and averaged them, providing a highly accurate result.
-
5\$\begingroup\$ How is that accurate at all? The contact point could be in the middle of an edge; taking only a vertex will be highly inaccurate. \$\endgroup\$ Jan 3, 2017 at 7:42
-
4\$\begingroup\$ I think this is only accurate for AABB, it yields the center of gravity of the overlap box. It may a good approximation shapes with a high number of close vertex, as that minimizes the error of picking two that are far appart. I'd not advice this as a general solution. \$\endgroup\$– TheraotMar 15, 2017 at 1:46
-
1\$\begingroup\$ physics engine dev here, this is not correct. The correct solution is to project the penetrating points. media.steampowered.com/apps/valve/2015/… \$\endgroup\$– JonDec 18, 2020 at 19:42