RE: [Algorithms] fast triangle-segment test *with precomputation*
Brought to you by:
vexxed72
|
From: Norman V. <nh...@ca...> - 2000-08-03 03:38:13
|
Charles Bloom writes:
>
>Ok, so the Moller+Haines triangle-segment test is about
>as good as it gets without any precomputation. The
>question is, how fast can you get with arbitrary
>precomputation? For example, I can precompute the
>plane of the triangle, and the three perpendicular
>planes which go through the edges. Then the intersections
>are all rays that hit the plane of the triangle and
>whose intersection point is inside the three planes.
>(BTW I don't care about computing the barycentric
>coordinates).
Hey I want to know the same thing !
Here is a naive beginning :-)
Norman
// check to see if the intersection point is actually inside this face
static bool PointInTriangle( Vec3 point, Vec3 tri[3] )
{
REAL xmin, xmax, ymin, ymax, zmin, zmax;
// punt if outside bouding cube
if ( point[0] < (xmin = MIN3 (tri[0][0], tri[1][0], tri[2][0])) ) {
return false;
} else if ( point[0] > (xmax = MAX3 (tri[0][0], tri[1][0], tri[2][0])) )
{
return false;
} else if ( point[1] < (ymin = MIN3 (tri[0][1], tri[1][1], tri[2][1])) )
{
return false;
} else if ( point[1] > (ymax = MAX3 (tri[0][1], tri[1][1], tri[2][1])) )
{
return false;
} else if ( point[2] < (zmin = MIN3 (tri[0][2], tri[1][2], tri[2][2])) )
{
return false;
} else if ( point[2] > (zmax = MAX3 (tri[0][2], tri[1][2], tri[2][2])) )
{
return false;
}
// drop the smallest dimension so we only have to work in 2d.
REAL dx = xmax - xmin;
REAL dy = ymax - ymin;
REAL dz = zmax - zmin;
REAL min_dim = MIN3 (dx, dy, dz);
REAL x1, y1, x2, y2, x3, y3, rx, ry;
if ( fabs(min_dim-dx) <= MY_EPSILON ) {
// x is the smallest dimension
x1 = point[1];
y1 = point[2];
x2 = tri[0][1];
y2 = tri[0][2];
x3 = tri[1][1];
y3 = tri[1][2];
rx = tri[2][1];
ry = tri[2][2];
} else if ( fabs(min_dim-dy) <= MY_EPSILON ) {
// y is the smallest dimension
x1 = point[0];
y1 = point[2];
x2 = tri[0][0];
y2 = tri[0][2];
x3 = tri[1][0];
y3 = tri[1][2];
rx = tri[2][0];
ry = tri[2][2];
} else if ( fabs(min_dim-dz) <= MY_EPSILON ) {
// z is the smallest dimension
x1 = point[0];
y1 = point[1];
x2 = tri[0][0];
y2 = tri[0][1];
x3 = tri[1][0];
y3 = tri[1][1];
rx = tri[2][0];
ry = tri[2][1];
} else {
// all dimensions are really small so lets call it close
// enough and return a successful match
return true;
}
// check if intersection point is on the same side of p1 <-> p2 as p3
REAL tmp = (y2 - y3) / (x2 - x3);
int side1 = SIGN (tmp * (rx - x3) + y3 - ry);
int side2 = SIGN (tmp * (x1 - x3) + y3 - y1);
if ( side1 != side2 ) {
// printf("failed side 1 check\n");
return false;
}
// check if intersection point is on correct side of p2 <-> p3 as p1
tmp = (y3 - ry) / (x3 - rx);
side1 = SIGN (tmp * (x2 - rx) + ry - y2);
side2 = SIGN (tmp * (x1 - rx) + ry - y1);
if ( side1 != side2 ) {
// printf("failed side 2 check\n");
return false;
}
// check if intersection point is on correct side of p1 <-> p3 as p2
tmp = (y2 - ry) / (x2 - rx);
side1 = SIGN (tmp * (x3 - rx) + ry - y3);
side2 = SIGN (tmp * (x1 - rx) + ry - y1);
if ( side1 != side2 ) {
// printf("failed side 3 check\n");
return false;
}
return true;
}
|