Sign in to follow this  
Ashandir

Math help, is object ahead or behind me

Recommended Posts

I am pretty noob at 3d math. I am controlling a 3d object that starts an animation when a vehicle pulls up next to it. Right now I have it working so it only starts the animation if the vehicle pulls up to it and is between 2-5 feet away with the same heading. Problem is that u can be 2-5 feet away and have same heading as the object and not really be next to it. So I need some math to make sure that when you pull up next to object you are right next to it. IGNORE "0"s they are just there so it semi formats correctly Object 00 Vehicle ****** 00 ****** ****** 00 ****** ****** 00 ****** ****** 00 ****** ****** 00 ****** ****** 00 ****** ****** 00 ****** so this is a picture of vehicle parked correctly. The top line would be its heading. So as long as vehicle has same heading and is correct distance its fine. Problem is below Object ****** ****** 00 Vehicle ****** 00 ****** ****** 00 ****** ****** 00 ****** ****** 00 ****** ****** 00 ****** 000000 000 ****** 000000 000 ****** This image evaluates true with my current logic so object starts animating but should not because vehicle is behind it and not right next to it. So i am pretty sure there is math that can look at its heading and x, y, z and figure out if its directly next to it. I just don't know enough about math so that is where I need your help. Z is the up axis. So if you can explain how to do this or have some sample code that would help a ton. Thanks

Share this post


Link to post
Share on other sites
Hope I understood your question... you want to check if the objects are exactly next to each other right?!

Don't know how much you know about plane maths (Wikipedia link) - you should understand the basics before you can understand my solution.

I assume each object has a vector containing the direction, and a point containing the "nose" (or the tail, however it will be used to compare the same point on each object).

You can then create a plane of A's nose/direction. This plane will be orthogonal to A's direction. Now check if B is on the plane - if yes, the objects are next to each other.

Some pseudocode:

bool NextToEachOther(Vector3 aNose, Vector3 aDirection, Vector3 bNose, Vector3 bDirection)
{
// you can find Plane code on the Internet
// Basically it's a formulae that is true for all points (x,y,z)
// 0 = ax + by + cz + d
Plane p(aNose, aDirection);

if(aDirection != bDirection) return false;

return (p.a*bNose.x + p.b*bNose.y + p.c*bNose.z + p.d) == 0;
}




Hint: Of course, my solution does only succeed if the direction is the same! Slightly different directions won't work. You can avoid this by replacing the last two lines with:


// Return true if it is exactly on the plane. If we skipped this line,
// the return statement would do a divide-by-zero.
if((p.a*bNose.x + p.b*bNose.y + p.c*bNose.z + p.d) == 0) return true;

// This will calculate the distance point<->plane, look at wikipedia
// We use it as a "tolerance" value: If the distance is less-equal 0.1, we assume the objects are roughly next to each other
return abs(p.a*bNose.x + p.b*bNose.y + p.c*bNose.z + p.d) / sqrt(bNose.x*bNose.x+bNose.y*bNose.y+bNose.z*bNose.z) <= 0.1;





P.S. WTF is Z the up axis :D ... doesn't matter anyway

Share this post


Link to post
Share on other sites
I'll assume you are working in the +X forward (north), +y right (east), +z up coordinate system, which is left handed. Your solution depends on what you really want to know. I don't quite get a full picture about what you want. Hopefully some tips will help you figure it out.

You can calculate the bearing to the vehicle by taking the normal of the veh's position minus the object's position. The normal of this vector will produce a 3D vector, but you may want to only know the angle off north or angle off up axis, etc. As a normalized vector, it is a direction cosine vector. In other words, each element of the vector represents the cosine of the angle along an axis. If the vector is (1, 0, 0), the vector lies completely north, and the cosine of 0 degrees is 1.0. Thus, the X element is the cosine of the angle.

To find the angle, just take the arccos of the element's value. If it is directly east, the vector (0, 1, 0) would have a Y value of 1.0, which means the vector lies 0 degrees (arccos(1.0)) off of the Y axis. The real trick is that you don't need to take the arccos at all. Just decide how far off of the axis will be acceptable, take the cosine of that value and make it a constant in your code. Then compare it to the element you are testing of your normalized vector. Here's an example.

Vehicle is at (0, 10, 0). Object is at (0, 0, 0). Normal direction cosine vector is (0, 1, 0). You can see that the object is exactly to the left of the vehicle.

Vehicle is at (1, 10, 0). Object is at (1, 0, 0). Normal is the same (0, 1, 0).

Vehicle is at (2, 10, 0). Object is at (1, 2, 0). Direction vector is (1, 8, 0), and normal is (0.124, 0.992, 0). Your angle off of the north axis (X) is arccos(0.124) = 82.8 deg, angle off of the east axis (Y) is arccos(0.992) = 7.25 deg. Note they add up roughly to 90 degrees, which means the math is correct because our z difference is 0.

What you seem primarily interested in here is the angle off the east axis (think about it). Remember it's the angle in any direction off the east axis, so it makes a cone. You can just add a check to your code to start the animation anytime the object is within 2 degrees of the object off of the east axis (2 degrees in either +Y or -Y direction, making a cone to the right and a cone to the left).

So, in practice:

vector3 veh, obj; // You know these.

vector_3 diff = veh - obj;
vector_3 normal = diff/(sqrt(diff.x*diff.x + diff.y*diff.y + diff.z*diff.z));

// Have to take absolute because you want to check 2 degrees in both directions along the Y axis.
if (fabs(normal.y) >= 0.99939) // cos(2) = 0.99939
start animation;

This produces a cone along the -Y and +Y axes with an angle of 2 degrees that the vehicle can lie within with respect to the object. Don't forget to check the distance in there too.

Hope this helps,
Chris

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this