0

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:

  1. For a given point calculate its distance to each plane of the convex polyhedron
  2. Check if distance is negative or positive
    1. If distance is negative point lies on the opposite side of the plane's normal so it's behind it.
    2. Else point lies on the same side as the plane's normal so it's in front of it
  3. 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:

enter image description here

rbaleksandar
  • 8,713
  • 7
  • 76
  • 161
  • Don't worry about halfspaces just think about the planes. For each plane with an outward pointing normal you want DistPointPlane < 0. In that case there are 5 planes to check. I suspect the code example is from C where there is no way to know how many elements are in an array so you need to explicitly supply the length of the array. More modern languages are smarter. – Salix alba Sep 28 '16 at 08:19
  • I think it's actually C++ due to `b-a` and similar which are of type `Point` (I was actually unable to find the implementation for this :D) and this is clearly operator overloading. As for the distance check - yeah, at least this part of the algorithm is perfectly clear (I've also mentioned it in my post). The fact that its working without any issues does show that at least what I've changed delivers correct results. It's the mathematical explanation I'm uncertain of because of this `n` argument. – rbaleksandar Sep 28 '16 at 11:04
  • Also the number of planes inside the array `Plane *h` is something that is known since the algorithm calculates stuff that is based on a convex polyhedron and we clearly know the number of planes in such a polyhedron: a square pyramid has 5 planes (correct me if I'm wrong). It might be that just the comments on this `n` are gibberish. :D – rbaleksandar Sep 28 '16 at 11:06
  • Yes, I see its the interpretation of the comment for the code. I think the author is considering the 5 half-spaces which include the shape rather than all ten halfspaces. – Salix alba Sep 28 '16 at 11:35
  • You can post this as the answer. I also think now that this is what he meant since for a given halfspace if the point is not in it then it's obviously in the other halfspace so basically all halfspaces play a role here even though the ones outside the pyramid are implicitly considered. Thanks! – rbaleksandar Sep 28 '16 at 12:27

2 Answers2

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.

chasester
  • 9
  • 5
0

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.

BobMorane
  • 3,870
  • 3
  • 20
  • 42