Math 两个平面的交线
我怎样才能找到两个平面之间的交线 我知道数学原理,我做了平面法向量的叉积Math 两个平面的交线,math,language-agnostic,plane,Math,Language Agnostic,Plane,我怎样才能找到两个平面之间的交线 我知道数学原理,我做了平面法向量的叉积 但是如何通过编程从结果向量中获取直线呢?直线的叉积就是相交直线的方向。现在你需要一个交叉点 可以通过在叉积上取一点,然后减去平面a的法线*到平面a的距离和平面B的法线*到平面B的距离来实现。清洁剂: p=叉积上的点 交点=([p]-([平面A的法线]*[从p到平面A的距离])-([平面B的法线]*[从p到平面B的距离]) 编辑: 您有两个具有两条法线的平面: N1 and N2 叉积是相交线的方向: C = N1 x N
但是如何通过编程从结果向量中获取直线呢?直线的叉积就是相交直线的方向。现在你需要一个交叉点 可以通过在叉积上取一点,然后减去平面a的法线*到平面a的距离和平面B的法线*到平面B的距离来实现。清洁剂: p=叉积上的点 交点=([p]-([平面A的法线]*[从p到平面A的距离])-([平面B的法线]*[从p到平面B的距离]) 编辑: 您有两个具有两条法线的平面:
N1 and N2
叉积是相交线的方向:
C = N1 x N2
上面的类具有计算点与平面之间距离的函数。使用它可以获得C上某个点p到两个平面的距离:
p = C //p = 1 times C to get a point on C
d1 = plane1.getDistance(p)
d2 = plane2.getDistance(p)
交叉线:
resultPoint1 = (p - (d1 * N1) - (d2 * N2))
resultPoint2 = resultPoint1 + C
平面的方程式为ax+by+cz+d=0,其中(a,b,c)是平面的法线,d是到原点的距离。这意味着满足该方程的每个点(x,y,z)都是平面的一个成员 给定两个平面:
P1: a1x + b1y + c1z + d1 = 0
P2: a2x + b2y + c2z + d2 = 0
(A3,B3,C3) = (A1,B1,C1) cross (A2,B2,C2)
两者之间的交点是验证两个方程的点集。要沿着这条线找到点,只需为x选择一个值,任意值,然后求解y和z的方程
y = (-c1z -a1x -d1) / b1
z = ((b2/b1)*(a1x+d1) -a2x -d2)/(c2 - c1*b2/b1)
如果将x=0
,这会变得更简单:
y = (-c1z -d1) / b1
z = ((b2/b1)*d1 -d2)/(c2 - c1*b2/b1)
只要两个平面不平行,这种方法就可以避免被零除 如果这些是飞机:
A1*x + B1*y + C1*z + D1 = 0
A2*x + B2*y + C2*z + D2 = 0
1) 找到一个平行于相交线的向量。这也是垂直于其他两个平面的第三个平面的法线:
P1: a1x + b1y + c1z + d1 = 0
P2: a2x + b2y + c2z + d2 = 0
(A3,B3,C3) = (A1,B1,C1) cross (A2,B2,C2)
2) 形成一个由3个方程组成的系统。这些描述了在一点相交的3个平面:
A1*x1 + B1*y1 + C1*z1 + D1 = 0
A2*x1 + B2*y1 + C2*z1 + D2 = 0
A3*x1 + B3*y1 + C3*z1 = 0
3) 求解它们以找到x1,y1,z1。这是相交线上的一个点
4) 相交线的参数方程为:
x = x1 + A3 * t
y = y1 + B3 * t
z = z1 + C3 * t
在直线上找到一点
要获得两个平面的交点,需要在直线上有一个点以及该直线的方向
找到那条线的方向真的很容易,只要穿过两个相交平面的两条法线
lineDir = n1 × n2
但该线穿过原点,沿平面交点的线可能不会穿过原点。所以,答案为在相交线上找到一个点(基本上是两个平面上的任何点)提供了一个很好的开始
如果你想看看如何解决这个问题的推导,下面是它背后的数学:
首先让x=0。现在我们在2个方程中有2个未知数,而不是在2个方程中有3个未知数(我们任意选择其中一个未知数)
然后,平面方程为(由于我们选择了x=0,因此消除了A项):
B1y+C1z+D1=0
B2y+C2z+D2=0
我们需要y和z,这样对于给定的B1,C1,这些方程都能正确求解(=0)
因此,只需将顶部等式乘以(-B2/B1)即可得到
-B2y+(-B2/B1)*C1z+(-B2/B1)*D1=0
B2y+C2z+D2=0
添加要获取的等式
z=(-B2/B1)*D1-D2)/(C2*B2/B1)*C1)
现在把你找到的z放到第一个方程中,得到y作为
y=(-D1-C1z)/B1
注意,最好的变量是系数最低的变量,因为它不携带任何信息。因此,如果C1和C2都是0,那么选择z=0(而不是x=0)将是一个更好的选择
如果B1=0,上述解决方案仍然会出错(这并非不可能)。您可以添加一些if语句来检查B1是否为0,如果是,请确保为其他变量之一求解
使用3个平面的交点求解
根据答案,3个平面相交的封闭形式解决方案实际上在Graphics Gems 1中。公式是:
交点=((点1•n1)(n2×n3)+(点2•n2)(n3×n1)+(点3•n3)(n1×n2))/det(n1,n2,n3)
实际上,点1•n1=-d1(假设你写平面Ax+By+Cz+D=0,而不是=-D)。因此,您可以将其改写为:
p_交点=(-d1)(n2×n3)+(d2)(n3×n1)+(d3)(n1×n2))/det(n1,n2,n3)
与3个平面相交的函数:
// Intersection of 3 planes, Graphics Gems 1 pg 305
static Vector3f getIntersection( const Plane& plane1, const Plane& plane2, const Plane& plane3 )
{
float det = Matrix3f::det( plane1.normal, plane2.normal, plane3.normal ) ;
// If the determinant is 0, that means parallel planes, no intn.
if( det == 0.f ) return 0 ; //could return inf or whatever
return ( plane2.normal.cross( plane3.normal )*-plane1.d +
plane3.normal.cross( plane1.normal )*-plane2.d +
plane1.normal.cross( plane2.normal )*-plane3.d ) / det ;
}
证明它有效(这里的黄点是rgb平面的交点)
接电话
一旦有了两个平面共有的交点,直线就消失了
p+t*d
其中p是交点,t可以从(-inf,inf)开始,d是两个原始平面法线的叉积方向向量
红色和蓝色平面之间的相交线如下所示
效率和稳定性
根据我的统计,“健壮”(第二种方式)需要48次基本运算,而第一种方式(x,y的隔离)需要36次基本运算。这两种方法在稳定性和#计算之间存在权衡
如果B1为0,而您没有检查,那么从调用第1个方法返回(0,inf,inf)将是非常灾难性的。因此,添加if
语句并确保不被0除到第1个方法中,可能会以代码膨胀和添加的分支(这可能非常昂贵)为代价提供稳定性。3平面相交法几乎没有分支,不会给出无穷大。为了完整性,添加此答案,因为在撰写本文时,这里的答案都不包含直接解决此问题的工作代码示例
尽管这里还有其他答案
可以使用三平面相交算法的简化版本计算两个平面之间的直线 答案中的第二个“更稳健的方法”引用了三平面交点 而这适用于2个平面(其中第3个平面