Unity 计算点到直线最短距离

写在前面

这两天做开发的时候,有个小伙伴问我怎么计算点到直线的最短距离,看样子困扰了他挺久,所以借这个机会吧这个问题记录下来,让更多小伙伴能涨一下姿势。

先看图:已知条件如下,p1、p2、target三个点,求红色线段的距离。

解题思路

思路1:向量投影法

这个方法核心问题是计算出target到p12向量上距离最短的点,然后通过Vector3.Distance方法计算得出最短距离。

那么如何找到这个点呢?这里,我用了向量投影。

1.先计算出target到p1的向量(蓝色线段)

2.再计算出p2到p1的向量(绿色线段)

3.通过Vector3.Project方法,计算出蓝色线段在绿色线段上的投影,这个投影就是p1F向量

4.将计算出来的投影向量再加上p1点的坐标,即使F点的坐标。

5.最后Vector3.Distance(target,F)即可计算出距离

代码如下:

    /// <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);
    }

思路2:三角函数法

这个方法,就是通过Sin(夹角)*斜边长度计算直角边的距离

1.先计算出target到p1的向量(蓝色线段)

2.再计算出p2到p1的向量(绿色线段)

3.计算前面两个向量的夹角Vector3.Angle(p1_2, p1_target);

4.获取斜边长度(蓝色线段)

5.通过Sin函数*斜边长度计算出距离

代码如下:

    /// <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);
    }

思路3:面积法

这个方法主要是通过平行四边形面积公式来计算出该距离 底 * 高 = 面积

现在我们知道了一条底边的长度(绿色线段),还差面积不知道

这里通过向量叉乘,获取叉乘结果的模就可以(叉乘出来的结果是个向量,向量的长度即为两个叉乘向量所形成的平行四边形的面积)

1.先计算出target到p1的向量(蓝色线段)

2.再计算出p2到p1的向量(绿色线段)

3.两个向量叉乘,获取的结果取长度,即为平行四边形的面积

4.然后 高 = 面积 / 底 得出距离

代码如下:

    /// <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);
    }

最后

这里展示了三种获取点到线的最短距离的方式方法,运行结果也都一致,这里做一个记录,希望能帮助到需要帮助的小伙伴。

猜你喜欢

转载自blog.csdn.net/chooselove/article/details/116808271