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\$
2
  • \$\begingroup\$ What exactly do you mean by in front of? Dead ahead? forward of abeam? In the front quarter? \$\endgroup\$ Commented Mar 12, 2015 at 2:39
  • \$\begingroup\$ Move your problem to origin then. It is just a vec substraction. \$\endgroup\$
    – wondra
    Commented Mar 12, 2015 at 7:43

4 Answers 4

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\$
3
  • \$\begingroup\$ Why does everybody always start by redundant calculation of angles? \$\endgroup\$
    – wondra
    Commented Mar 12, 2015 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\$ Commented Mar 12, 2015 at 20:41
  • \$\begingroup\$ I did not downvote you, I only pointed out your solution can be considered as bad practise. \$\endgroup\$
    – wondra
    Commented Mar 13, 2015 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\$
3
  • \$\begingroup\$ And how does this differ from already posted answers? The code looks identical to Jason's. \$\endgroup\$
    – wondra
    Commented Mar 12, 2015 at 13:24
  • \$\begingroup\$ I'm just trying to explain what is happen behind the scene. \$\endgroup\$
    – Johann HA
    Commented Mar 13, 2015 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
    Commented Mar 13, 2015 at 13:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .