1.前言
空间平面方程:
空间两平面如果不平行,那么一定相交于一条空间直线,
空间平面求交有多种方法,本文进行相关讨论。
2.讨论
可以联立方程组求解,共有3个变量,2个方程,而所求直线有1个变量,直线方程为,
2.1.方法一:联立方程求解
通过如下链接中方法可得到所交直线方程,
analytic geometry - How to calculate the intersection of two planes? - Mathematics Stack Exchangehttps://math.stackexchange.com/questions/475953/how-to-calculate-the-intersection-of-two-planes Planes intersection calculator
http://www.ambrnet.com/TrigoCalc/Plan3D/Plane3D_.htm
化为直线参数方程:
这种方法有其局限性,上述公式的分母可能为0,就需要比较繁杂的处理,如令x=t,重新求解。斯坦福官网中的关于Plane类实现的资料中对于面面相交(plane intersect plane)也没有实现该情况的处理,
bool Plane::PlanePlaneIntersection(const Plane &P1, const Plane &P2, Line3D &L)
{float Denominator = P1.a * P2.b - P1.b * P2.a;if(Denominator == 0.0f){// this case should be handled by switching axes...return false;}L.P0 = Vec3f((P2.d * P1.b - P1.d * P2.b) / Denominator, (P1.d * P2.a - P2.d * P1.a) / Denominator, 0.0f);L.D = Vec3f::Cross(P1.Normal(), P2.Normal());if(L.D.Length() == 0.0f){return false;}L.D = Vec3f::Normalize(L.D);return true;
}
Plane.cpp
2.2.方法二:正交平面辅助求解
三维坐标系中三个正交平面为XOY、YOZ、ZOX平面,只要空间平面不与某正交平面(如XOY平面)平行,那么一定有交线,且线上有一点,其Z坐标为0(如果选用了XOY平面),这样将z=0带入平面方程组,求解,此方法和上述方法一本质上是一样的。在方法一中对应的方式是令z=t。
可参考如下实现,和方法一类似,同样需要一些特殊处理,
空间平面相交的直线的计算及其源码_平面的交线计算原理-CSDN博客
2.3.方法三:构造第三平面
两平面法向叉乘可得交线方向,过某点(如平面1上的点或平面2上的点)以其为法向构造第三平面,三平面交于一点(如果平面1和平面2不平行),求该点作为交线上的点。
可直接套用公式,
Plane-Plane Intersection -- from Wolfram MathWorld
Hessian Normal Form -- from Wolfram MathWorld
Intersects of 3 planes_intersectplanes(plane p1, plane p2, plane p3)-CSDN博客
注意构造的第三平面可以过特定点,这样得到的交线上的点距离该特定点最近。
2.4.方法四:几何法
- 求plane1上点到plane2的距离;
- 求2个plane的夹角;
- 根据夹角求asin得到disExpand;
- ptOnPlane1沿dirOffset偏移disExpand得到交线上点;
这种方法得到的点距离点ptOnPlane1最近。
此方法对于需要以距离特定点最近的点来表示直线的情况比较实用,毕竟如果直线上的点非常远时,由于浮点存储机制所带来的精度误差会带来负面影响。
3.精度
一般情况下,公式简洁有效,计算逻辑简单,精度就比较高,当然不是绝对的,也与所选参数的情况、运算过程的主动精度损失等有关系,需要根据具体情况进行精度的分析和测试。