问题
I am looking robust collision detection algorithms and found an awesome book called Realtime Collision Detection by Christer Ericson. I am trying to use a particular algorithm which checks whether a given point is inside convex polyhedron (in 3D space these are the square pyramid, cube and tetrahedron (aka pyramid with all sides being a triangle)). In my case I have a square pyramid. The validation of the point is done by using the intersection volume for a given number of halfspaces and determining whether the point is in front or behind all of the planes that are spanned by the polyhedron's sides. I have difficulties understanding the usage of the argument n
(see below) which represents the number of halfspaces for the given polyhedron:
// Test if point p inside polyhedron given as the intersection volume of n halfspaces
int TestPointPolyhedron(Point p, Plane *h, int n) {
for (int i = 0; i < n; i++) {
if(DistPointPlane(p, h[i]) > 0.0f) return 0;
}
return 1;
}
with DistPointPlane(...)
calculating the distance between a given point and a plane
float DistPointPlane(Point q, Plane p) {
return Dot(q, p.n) - p.d;
}
and Plane
being a structure that represents a plane in 3D space
struct Plane {
Vector n; // Plane normal. Point X on the plane satisfies Dot(n, X) = d
float d; // d = dot(n, p) for a given point on the plane
}
Plane ComputePlane(Point a, Point b, Point c) {
Plane p;
p.n = Normalize(Cross(b - a, c - a));
p.d = Dot(p.n, a);
return p;
}
What the algorithm does is basically the following:
- For a given point calculate its distance to each plane of the convex polyhedron
- Check if distance is negative or positive
- If distance is negative point lies on the opposite side of the plane's normal so it's behind it.
- Else point lies on the same side as the plane's normal so it's in front of it
- If point behind all planes of the given polyhedron it lies inside else it lies outside
Now in terms of a square pyramid as far as I can tell there are 10 halfspaces since we have 4 sides and a base each representing a separate plane (so in total there are 5 planes) that divides the 3D space in two halfspaces (5 planes * 2 = 10 halfspaces
). What I don't get is the usage of n
in the code for the algorithm above. It is used as a termination condition for the loop which iterates through an array of Plane
instances. However as mentioned there are 10 halfspaces.
One thing I have thought about after some digging is the fact that the intersection between two planes is a line (edge of the pyramid). Further quoting Wolfram Mathworld
To uniquely specify the line, it is necessary to also find a particular point on it. This can be determined by finding a point that is simultaneously on both planes
Each of the pyramid's vertices fulfill this requirement since for any given two sides (including the base) we get a line which is between two of the pyramid's vertices. So in terms of intersection we do have 5 (4 for the base and 1 for the apex) however the text in the book (including the comment above the function's implementation) is vague and reading it one might get the wrong idea (at least that's my case).
Is my line of thought close to the truth or am I missing some big chunk in terms of math knowledge?
I have ported the code to Python 3 and altered the algorithm to loop through just my list of planes without taking an additional argument (which, if my thoughts are correct, is basically the same as the original one) and plotted it with matplotlib
. It works perfectly fine but I still want to know whether I have understood it correctly or not:
回答1:
here's a similar question
Basically your shape is a polyhedron but that is simply defined as a shape with many faces normally 6. You need to actually be looking for the name tetrahedron which is the classic pyramid shape you have defined in the visual representation above. But the basic answer is taking the normal of your 5 planes (the 4 triangles and one square), and check if they are facing in the same direction of the point in space. If they all return false then your point is inside of the shape. If any one of them returns true then you are outside the shape. This type of test works for most convex shapes because there is no case where the planes are overlapping there normals.
回答2:
I would say that you understood the most of it. I'm not sure what exactly you mean with "distance". Usually the dotproduct provides the angle between the two vectors. In your case there's one position vector (the point) and one normal vector. Because of the laws of cosine, if the dotproduct is greater 0, the angle between the two vectors is less than 90 degrees. On the other hand, if the product is negative, the angle is greater than 90 degrees. If it's 0, the vectors are orthogonal. So basically it's got nothing to do with distance, but with angles.
来源:https://stackoverflow.com/questions/39740727/algorithm-for-checking-if-3d-point-inside-convex-polyhedron-square-pyramid