计算两直线之间距离,线段之间距离,点到线段距离,点到直线距离

该文提供了一组在Unity3D环境中使用C#语言计算两条直线之间、两条线段之间以及点到线段距离的代码示例。这些方法涉及到了Ray类、向量运算以及三角形几何知识,对于游戏开发中的碰撞检测和几何计算具有实用价值。

以下方法都是在Unity环境下基于C#语言测试通过的代码。

两条直线之间的距离代码参考如下:

// 计算两条直线之间的最短距离,这里借用了Ray射线类来替代表示直线
float LinesMinDist(Ray ray1, Ray ray2)
{
	Vector3 p1 = ray1.origin;
	Vector3 p2 = ray2.origin;
	Vector3 d1 = ray1.direction;
	Vector3 d2 = ray2.direction;
	Vector3 n = Vector3.Cross(d1, d2);

	// 方向向量叉乘为零,表示直线平行或重合
	if (Mathf.Approximately(n.magnitude, 0))
	{
		// 平行或重合的情况
		return Vector3.Distance(Vector3.Project(p2 - p1, d1) + p1, p2);
	}
	else
	{
		// 不平行的情况
		return Vector3.Project(p1 - p2, n).magnitude;
	}
}

两条线段之间的距离代码参考如下:


    public class Segment
    {
        public Vector3 start;
        public Vector3 end;
    }

    public float SegmentDistance(Segment seg1, Segment seg2)
    {
        Vector3 u = seg1.end - seg1.start;
        Vector3 v = seg2.end - seg2.start;
        Vector3 w = seg1.start - seg2.start;
        float a = Vector3.Dot(u, u);
        float b = Vector3.Dot(u, v);
        float c = Vector3.Dot(v, v);
        float d = Vector3.Dot(u, w);
        float e = Vector3.Dot(v, w);
        float D = a * c - b * b;
        float sc, sN, sD = D;
        float tc, tN, tD = D;
        if (D < 0.01f)
        {
            sN = 0;
            sD = 1;
            tN = e;
            tD = c;
        }
        else
        {
            sN = (b * e - c * d);
            tN = (a * e - b * d);
            if (sN < 0)
            {
                sN = 0;
                tN = e;
                tD = c;
            }
            else if (sN > sD)
            {
                sN = sD;
                tN = e + b;
                tD = c;
            }
        }
        if (tN < 0)
        {
            tN = 0;
            if (-d < 0)
            {
                sN = 0;
            }
            else if (-d > a)
            {
                sN = sD;
            }
            else
            {
                sN = -d;
                sD = a;
            }
        }
        else if (tN > tD)
        {
            tN = tD;
            if ((-d + b) < 0)
            {
                sN = 0;
            }
            else if ((-d + b) > a)
            {
                sN = sD;
            }
            else
            {
                sN = (-d + b);
                sD = a;
            }
        }
        if (Mathf.Abs(sN) < 0.01f)
        {
            sc = 0;
        }
        else
        {
            sc = sN / sD;
        }
        if (Mathf.Abs(tN) < 0.01f)
        {
            tc = 0;
        }
        else
        {
            tc = tN / tD;
        }
        Vector3 dP = w + (sc * u) - (tc * v);
        float distance1 = Mathf.Sqrt(Vector3.Dot(dP, dP));
        return distance1;
    }

点到线段距离2D版本代码如下:


public class Line2D
{
    public Vector2 start;
    public Vector2 end;
}
//计算点到线段的距离
public float DistPoint2DToLine2D(Vector2 point, Line2D line)
{
    float distToStart = Vector2.Distance(point, line.start);
    float distToEnd = Vector2.Distance(point, line.end);
    float len = Vector2.Distance(line.start, line.end);
    if (Mathf.Approximately(distToStart, 0) || Mathf.Approximately(distToEnd, 0)) return 0;
    if (Mathf.Approximately(len, 0)) return distToStart;
    //三角形一边长度平方与另外两边长度平方和的比较,大于是钝角三角形,小于是锐角三角形, 等于是直角三角形)
    if (distToStart * distToStart >= len * len + distToEnd * distToEnd) return distToEnd;
    if (len * len + distToStart * distToStart <= distToEnd * distToEnd) return distToStart;
    //利用三角形的面积求高(点到垂足的距离)
    float p = (len + distToStart + distToEnd) * 0.5f;
    float area = Mathf.Sqrt(p * (p - distToEnd) * (p - distToStart) * (p - len));
    return 2 * area / len;
}

点到线段距离3D版本代码如下:


public class Line
{
    public Vector3 start;
    public Vector3 end;
}

public float DistPointToLine(Vector3 point, Line line)
{
    float distToStart = Vector3.Distance(point, line.start);
    float distToEnd = Vector3.Distance(point, line.end);
    float len = Vector3.Distance(line.start, line.end);
    if (Mathf.Approximately(distToStart, 0) || Mathf.Approximately(distToEnd, 0)) return 0;
    if (Mathf.Approximately(len, 0)) return distToStart;
    //三角形一边长度平方与另外两边长度平方和的比较,大于是钝角三角形,小于是锐角三角形, 等于是直角三角形)
    if (distToStart * distToStart >= len * len + distToEnd * distToEnd) return distToEnd;
    if (len * len + distToStart * distToStart <= distToEnd * distToEnd) return distToStart;
    //利用三角形的面积求高(点到垂足的距离)
    float p = (len + distToStart + distToEnd) * 0.5f;
    float area = Mathf.Sqrt(p * (p - distToEnd) * (p - distToStart) * (p - len));
    return 2 * area / len;
}

点到直线距离3D版本如下:

float DistPointToLine(Vector3 point, Vector3 pSegA, Vector3 pSegB)
{
	Vector3 vecAB = pSegA - pSegB;
	Vector3 vecAP = pSegA - point;
	float magOfCross = Vector3.Cross(vecAP, vecAB).magnitude;
	return magOfCross / vecAB.magnitude;
}

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值