确定一个点是否在一条线上的其他 2 个点之间

Sir*_*Sir 0 c# unity-game-engine

我一直在努力研究如何检查一个点是否在同一条线上以及其他两个点之间。如果这条线是对角线,它似乎有效,但如果它在垂直或水平方向是直的,它就会失败。

这是我的方法:

public bool isBetween(Vector3 C, Vector3 A, Vector3 B)
{
    Vector3 sum = Vector3.Cross(A,B) + Vector3.Cross(A,C) + Vector3.Cross(B,C);

    if (sum.x == 0 && sum.z == 0 && sum.y == 0)
    {
        Vector3 min = Vector3.Min(A, B);
        Vector3 max = Vector3.Max(A, B);

        // only checking 2 dimensions
        if (C.x > min.x && C.x < max.x && C.z > min.z && C.z < max.z)
        {
            return true;
        }
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

它适用于某些情况,但不是 100% 适用于所有情况。不知道如何修复它以使其正常工作。

小智 5

假设point1和point2不同,首先检查点是否在直线上。为此,您只需要向量 point1 -> currPoint 和 point1 -> point2 的“叉积”。

dxc = currPoint.x - point1.x;
dyc = currPoint.y - point1.y;

dxl = point2.x - point1.x;
dyl = point2.y - point1.y;

cross = dxc * dyl - dyc * dxl;
Run Code Online (Sandbox Code Playgroud)

当且仅当 cross 等于零时,您的点位于线上。

if (cross != 0)
 return false;
Run Code Online (Sandbox Code Playgroud)

现在,您知道该点确实位于直线上,是时候检查它是否位于原始点之间。这可以通过比较 x 坐标轻松完成,如果该线“比垂直更水平”,否则为 y 坐标

if (abs(dxl) >= abs(dyl))
 return dxl > 0 ? 
   point1.x <= currPoint.x && currPoint.x <= point2.x :
   point2.x <= currPoint.x && currPoint.x <= point1.x;
else
 return dyl > 0 ? 
   point1.y <= currPoint.y && currPoint.y <= point2.y :
   point2.y <= currPoint.y && currPoint.y <= point1.y;
Run Code Online (Sandbox Code Playgroud)

请注意,如果输入数据是整数,则上述算法是完全整数,即它不需要整数输入的浮点计算。但是在计算交叉时要注意潜在的溢出。

PS 这个算法是绝对精确的,这意味着它会拒绝离线很近但不正好在线上的点。有时这不是所需要的。但那是另一回事了。