Unity calculates the shortest distance from a point to a straight line

write in front

During the past two days of development, a friend asked me how to calculate the shortest distance from a point to a straight line. It seemed to have troubled him for a long time, so I took this opportunity to record this problem so that more friends can improve their posture. .

Look at the picture first: the known conditions are as follows, three points p1, p2 and target, find the distance of the red line segment.

Problem-solving ideas

Idea 1: Vector projection method

The core problem of this method is to calculate the point with the shortest distance from the target to the p12 vector, and then calculate the shortest distance through the Vector3.Distance method.

So how to find this point? Here, I used vector projection.

1. First calculate the vector from target to p1 (blue line segment)

2. Then calculate the vector from p2 to p1 (green line segment)

3. Use the Vector3.Project method to calculate the projection of the blue line segment on the green line segment. This projection is the p1F vector.

4. Add the calculated projection vector to the coordinates of point p1, which is the coordinates of point F.

5. Finally, Vector3.Distance(target,F) can calculate the distance

code show as below:

    /// <summary>
    /// 向量投影法
    /// </summary>
    public void ProjectFunc(Vector3 p1, Vector3 p2, Vector3 target)
    {
        //p1->p2的向量
        Vector3 p1_2 = p2 - p1;
        //p1->target向量
        Vector3 p1_target = target - p1;
        //计算投影p1->f
        Vector3 p1f = Vector3.Project(p1_target, p1_2);
        //加上p1坐标 然后计算距离
        float distance = Vector3.Distance(target, p1f + p1);
        Debug.Log("向量投影法:" + distance);
    }

Idea 2: Trigonometric function method

This method is to calculate the distance between the right-angled sides through Sin (included angle) * length of the hypotenuse

1. First calculate the vector from target to p1 (blue line segment)

2. Then calculate the vector from p2 to p1 (green line segment)

3. Calculate the angle between the first two vectors Vector3.Angle(p1_2, p1_target);

4. Get the length of the hypotenuse (blue line segment)

5. Calculate the distance through the Sin function * the length of the hypotenuse

code show as below:

    /// <summary>
    /// 三角函数
    /// </summary>
    public void TriangleFunc(Vector3 p1, Vector3 p2, Vector3 target)
    {
        //p1->p2的向量
        Vector3 p1_2 = p2 - p1;
        //p1->target向量
        Vector3 p1_target = target - p1;
        //前面两个向量的夹角
        float angle = Vector3.Angle(p1_2, p1_target);
        //获取斜边的长度
        float distance_p1_target = p1_target.magnitude;
        //Sin函数计算距离
        float distance = Mathf.Sin(angle * Mathf.Deg2Rad) * distance_p1_target;
        Debug.Log("三角函数法:" + distance);
    }

Idea 3: Area method

This method mainly calculates the distance through the parallelogram area formula: base * height = area

Now we know the length of a base (green line segment), but we still don’t know the area.

Here, you can obtain the module of the cross product result through vector cross product (the result of the cross product is a vector, and the length of the vector is the area of ​​the parallelogram formed by the two cross product vectors)

1. First calculate the vector from target to p1 (blue line segment)

2. Then calculate the vector from p2 to p1 (green line segment)

3. Cross product two vectors, and the result obtained is the length, which is the area of ​​the parallelogram.

4. Then height = area / base to get the distance

code show as below:

    /// <summary>
    /// 叉乘面积
    /// </summary>
    public void CrossAreaFunc(Vector3 p1, Vector3 p2, Vector3 target)
    {
        //p1->p2的向量
        Vector3 p1_2 = p2 - p1;
        //p1->target向量
        Vector3 p1_target = target - p1;
        //两个向量叉乘结果取长度 用做面积
        float area = Vector3.Cross(p1_2, p1_target).magnitude;
        //面积/底边计算出高度
        float distance = area / p1_2.magnitude;
        Debug.Log("叉乘面积法:" + distance);
    }

at last

Here are three ways to obtain the shortest distance from a point to a line, and the running results are all consistent. I will make a record here, hoping to help friends who need help.

 

Guess you like

Origin blog.csdn.net/chooselove/article/details/116808271