简体   繁体   中英

Detect if a vector2 is between two other vector2

as the title suggests I am trying different ways but without solving. I would need to check if the mouse is between two 2d points in PlayMode. I thought of using rect to build a rectangle between two vector2 on the fly and check with rect.contains if the mouse position is inside the rectangle. This works if the rectangle is horizontal but the points on the screen are not aligned and it does not seem to me that there is a way to create an oblique rectangle. I tried to calculate the distance between the two points, to create the rectangle and to move its center to rotate it but it doesn't seem to work. Also it seems that there is no way to display the rectangle on the screen and therefore it is difficult to understand if it retains its original shape after changing some parameters. Do you have any suggestions? But I need the detection area to be rectangular and not on a single line. Using LineCast it is possible to solve but the detected area is too narrow.

I thought of a rectangle between the two vectors. Imagine a one-pixel line connecting the two vectors. Now increase the thickness of the line up to 10/20 pixels so that the mouse is detected a little before and a little after the original line. Maybe I'm wrong but I see the new rect as a good solution but as far as I looked at all its properties I can't understand how to build it between two vectors without too many lines of code.

You can do some vector math to:

  1. Determine if the test point is not "outside" of the two points.

  2. Calculate the distance from the line segment your point is, and if that's equal or below some threshold, then consider it to be "near" the segment between the two points.

  3. If it's "near" the segment and not "outside" the two points, then consider it to be "between" the points.

For example:

Vector3 point1 = new Vector2(10f, 10f);
Vector3 point2 = new Vector2(50f, 50f);
float closeThreshold = 5f;

Vector3 testPoint = new Vector2(20f, 21f);

Vector3 segmentDirection = (point2-point1).normalized;
Vector3 point1ToTest = testPoint - point1;
Vector3 testToPoint2 = point2 - testPoint;

// determine if testPoint is not "outside" the points
if (       Vector3.Dot(segmentDirection, point1ToTest.normalized) >= 0f
        && Vector3.Dot(segmentDirection, testToPoint2.normalized) >= 0f)
{
    Vector3 closestPointOnSegment = point1 
            + segmentDirection * Vector3.Dot(point1ToTest, segmentDirection);

    // determine if testPoint is close enough to the line segment point1->point2
    if ((closestPointOnSegment - testPoint).magnitude <= closeThreshold)
    {
        // testPoint is "between" point1 and point2
    } 
}

This will work with Vector3 or Vector2 , which will safely convert to Vector3 as shown above.


If you are only concerned with if the point is exactly between the two positions, take the directions from the point you're testing to either end of the line, and if the dot product between those directions is -1, then the point is between them:

Vector3 point1 = new Vector2(-1f,-1f);
Vector3 point2 = new Vector2(1f,1f);

Vector3 testPoint = new Vector2(0f,0f);

Vector3 testTo1 = (point1-testPoint).normalized;
Vector3 testTo2 = (point2-testPoint).normalized;

if (Mathf.Approximately(-1f, Vector3.Dot(testTo1, testTo2)))
{
    // testPoint is between point1 and point2
}

This will work with Vector3 or Vector2 , which will safely convert to Vector3 as above.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM