在深入研究我的旧微积分后,我找到了这个问题的数学答案。
鉴于我在空间中有三个点,我可以组成一个平面:
P: (Px, Py, Pz)
Q: (Qx, Qy, Qz)
R: (Rx, Ry, Rz)
http://tutorial.math.lamar.edu/Classes/CalcIII/EqnsOfPlanes.aspx 中描述的这些点和数学让我继续前进。
Vector(PQ) = (PQx, PQy, PQz)
Vector(PR) = (PRx, PRy, PRz)
现在我将叉积应用于这两个向量,这给出了平面的法线向量
(此处描述的交叉产品数学:http://tutorial.math.lamar.edu/Classes/CalcII/CrossProduct.aspx#Vectors_CrossProd_Ex2)
Vector(PQ) x Vector(PR) = Vector(PQy * PRz - PQz * PRy,
PQz * PRx - PQx * PRz,
PQx * PRy - PQy * PRx)
所以,这就是我得到的平面方程,不管它必须通过其中一个点:
x(PQy * PRz - PQz * PRy) + y(PQz * PRx - PQx * PRz) + z(PQx * PRy - PQy * PRx) = 0
要获得通过所有点的平面的完整方程,我必须应用一个点,如第一个链接中的示例 1 所述。
x(PQy * PRz - PQz * PRy) + y(PQz * PRx - PQx * PRz) + z(PQx * PRy - PQy * PRx) =
Px(PQy * PRz - PQz * PRy) + Py(PQz * PRx - PQx * PRz) + Pz(PQx * PRy - PQy * PRx)
要将我的示例应用于此公式,我得到以下等式:
P: (90, 6, 5)
Q: (70, 6, 6)
R: (70, 8, 7)
Vector(PQ) = (20, 0, -1)
Vector(PR) = (20, -2, -2)
这些的交叉产品给了我这个公式:
-2x + 20y - 40z = 0
如果我现在将点 P 应用于此,我可以得到我的飞机的完整方程:
-2x + 20y - 40z = -2 * 90 + 20 * 6 - 40 * 5
-2x + 20y - 40z = -260
z = (-2x + 20y + 260) / 40
当我寻找 x = 6 和 y = 80 的 z 值时,我将这些值放入等式中。
x = 80
y = 6
z = (-2 * 80 + 20 * 6 + 260) / 40
z = 5.5
5.5 是本示例的预期答案,因为它恰好位于 P 和 Q 的中间。
这个算法的最终实现:
float TargetSpeed::PlaneInterpolation(Point3D p, Point3D q, Point3D r, int x, int y)
{
Point3D pq = Point3D(p.X - q.X, p.Y - q.Y, p.Z - q.Z);
Point3D pr = Point3D(p.X - r.X, p.Y - r.Y, p.Z - r.Z);
Point3D n = Point3D(pq.Y * pr.Z - pq.Z * pr.Y,
pq.Z * pr.X - pq.X * pr.Z,
pq.X * pr.Y - pq.Y * pr.X);
float d = n.X * p.X + n.Y * p.Y + n.Z * p.Z;
float z = (d - n.X * (float)x - n.Y * (float)y) / n.Z;
return z;
}