typedef enum pointPos {PLANE_FRONT, PLANE_BACK, PLANE_COINCIDE} pointPos;
pointPos classifyPoint(FACE *face, Vector3 *point)
{
float p = scalarProduct(&face->normal, point) + face->distance;
if( p > 0.0f ) return PLANE_FRONT;
if( p < 0.0f ) return PLANE_BACK;
return PLANE_COINCIDE;
}
point outside of a brush problem
I've got a pretty decent .Map file parser, but theres just one little bug that is keeping me from making shapes other than cubes... I need to be able to test whether or not a vertice is outside of a given brush, and I've got this fucntion to do just that:
but the problem is, it thinks that 4 of the vertices of my actual cube (and these are correct vertices that should coincide) are outside of it...but they are not. is there something wrong with my code or is there an error in my math?
You have to add an epsilon value.
if(p > -MY_EPSILON && p < MY_EPSILON)
return COINCIDE;
if(p < 0.0f)
return BACK;
else
return FRONT;
your presision is to narrow.
if(p > -MY_EPSILON && p < MY_EPSILON)
return COINCIDE;
if(p < 0.0f)
return BACK;
else
return FRONT;
your presision is to narrow.
Epsilon can be thought of as the smallest delta that wouldn't affect the outcome of some process.
Choosing a good epsilon can be done using careful floating-point precision analysis, or it can be done by just throwing values at the wall and seeing what sticks. Needless to say, most code-and-burn game programmers choose the second method.
If your values are in the "1.0" range (i e, measured in meters) then 1e-5 is a good value for epsilon, because it's about one bit's worth of the mantissa at scale 1.0 (very loosely). If you're working with inches instead of meters, you might want 1e-4 instead -- or, if you're really sloppy, 1e-3.
Burn, baby, burn!
Choosing a good epsilon can be done using careful floating-point precision analysis, or it can be done by just throwing values at the wall and seeing what sticks. Needless to say, most code-and-burn game programmers choose the second method.
If your values are in the "1.0" range (i e, measured in meters) then 1e-5 is a good value for epsilon, because it's about one bit's worth of the mantissa at scale 1.0 (very loosely). If you're working with inches instead of meters, you might want 1e-4 instead -- or, if you're really sloppy, 1e-3.
Burn, baby, burn!
alright, I'm still getting the same problem. this time I've got this code:
the first vertex that it thinks is wrong (which is right) is this, along with the face normal and distance:
point checking for: (2,2,-2)
face distance: 2
face normal: (0, 1, 0)
my epsilon not sufficient? I've tried 1e-5, 1e-4, and 1e-3.
(1e-5 == 0.00001), correct?
#define EPSILON (1e-5)typedef enum pointPos {PLANE_FRONT, PLANE_BACK, PLANE_COINCIDE} pointPos;/** test whether or not a point is in front, behind, or coincides with a plane **/pointPos classifyPoint(FACE *face, Vertex3 *point){ float p = scalarProduct(&face->normal, point) + face->distance; if((p > -EPSILON) && (p < EPSILON)) return PLANE_COINCIDE; if( p < 0.0f ) return PLANE_BACK; if( p > 0.0f ) return PLANE_FRONT;}
the first vertex that it thinks is wrong (which is right) is this, along with the face normal and distance:
point checking for: (2,2,-2)
face distance: 2
face normal: (0, 1, 0)
my epsilon not sufficient? I've tried 1e-5, 1e-4, and 1e-3.
(1e-5 == 0.00001), correct?
Usually, if I don't understand what happens, I add more printf():s to see what's happening. You could print the values of your variables out before comparing them. Then, if you are lucky, you could see something that starts to make sense.
For example there you have:
point checking for: (2,2,-2)
face distance: 2
face normal: (0, 1, 0)
If I'm not calculating wrong, your p is going to be
p = 4;
not p = 0;
So it's not even close to zero in that case.
For example there you have:
point checking for: (2,2,-2)
face distance: 2
face normal: (0, 1, 0)
If I'm not calculating wrong, your p is going to be
p = 4;
not p = 0;
So it's not even close to zero in that case.
alright, all the math is correct, at least for the classifyPoint() Fucntion. I'm assuming my functions for getting the normaland distance of a plane are correct, because if I just skip trying to determine if all the vertices are not outside the plane, I can successfully draw a cube (or many) on the screen and have it completely put together after fidning all the missing vertices and then putting them in the correct order. what could be wrong here? I'm stumped.
I'm pretty sure all these functions are correct:
I'm pretty sure all these functions are correct:
/** return the normal of a face **/Vertex3 getNormal(FACE *face){ Vertex3 U, V, normal; // subtractVV subtracts two vertexes (arg2 from arg1) U = subtractVV(&face->vertex[1], &face->vertex[0]); V = subtractVV(&face->vertex[2], &face->vertex[1]); normal = vectorialProduct(&U, &V); return normal;}/** normalize a vector **/int normalize(Vertex3 *normal){ double length; length = (float)sqrt(pwr(normal->x, 2) + pwr(normal->y, 2) + pwr(normal->z, 2)); if (length != 0) { normal->x = (float)(normal->x / length); normal->y = (float)(normal->y / length); normal->z = (float)(normal->z / length); } return 0;}/** return the distance of a plane **/float getDistance(FACE *face){ return (float)scalarProduct(&face->normal, &face->vertex[0]);}
I think this is the problem: are there two different distance formulas? as in, theres a distance between a plane and its origin, and isn't there a separate distance required for this such as the distance bewteen a given vertex and the origin? ...
Edit:
distance between a plane and the origin, and length of a vector.
perhaps length of a vector is what I'm supposd to use here...
Edit: nope. thats not it. all my calculations seem to work just fine until I try to classifyPoint();
any input on this would be great.
[Edited by - LabRat404 on November 29, 2004 9:58:08 PM]
Edit:
distance between a plane and the origin, and length of a vector.
perhaps length of a vector is what I'm supposd to use here...
Edit: nope. thats not it. all my calculations seem to work just fine until I try to classifyPoint();
any input on this would be great.
[Edited by - LabRat404 on November 29, 2004 9:58:08 PM]
You're not actually normalizing the face normal when you calculate it. You have to do that before you return it.
Also, sometimes a plane equation is written as Ax+By+Cz+D = 0, sometimes it's Ax+By+Cz = D -- note the difference in sign. Make sure you use the same convention throughout your code.
If you step through the entire function, and look at all the values that come out, you should easily be able to tell what is going wrong.
Also, sometimes a plane equation is written as Ax+By+Cz+D = 0, sometimes it's Ax+By+Cz = D -- note the difference in sign. Make sure you use the same convention throughout your code.
If you step through the entire function, and look at all the values that come out, you should easily be able to tell what is going wrong.
all the normals I calculate get normalized right after they are calculated. is that what you mean? that a normalized normal is not always what I need?
Edit: as soon as I get the normal, it gets normalized directly afterward, as shown:
my normalize function is this:
Edit: as soon as I get the normal, it gets normalized directly afterward, as shown:
...world->brush[g].face.normal = getNormal(&world->brush[g].face); /* get the plane's normal */ normalize(&world->brush[g].face.normal); /* normalize the normal */...
my normalize function is this:
/** normalize a normal **/int normalize(Vertex3 *normal){ double length=getLength(normal); if (length != 0) { normal->x = (float)(normal->x / length); normal->y = (float)(normal->y / length); normal->z = (float)(normal->z / length); } return 0;}/** return the length of a vector **/double getLength(Vertex3 *vector){ return (double)sqrt(pwr(vector->x, 2) + pwr(vector->y, 2) + pwr(vector->z, 2));}
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement