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个平面