- Home /
Check if point is between two Vectors
I need to figure out if a point is within an area defined by two Vectors in 2D-Space.
For example, I have two directional Vectors and a starting point A. I need to check if another point B is within the red area between the two vectors. So in the image above, checking for point B should return true, while Point C and D should return false.
Unfortunately, I have no idea where to start. Any suggestions or math libraries that could help with that?
Answer by Bunny83 · May 31, 2019 at 05:09 PM
Note that the way you've drawn your vectors it's not clear where they start in space. Vectors generally start at 0,0.
"Between two vectors" can also be interpreted in multiple ways. It could mean either between the smaller angle of the vectors or between the larger angle of the two vectors. If you always want to know if it's in the smaller angled region just do
float angleArea = Vector3.Angle(V1, V2);
if (Vector3.Angle(V1, P) < angleArea && Vector3.Angle(V2,P) < angleArea)
{
// P is inside the area between V1 and V2
}
This assumes that vectors V1, V2 and P actually start at the same point (0,0). If you you have V1 and V2 already as direction vectors but have the point P in world coordinates you have to subract the starting point from P
If you want to know if it's in the larger area, just inverse the condition like this:
if (Vector3.Angle(V1, P) > angleArea || Vector3.Angle(V2,P) > angleArea)
or this
if (!(Vector3.Angle(V1, P) < angleArea && Vector3.Angle(V2,P) < angleArea))
Besides those two interpretations it's also possible to define an area that always starts at the first vector (for example the one that's pointing up) and the area always expands counter clockwise (or clockwise) to the second vector you would do something like this:
float range = Vector3.SignedAngle(V1, V2, Vector3.forward);
if (range < 0)
range += 360f;
float a1 = Vector3.SignedAngle(V1, P, Vector3.forward);
if (a1 < 0)
a1 += 360f;
float a2 = Vector3.SignedAngle(P, V2, Vector3.forward);
if (a2 < 0)
a2 += 360f;
if (a1 < range && a1 < range)
{
// P is between V1 and V2
}
Note that this second solution depends on the order you use V1 and V2. If you swap the two vectors you essentially test for the opposite area. While the first solution works in any arbitrary 2d plane in 3d space, this solution assumes the x-y plane (since we use Vector3.forward as reference normal).
I guess one could also divide vX
elementvise by Vector3.Project(A-B,v)-A
and check the sign. If all signs are positive for v1 and v2 then the point should be in the red area.
i guess this should work without limitations to 2D or 3D, but might be slower in performance than your solutions.
I think I got a similar idea like you had, however that wouldn't really work as you would use each vector essentially as a normal that defines a half space. Though the overlapping area of those two halfspaces would not be that red area. It would work if we used the "normals" of those vectors. Though we would need to use the clockwise normal for V1 and the counter clockwise normal for V2. Note that this approach would only work for angles <180°. If you go larger you get strange results
var tmp = Vector3.Cross(V1, V2-V1);
var n1 = Vector3.Cross(tmp, V1);
var n2 = -Vector3.Cross(tmp, V2);
var p = point - A;
if (Vector3.Dot(n1, p) > 0 && Vector3.Dot(n2, p) > 0)
// inside
The pure 2d case is slightly simpler since to get the normal of a vector in the 2d plane you just swap the two coordinates and invert one
var n1 = new Vector2(V1.y, -V1.x); // clockwise normal
var n2 = new Vector2(-V2.y, V2.x); // counter clockwise normal
var p = point - A;
if (Vector2.Dot(n1, p) > 0 && Vector3.Dot(n2, p) > 0)
// inside
The yellow area is the halfspace of n1 while the green area is the halfspace of n2. Of course the orange is the overlapping area that we're looking for. In the end it's not that much different from my first angle based approach. You just save the Acos calls inside Vector3.Angle. Though this one requires a certain order of the two vectors. If you swap them you get the white area at the bottom ins$$anonymous$$d.
Thanks, that's exactly what I needed! I was talking about the smaller angled area, so the first answer should work.
Your answer
Follow this Question
Related Questions
How to get vector X distance from point on Y angle? 4 Answers
[RESOLVED] Raycast - Calculate Angular Difference from Object 3 Answers
Maths: Given a point on a circle and a fixed length line. Find the next closest point on the circle. 2 Answers
Vector2 scalar multiplication issue 1 Answer
Dotted line bouncing on Unity 0 Answers