简体   繁体   中英

how to find a point(vector2) between two points(Vector2) of a line (line renderer)

As the question explains, how to find a point(vector2) between two points(Vector2) of a line (line renderer),

例子

I am using a line renderer to draw the line with two points (start with vector and endpoint), what I want is that want point A in the line as you can see in the image.

In theory, I want to shorten the line from the original length for my use case, I am doing a line intersection check for two lines overlapping, but the problem is that in some cases the lines start from the same point, and in those situations, if the points meet, it still counts as a line intersection. So in theory I want to shorten the line for line intersection check so it doesn't intersect with the other line if the points meet.

Here is the script for my line intersection check!

  public bool isIntersecting = false;
  LineRenderer lineRenderer;
 
     private void Start()
     {
         lineRenderer = this.GetComponent<LineRenderer>();
     }
 
     private void Update()
     {
         LineRenderer recievedLine;
         if (FindObjectOfType<LineDynamics>().ropeRenderer != null)
         {
             recievedLine = FindObjectOfType<LineDynamics>().ropeRenderer;
         }
         else
         {
             return;
         }
 
         AreLineSegmentsIntersectingDotProduct(lineRenderer.GetPosition(0), lineRenderer.GetPosition(lineRenderer.positionCount - 1), recievedLine.GetPosition(0), recievedLine.GetPosition(recievedLine.positionCount - 1));
     }
 
     //Line segment-line segment intersection in 2d space by using the dot product
     //p1 and p2 belongs to line 1, and p3 and p4 belongs to line 2 
     public bool AreLineSegmentsIntersectingDotProduct(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4)
     {
 
         if (IsPointsOnDifferentSides(p1, p2, p3, p4) && IsPointsOnDifferentSides(p3, p4, p1, p2))
         {
             isIntersecting = true;
         }
         else
         {
             isIntersecting = false;
         }
 
         return isIntersecting;
     }
 
     //Are the points on different sides of a line?
     private bool IsPointsOnDifferentSides(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4)
     {
         bool isOnDifferentSides = false;
 
         //The direction of the line
         Vector2 lineDir = p2 - p1;
 
         //The normal to a line is just flipping x and z and making z negative
         Vector2 lineNormal = new Vector2(-lineDir.y, lineDir.x);
 
         //Now we need to take the dot product between the normal and the points on the other line
         float dot1 = Vector2.Dot(lineNormal, p3 - p1);
         float dot2 = Vector2.Dot(lineNormal, p4 - p1);
 
         //If you multiply them and get a negative value then p3 and p4 are on different sides of the line
         if (dot1 * dot2 < 0f)
         {
             isOnDifferentSides = true;
         }
 
         return isOnDifferentSides;
     }

Any suggestion and help will be appreciated.

To your question

You could eg use Vector2.Lerp in order to get any point between your start and end point given a factor between 0 and 1 where

  • 0 : equal to start point
  • 1 : equal to end point
  • {0;1} : equal to linear interpolation between start and end

For the center it would eg be

var center = Vector2.Lerp(startPosition, endPosition, 0.5f);

If you rather need a certain travel distance from the start point you could use Vector2.MoveTowards like

var otherPoint = Vector2.MoveTowards(startPoint, endPoint, desiredDistanceFromStartPoint);

Basically you also can go fully manual and basically do the same like

var direction = (endPoint - startPoint).normalized;
var otherPoint = startPoint + direction * desiredDistanceFromStartPoint;

This however, doesn't protect you from overshooting the endPoint.


Ton your actual problem

You know that there is already functions implemented by the Unity community long ago under Wiki - Math functions which already provides eg

//Calculate the intersection point of two lines. Returns true if lines intersect, otherwise false.
//Note that in 3d, two lines do not intersect most of the time. So if the two lines are not in the 
//same plane, use ClosestPointsOnTwoLines() instead.
public static bool LineLineIntersection(out Vector3 intersection, Vector3 linePoint1, Vector3 lineVec1, Vector3 linePoint2, Vector3 lineVec2){

    Vector3 lineVec3 = linePoint2 - linePoint1;
    Vector3 crossVec1and2 = Vector3.Cross(lineVec1, lineVec2);
    Vector3 crossVec3and2 = Vector3.Cross(lineVec3, lineVec2);

    float planarFactor = Vector3.Dot(lineVec3, crossVec1and2);

    //is coplanar, and not parrallel
    if(Mathf.Abs(planarFactor) < 0.0001f && crossVec1and2.sqrMagnitude > 0.0001f)
    {
        float s = Vector3.Dot(crossVec3and2, crossVec1and2) / crossVec1and2.sqrMagnitude;
        intersection = linePoint1 + (lineVec1 * s);
        return true;
    }
    else
    {
        intersection = Vector3.zero;
        return false;
    }
}

//Two non-parallel lines which may or may not touch each other have a point on each line which are closest
//to each other. This function finds those two points. If the lines are not parallel, the function 
//outputs true, otherwise false.
public static bool ClosestPointsOnTwoLines(out Vector3 closestPointLine1, out Vector3 closestPointLine2, Vector3 linePoint1, Vector3 lineVec1, Vector3 linePoint2, Vector3 lineVec2){

    closestPointLine1 = Vector3.zero;
    closestPointLine2 = Vector3.zero;

    float a = Vector3.Dot(lineVec1, lineVec1);
    float b = Vector3.Dot(lineVec1, lineVec2);
    float e = Vector3.Dot(lineVec2, lineVec2);

    float d = a*e - b*b;

    //lines are not parallel
    if(d != 0.0f){

        Vector3 r = linePoint1 - linePoint2;
        float c = Vector3.Dot(lineVec1, r);
        float f = Vector3.Dot(lineVec2, r);

        float s = (b*f - c*e) / d;
        float t = (a*f - c*b) / d;

        closestPointLine1 = linePoint1 + lineVec1 * s;
        closestPointLine2 = linePoint2 + lineVec2 * t;

        return true;
    }

    else{
        return false;
    }
}   

And as said if your concern is actually the start point being equal for two lines (very unlikely) doing 50 Vector3 == checks is very cheap compared with the rest of calculations you are doing anyway.

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