问题
I'm trying to work out the best way to determine whether a point is inside a frustum. I have something working, but not sure whether it is too cumbersome, and perhaps there is a more elegant / efficient way I should be doing this.
Suppose I want to find out whether point 'x' is inside a frustrum:
Once I have the locations of the 8 points of the frustrum (4 near points, four far points), I am calculating the normal for each plane of the frustum based on a triangle made from three of the points. For example (as in the diagram above), for the right side, I am making two vectors from three of the points:
Vector U = FBR - NBR
Vector V = FTR - NBR
Then I am making the cross product between these two vectors, ensuring that the winding order is correct for the normal to be pointing inside the frustum, in this case V x U
will give the correct normal.
Right_normal = V x U
Once I have the normal for each plane, I am then checking whether point x is in front of or behind the plane by drawing a vector from x to one of the plane's points:
Vector xNBR = x - NBR
Then I am doing the dot product between this vector and the normal and testing whether the answer is positive, confirming whether point x is the correct side of that plane of the frustrum:
if ( xNBR . Right_normal < 0 )
{
return false;
}
else continue testing x against other planes...
If x is positive for all planes, then it is inside the frustum.
So this seems to work, but I'm just wondering whether I'm doing this in a stupid way. I didn't even know what 'cross product' meant until yesterday, so it's all rather new to me and I might be doing something rather silly.
回答1:
To adapt the approach you have taken, rather than change it totally, you can make use of the fact that 2 of the pairs of planes are parallel. Create only one normal for that pair of planes. You already have the test for the point being "in front" of one of the planes, but assuming you know the depth of the frustum, you can use the same distance to test the point against the other parallel face.
double distancePastFrontPlane = xNBR . Right_normal;
if (distancePastFrontPlane < 0 )
{
// point is in front of front plane
return false;
if(distancePastFrontPlane > depthFaceRtoFaceL)
{
// point is behind back plane
return false;
}
}
If you have multiple points to test against the same frustum you can benefit because you only calculate the frustum depth once (per pair of parallel planes).
来源:https://stackoverflow.com/questions/41163030/determine-if-point-is-in-frustum