Game Development Community

How to verify if a point lies between 2 vectors?

by Brandon Fogerty · in Technical Issues · 02/13/2008 (2:01 pm) · 9 replies

How do you verify if a point lies between 2 vectors?

If I have 2 2d vectors and a 2d point, how can I know that the point lies between the 2 vectors like in a radar view system?

Thanks in advance!

#1
02/13/2008 (2:19 pm)
I assume both vectors have a common start point.

Try checking the dot product from each vector against the vector to the point (shared vector start to point). The dot product will tell you which side of the vector the point lies on returning a positive or negative result.

If the correct one is positive and the other is negative the point lies between the two vectors.

Gabriel
#2
02/13/2008 (3:46 pm)
It's the cross product you need to determine which side a point is from a given vector.

Dot product can be used to determine if two vectors are perpendicular or separated by less then 90deg (when positive signed) amongst other uses.

Other than using cross product, do just what Gabriel says.
#3
02/14/2008 (12:23 am)
He was asking about 2d vectors.

Cross product is 3d operation that returns another 3d vector which is perpendicular to the plane defined by the two other vectors. It does not have a 2d equivalent.

The dot product is the cosine of the angle between two vectors. In this case each of the side vectors and the vector to the point.

Gabriel
#4
02/14/2008 (4:59 am)
Gabriel: Cross is defined for 3d use, but it can be used with 2d vectors by setting the Z value of both vectors to 0. The Z value of the resulting cross is then sign sensitive based upon the side one vector is of the other.

There's an example of this on page 42-44 of the "Mathematics for Game Developers" book. I tried to find this on-line however, as is typical, the look-inside feature does not have the relevant page. There is a further reference to this method in the book though on page 112-113

Maths for Game Developers Google Look-Inside

First half of the second paragraph p113 talks about the determinants sign (E.G the Z component).

It would seem the dot product can also be used though, as mentioned by the second half of the paragraph on p113. Which means I'm misunderstanding something about the dot product and would appreciate it if you could help clear this up. Without hijacking the original thread too much :)

Doesn't the sign of the dot product only tell you that the two vectors are separated by less than 90deg when positive?

If so, wouldn't the use of the dot product fail if the two side angles were separated by for example, 45deg. As a point just to the left of the left side vector (sideA) could still be <90 from both sideA and sideB and yet is not within the two sides.

I can see how the cross product would achieve the desired result, as it can be used given just a single vector and a point to determine what side the point lies on the vector, which is easily extended to two tests on two vectors to determine if it's within or outside the two vectors. But, I cannot see how this is possible with the dot product?
#5
02/14/2008 (6:04 am)
You could use either the dot product or the cross product.

Like Gabriel said, the dot product is proportional to the cosine of the angle between the two vectors.
The Z component of the cross product is proportional to the sine of the angle between the two vectors.
And a cosine is just a sine with a different phase, so if you rotate one of your vectors by pi/2 and then look at the sign of the dot product, that's exactly the same as doing a cross product.

Rotating your vector isn't free though, so the cross product approach is slightly more efficient. Only slightly though, because on modern hardware the real bottleneck is in going from a vector register to a scalar register, which would happen in both cases, assuming that your code is optimized and using vector hardware properly.
#6
02/14/2008 (9:01 am)
I would just like to jump in here and say that Point3F/Point2F are not aligned data types, and so what Hadoken is talking about, regarding vector hardware, is true, and there is a hit. There is work that has been done on data alignment and type-unions with __mm128 and __vector4.

That being said, Torque/Torque2d do many, many dot products etc per frame, so don't shy away from using the solution. Also, reading this thread has made me feel warm and fuzzy inside. I like math.
#7
02/14/2008 (9:16 am)
For a radar system (assuming P0 is the center and P1 is the outer vector that moves/rotates around P0):
-find the distance of P0 to P1 => this gives you radius from the center that makes a circle:
radar_radius = (P1 - P0).distance(); (or .lenght() or .magnitude(), depending on what you have in your vector2d class)

-find the distance from P0 to Px:
distance = (Px - P0).distance();

-if distance <= radar_radius then the Px is within the radar circle

It may be easier to define a radar as having a center vector point and a radius to eliminate a need to recalculate radar_radius every frame.

edit: corrected typo
#8
02/14/2008 (9:27 am)
I apologize. I should have worded the problem better. I drew a picture for you to see what I am talking about.

http://www.brandonfogerty.com/theory/radar_scan.JPG

Does that help?
#9
02/14/2008 (11:07 pm)
If that's the case then you can do something like what's shown below. Assume V1 and V2 share a common point at P0, and P1 and P2 can be found at ends of V1 and V2, respectively.

// find the normal of the triangle, using right hand rule
vector2 n = cross( V2, V1 );

// find the third edge, V3, from P2 to P1 (it's the green line from end of V2 to V1)
vector2 V3 = P1 - P2;

// test and see if the point, Px, is inside all three edges
// here is the first test against V2
if ( dot( n, cross( V2, ( Px - P0 ) ) ) < 0 ) then it's outside the triangle

// repeat two other edge tests and if all three tests pass then the point is inside the triangle