Plane/point math problems

I’m having some issues with some math in my code, and am totally stuck. Here is my cry for help!

Problem:

I have a point in space, and a sphere. The sphere moves, the point in space [at this point] does not. What I need, is to know if any of the tris on this sphere, are facing the point. Note, I’m calculating this every frame, and the sphere could move anywhere in the world.

My Approach So Far:

For every face [tri] of this sphere, I am calculating a plane. (foot#1 for code). After calculating this plane for every face, I test each plane for being ‘facing’ the point or not (foot#2 for code). I am testing to see results, by coloring the tris different colors if they are facing or not.

The problem:

This doesn’t seem to work really at all. I get a few positives, but they don’t make sense at all really, and they don’t change when I move my sphere around.

I got the general idea of this from an article on nvidia’s developer site, the code they use looks something like this (foot #3), but the variable names they are using don’t seem to make a lot of sense to me.

Thanks very much in advance to anybody that can respond to this.

// footnote #1
// calculating a plane from the verts
// of the 3 verticies that form a face
// NOTE
// the 3 verticies being passed, are the
// local values I am keeping for this
// object in memory, NOT their position
// in world coordinates, maybe this is
// a problem??
void Plane::calculate (float t1[3], float t2[3], float t3[3]) {
float v0[3];float v1[3];float cr[3];float k;
v0[X] = t2[X] - t1[X];
v0[Y] = t2[Y] - t1[Y];
v0[Z] = t2[Z] - t1[Z];
v1[X] = t3[X] - t1[X];
v1[Y] = t3[Y] - t1[Y];
v1[Z] = t3[Z] - t1[Z];
cr[X] = v0[Y] * v1[Z] - v0[Z] * v1[Y];
cr[Y] = v0[Z] * v1[X] - v0[X] * v1[Z];
cr[Z] = v0[X] * v1[Y] - v0[Y] * v1[X];
k = sqrt(cr[X] * cr[X] + cr[Y] * cr[Y] + cr[Z] * cr[Z]);
a = cr[X] / k;
b = cr[Y] / k;
c = cr[Z] / k;
d = - (a * t1[X] + b * t1[Y] + c * t1[Z]);
}

// footnote #2
bool facingplane =
(plane.a * pointposition[X] +
plane.b * pointposition[Y] +
plane.c * pointposition[Z] +
plane.d * 1); //1 being W

// footnote #3
// from infinite shadow volumes.cpp
// © somebody :wink: only relevant parts pasted
//
// NOTE
// what I’m mostly confused about, is how
// ‘olight’ is derived… it seems that
// it comes from 4x4 matrix
// 'object[in my case, the sphere] .get_inverse_transform() [???]
// multiplying light [the point in my case, maybe?] .get_transform() [??], and then
// multiplying the resulting matrix against
// the light source [point in my case]'s location

vec4f olight;

matrix4f ml = object[mindex].get_inverse_transform() * light.get_transform();

ml.mult_matrix_vec(light_position, olight);

object[mindex].apply_transform();

bool facing_light = (( p.a * olight[0] +
p.b * olight[1] +
p.c * olight[2] +
p.d * olight[3] )
>= 0 );

  • Make sure both object coordinates and light position are in the same coordinate system! Your code looks as if you transform the light into object coordinates and the object into world coordinates.
  • Calculate the face normal (cross product, have your coordinate system’s handedness (is that a word ) right!)
  • Calculate the vector from footpoint to light.
  • Normalize(!) both vectors.
  • Dot product of normal and light vector gives the cosine of the angle between the two.
    If the result is < 0 the triangle is facing away from the light, == 0 is edge on, > 0 faces the light.

im not good at math or anything… but as a rule floats/doubles etc… are hard to get exact results with… floats rarely hit exactly 0… maybe define two bounds for zero -.00000000000001 and .0000000000001 for example
then check the result of your calculations against those values…

bool facingplane =
(plane.a * pointposition +
plane.b * pointposition[Y] +
plane.c * pointposition[Z] +
plane.d * 1); //1 being W

Thanks a lot, I got that algorithm working!!! I’ve got a question though, getting a >= on the dot should give me > 0 if it the tri faces the light, but it’s backwords of this… perhaps my normals are backwords ?

That can happen if you have your cross product done in the opposite direction.
If you have to vectors like this

B
|
|
±-----A

and you’re working in a right handed coordinate system then A x B points out of the screen, but B x A points into the screen.

You should strive to have your triangle’s front face winding to be counterclockwise in a right handed coordinate system, then all fits together mathematically.

Do the famous computer graphics aerobics.
Right handed: Thumb is x pointing to the right, forefinger is y pointing up, middle finger is z pointing towards you.
Left handed: Thumb is x pointing to the right, forefinger is y pointing up, middle finger is z pointing away from you.

[This message has been edited by Relic (edited 12-02-2002).]