Jump to content
  • Advertisement
Sign in to follow this  
PY_Sheo

3D Ray-Plane Intersection Assistance

This topic is 2810 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying to test whether the direction a player is looking intersects with a side of a cube when he left clicks. After reading many articles online and implementing a few tutorials, I cannot understand why the following code won't work. Any help is appreciated.

(I understand the code organization is horrible)


public static boolean sideIntersectsView(BlockSide s)
{
float x1 = s.vectors[0].x;//QUAD POINT 1
float y1 = s.vectors[0].y;
float z1 = s.vectors[0].z;

float x2 = s.vectors[1].x;//QUAD POINT 2
float y2 = s.vectors[1].y;
float z2 = s.vectors[1].z;

float x3 = s.vectors[2].x;//QUAD POINT 3
float y3 = s.vectors[2].y;
float z3 = s.vectors[2].z;

float x4 = s.vectors[3].x;//QUAD POINT 4
float y4 = s.vectors[3].y;
float z4 = s.vectors[3].z;

float A = y1*(z2-z3) + y2*(z3-z1) + y3*(z1-z2);//PLANE
float B = z1*(x2-x3) + z2*(x3-x1) + z3*(x1-x2);
float C = x1*(y2-y3) + x2*(y3-y1) + x3*(y1-y2);
float D = -x1*(y2*z3 - y3*z2) - x2*(y3*z1 - y1*z3) - x3*(y1*z2 - y2*z1);

float x0 = Player.xpos;//RAY ORIGIN
float y0 = Player.ypos;
float z0 = Player.zpos;

float f1 = (float) -Math.cos(-Player.yrot * 0.01745329F - 3.141593F);
float f3 = (float) Math.sin(-Player.yrot * 0.01745329F - 3.141593F);
float f5 = (float) -Math.cos(-Player.xrot * 0.01745329F);
float f7 = (float) Math.sin(-Player.xrot * 0.01745329F);

float xd = f3*f5;
float yd = f7;
float zd = f1*f5;

Vector Rd = new Vector(xd, yd, zd);//RAY DIRECTION

float t = -(A*x0 + B*y0 + C*z0 + D) / (A*xd + B*yd + C*zd);

if (t < 0.0f)
{
return false;
}

Vector intersection = new Vector(x0 + Rd.x*t, y0 + Rd.y*t, z0 + Rd.z*t);

Vector V1 = new Vector(x2-x1, y2-y1, z2-z1).normalize();
Vector V3 = new Vector(x4-x3, y4-y3, z4-z3).normalize();
Vector V4 = new Vector(intersection.x-x1, intersection.y-y1, intersection.z-z1).normalize();
Vector V5 = new Vector(intersection.x-x3, intersection.y-y3, intersection.z-z3).normalize();

float V1DotV4 = V1.getDotProduct(V4);
float V3DotV5 = V3.getDotProduct(V5);

if (V1DotV4 >= 0.0f && V3DotV5 >= 0.0f)//IF POINT IS ON PLANE AND IN QUAD
{
return true;
}

return false;
}

Share this post


Link to post
Share on other sites
Advertisement
What kind of results are you getting?
From your Approach I'm guessing your Quads aren't rectengular?


From what I see, everything up to Intersection (at least the Idea, haven't checked the Math a 100%) looks good.
The last Part is (if your Quads are Rectengular) incomplete => You'd need to check the other 2 sides too, but I'd use a completely different Method for this.
If your Quads can be any shape, then it's wrong => There can be cases when the "Intersection" Point is in a Trapezoid for example, and still return a negative Cosine.

Share this post


Link to post
Share on other sites

What kind of results are you getting?
From your Approach I'm guessing your Quads aren't rectengular?


From what I see, everything up to Intersection (at least the Idea, haven't checked the Math a 100%) looks good.
The last Part is (if your Quads are Rectengular) incomplete => You'd need to check the other 2 sides too, but I'd use a completely different Method for this.
If your Quads can be any shape, then it's wrong => There can be cases when the "Intersection" Point is in a Trapezoid for example, and still return a negative Cosine.


I seem to be receiving random output. Sometimes it will return a value correctly then I can click again and it won't. For right now I just want it to work with rectangular quads as I can expand upon this later. What method do you suggest for a rectangular quad?

Share this post


Link to post
Share on other sites
I'd recommend that before you try to figure out why the intersection test isn't working, you clean up your code a bit, as that will make it a lot easier to debug. A few tips:

- You're writing out a lot of operations 'by hand' that could be more clearly expressed using overloaded operators or named functions. (Just to provide a few examples, the dot product and cross product should be named functions, and arithmetic operations other than multiplication involving vectors should generally be implemented as overloaded operators.)

- Rather than 'magic numbers' such as 0.01745329F, used named constants, e.g. DEG_TO_RAD.

- Instead of using multipliers like DEG_TO_RAD to perform conversion between radians and degrees, use functions instead, e.g. DegToRad().

- It looks like you're performing an Euler- or spherical-angle conversion to yield the forward vector. It's likely you're duplicating work here that's already been done elsewhere. (Presumably there's a transform matrix associated with the object; if so, you already have the forward vector and needn't compute it again here.)

- Stuff like the Euler-angle conversion should really be factored out for easier testing and debugging.

Basically, the code needs a lot of refactoring. Once you've done that, I think you'll find it'll be a lot easier to debug and get working correctly.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!