FPlane::PlaneDot
/** * Calculates distance between plane and a point. * * @param P The other point. * @return >0: point is in front of the plane, <0: behind, =0: on the plane. */ FORCEINLINE float FPlane::PlaneDot(const FVector &P) const { return X * P.X + Y * P.Y + Z * P.Z - W; }
从其注释表明,这是计算点到Plane的距离的函数,同时要知道,Plane将空间分成了两部分,其法线正向所在的部分定义为正,另一部分定义为负。在正空间的点到Plane的距离为正,负空间的点到Plane的距离为负。
#189的解释简单直接
PointPlaneProject
/** * Calculate the projection of a point on the given plane. * * @param Point The point to project onto the plane * @param Plane The plane * @return Projection of Point onto Plane */ FVector FVector::PointPlaneProject(const FVector& Point, const FPlane& Plane) { //Find the distance of X from the plane //Add the distance back along the normal from the point return Point - Plane.PlaneDot(Point) * Plane; }
设投影点是Q,有OP = OQ + QP. 因此Q点坐标即OQ = OP - QP
QP = (Point到Plane的有向距离) * (Plane.Normal). 当P在正空间时,有向距离为正,QP结果与Normal同向;当P在负空间时,有向距离为负,QP结果与Normal反向。因此这里的QP计算式是正确的,符合事实。
章节(12.5) 平面
平面方程的隐式定义:
$$ax + by + cz = d\\
\textbf{p * n} = d$$
点到平面的距离
关于#130里FPlane的定义,其实就是n*p=d的形式。其中x、y、z分量存法线n,w存的d。
实际上,n*p就是OP在方向向量n上的投影,对于平面上所有的点P,其OP在n上的投影都是相同的,即具有相同的d。反过来也就是说:对于一个确定的方向向量n,若有OP在n上的投影(即n*p)相同(记为d),则称这些P在同一个平面上。因此可以用n*p = d来表达一个平面。
而点到平面的距离也可以直观的思考:任意点Q都可以求出其在n上的投影n*q,若Q在平面上,则有n*q=d,若Q在平面的正空间,则有n*q>d,反之若Q在平面的负空间,则有n*q<d。因此Q点到平面的有向距离就是:n*q - d
还有一种定义平面的方式:已知平面法线n,平面上一点p0,那么对于平面上的任一点p,都有n*(p-p0) = 0