C# 在平面上的 2 个 Vector3 点之间相交一条线

C# intersect a line bettween 2 Vector3 point on a plane

我在两个 Vector3 点之间有一条线,我想找出该线何时与 Z 轴的某个高度相交。

我正在尝试编写一个函数来计算交点。

void Main()
{
    Vector3 A = new Vector3(2.0f,  2.0f, 2.0f);
    Vector3 B = new Vector3(7.0f, 10.0f, 6.0f);
    float Z = 3.0f;

    Vector3 C = getIntersectingPoint(A, B, Z);
    //C should be X=3.25, Y=4.0, Z=3.0
} 

但试图弄清楚如何进行数学运算以正确处理可能的负数确实开始让我感到困惑。

这就是我所拥有的,但这是不正确的。

public static Vector3 getIntersectingPoint(Vector3 A, Vector3 B, float Z)
{
    // Assume z is bettween A and B and we don't need to validate
    // Get ratio of triangle hight, height Z divided by (Za to Zb)  
    ("absolute value: " + Math.Abs(A.Z-B.Z)).Dump();
    ("z offset: " + (Math.Abs(Z-B.Z)<Math.Abs(A.Z-Z)?Math.Abs(Z-B.Z):Math.Abs(A.Z-Z))).Dump();
    float ratio = (Math.Abs(Z-B.Z)<Math.Abs(A.Z-Z)?Math.Abs(Z-B.Z):Math.Abs(A.Z-Z))/Math.Abs(A.Z-B.Z);
    ("ratio: " + ratio.ToString()).Dump();
    float difX = ratio*Math.Abs(A.X-B.X);//this still needs to be added to or taken from the zero point offset
    ("difX: " + difX.ToString()).Dump();
    float difY = ratio*Math.Abs(A.Y-B.Y);//this still needs to be added to or taken from the zero point offset
    ("difY: " + difY.ToString()).Dump();

    float X = difX + (A.X<B.X?A.X:B.X);
    ("X: " + X).Dump();
    float Y = difY + (A.Y<B.Y?A.Y:B.Y);
    ("Y: " + Y).Dump();
    return new Vector3(X,Y,Z);
}

有谁知道是否有任何数学库已经可以执行此操作或说明如何执行此操作的示例我可以遵循?

您有起始 (2.0f) 和结束 (6.0f) Z 坐标。两点之间的 Z 距离为 4.0f。您想知道 Z 为 3.0f 的点的 X 和 Y 坐标。

请记住,Z 沿线段线性变化。线段长度为 4 个单位,您感兴趣的点距起点 1 个单位,或线段长度的 1/4。

整个线段的 X 距离为 7.0 - 2.0,即 5 个单位。 5的1/4是1.25,所以交点的X坐标是3.25.

整个线段的Y距离为8,8的1/4为2,所以交点的Y坐标为6.0。

交点为(3.25f, 6.0f, 3.0f).

如何计算:

// start is the starting point
// end is the ending point
// target is the point you're looking for.
// It's pre-filled with the Z coordinate.
zDist = Math.Abs(end.z - start.z);
zDiff = Math.Abs(target.z - start.z);
ratio = zDiff / zDist;

xDist = Math.Abs(end.x - start.x);
xDiff = xDist * ratio;
xSign = (start.x < end.x) ? 1 : -1;
target.x = start.x + (xDiff * xSign);

yDist = Math.Abs(end.y - start.y);
yDiff = yDist * ratio;
ySign = (start.y < end.y) ? 1 : -1;
target.y = start.y + (yDiff * ySign);

想想看,整个标志的东西应该是不必要的。考虑一下,当 end.x = 10start.x = 18:

xDist = end.x - start.x;      // xDist = -8
xDiff = xDist * ratio;        // xDiff = -2
target.x = start.x + xDiff;   // target.x = 18 + (-2) = 16

是的,不需要愚蠢的符号。

计算比率时也不需要调用 Math.Abs。我们知道 zDistzDiff 的符号相同,所以 ratio 总是正数。