0
\$\begingroup\$

I need to figure out whether a point is infront or behind my vehicle.

I have the vector of it's position, forward direction.

So far I have tried finding the vector perpendicular to its forward direction and then calculating what side of the line it is positioned on.

This works fine at first. But then I realised it is only calculating around the origin.

bool Car::isInfront(ngl::Vec2 _pos)
{
//http://stackoverflow.com/questions/1243614/how-do-i-calculate-the-normal-vector-of-a-line-segment

//if we define dx=x2-x1 and dy=y2-y1, then the normals are (-dy, dx) and (dy, -dx).

//create vector per to the direction of travel.
ngl::Vec2 fwdVec = m_carPhysics->getForwardVec2();
ngl::Vec2 pos = m_carPhysics->getPosVec2();

ngl::Vec2 dir = pos + fwdVec;


float dx = dir.m_x - pos.m_x;
float dy = dir.m_y - pos.m_y;

ngl::Vec2 v1(-dy, dx);
ngl::Vec2 v2(dy, -dx);

ngl::Vec2 perp = (v1) - (v2);


int turn = getLeftOrRight(_pos, perp);


if(turn == LEFT)
{
    return true;
}
else
{
    return false;
}

int Car::getLeftOrRight(ngl::Vec2 _dir, ngl::Vec2 _fwd)
{
//http://gamedev.stackexchange.com/questions/34536/calculating-angle-between-two-vectors-to-steer-towards-a-target
//cross product;
float val = (_dir.m_x * _fwd.m_y) - (_dir.m_y * _fwd.m_x);

if(val > 0)
{
    return LEFT;
}
else
{
    return RIGHT;
}

}

\$\endgroup\$
  • \$\begingroup\$ What exactly do you mean by in front of? Dead ahead? forward of abeam? In the front quarter? \$\endgroup\$ – Pieter Geerkens Mar 12 '15 at 2:39
  • \$\begingroup\$ Move your problem to origin then. It is just a vec substraction. \$\endgroup\$ – wondra Mar 12 '15 at 7:43
0
\$\begingroup\$

The idea is right, the execution however is chaotic.
First of all "So far I have tried finding the vector perpendicular to its forward direction", you already seem to know the trick - swaping x,y and inverting one axis, but why you apply it to some random products of calculations?

bool Car::isInfront(ngl::Vec2 _pos)
{
ngl::Vec2 fwdVec = m_carPhysics->getForwardVec2();
ngl::Vec2 perp = vec2(-fwdVec.y, fwdVec.x);

Second: "But then I realised it is only calculating around the origin.", there is nothing easier than moving your problem to origin - by using relative position to your car(just substract its position).

return getLeftOrRight(_pos - m_carPhysics->getPosVec2(), perp);
}

...and that is all code you need. Judging from comments you originally wanted 45deg slice, and you were probably on the right track there too - just be aware it might require chcecking against both vectors v1(-fwd.y,fwd.x) and v2(fwd.y,-fwd.x) (if you think about it, point in 45 slice must be right of forward-left bound AND left of forward-right boundary).

\$\endgroup\$
1
\$\begingroup\$

If two vectors point in the same direction, then their dot product is positive. If the point in opposite directions, there dot product is negative. If they are perpendicular, the dot product is zero. All we need to do is compare a vector from the car to the point and the car's forward vector:

bool Car::isInfront(ngl::Vec2 _pos)
{
  ngl::Vec2 fwdVec = m_carPhysics->getForwardVec2();
  ngl::Vec2 pos = m_carPhysics->getPosVec2();
  ngl::Vec2 dir = _pos - pos;
  return (dir.x * fwdVec.x + dir.y * fwdVec.y) >= 0; // dot product
}
\$\endgroup\$
-1
\$\begingroup\$

In simple terms, there are two steps you'll need to take:

  1. Calculate the angle between the vehicle's position and the point's position.

  2. Compare that angle to the angle the vehicle is facing (the angle of the vehicle's forward vector).

More specifically...

Step 1 is easy: subtract one vector from the other, and use a trig function (often called something like "atan" or "atan2" in most programming languages) to turn that new vector into an angle.

For step 2, there are a couple of ways to approach this. The simplest would just be to subtract one angle from the other, and take the absolute value of it (example: abs(60 degrees - 90 degrees) = 30 degrees), and then check whether it's under some threshold you define. A threshold of 45 degrees might be a good starting point. A higher threshold will be more generous, while a low threshold will require the vehicle to be facing directly toward the point.

\$\endgroup\$
  • \$\begingroup\$ Why does everybody always start by redundant calculation of angles? \$\endgroup\$ – wondra Mar 12 '15 at 8:25
  • \$\begingroup\$ @wondra Nice downvote, how obnoxious. This answer works and is correct. I figured this was obvious and didn't need to be stated, but I intentionally calculated the angles to illustrate to the OP what the trigonometry represents. \$\endgroup\$ – Josh1billion Mar 12 '15 at 20:41
  • \$\begingroup\$ I did not downvote you, I only pointed out your solution can be considered as bad practise. \$\endgroup\$ – wondra Mar 13 '15 at 13:50
-1
\$\begingroup\$

I get a simple geometry trick that will solve you problem. You actually have the position and the direction of the vehicle. So, with that information you can construct a plane. If vector position

(Px,Py,Pz)

and forward direction is

(Dx,Dy,Dz)

and the object´s position to check is

(Ox,Oy,Oz)

well, you plane's formula is:

Dx*(Ox - Px) + Dy*(Oy - Py) + Dz*(Oz - Pz) = P

If P is positive, the object is in front. If P is equal to zero, your vehicle and the object are in the same position. If P is negative, the object is behind. So your code looks like:

bool Car::isInfront(ngl::Vec2 _pos)
{
    ngl::Vec2 fwd = m_carPhysics->getForwardVec2();
    ngl::Vec2 pos = m_carPhysics->getPosVec2();
    return fwd.x*(_pos.x - pos.x) + fwd.y*(_pos.y - pos.y) + fwd.z*(_pos.z - pos.z) > 0;
}
\$\endgroup\$
  • \$\begingroup\$ And how does this differ from already posted answers? The code looks identical to Jason's. \$\endgroup\$ – wondra Mar 12 '15 at 13:24
  • \$\begingroup\$ I'm just trying to explain what is happen behind the scene. \$\endgroup\$ – Johann HA Mar 13 '15 at 9:12
  • \$\begingroup\$ If you wanted to explain how the math works, you should explain it. You just said it is a plane and then magic happend. \$\endgroup\$ – wondra Mar 13 '15 at 13:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.