找到3个球体之间的交叉点

时间:2009-09-10 16:36:48

标签: math

我正在寻找一种算法来找到3个球体之间的公共交叉点。

完整的算法,对数学的全面/详细描述将非常有用。

这是迄今为止我发现的唯一有用的资源: http://mathforum.org/library/drmath/view/63138.html

但是这里描述的方法都不够详细,我可以写一个算法。

我更喜欢第二篇文章中描述的纯粹代数方法,但它有用。

6 个答案:

答案 0 :(得分:8)

可能比构建3D圆圈更容易,因为主要在线条和平面上工作:

对于每对球体,通过减去球体方程(每个形式X ^ 2 + Y ^ 2 + Z ^ 2 + a X + b <,得到包含其交叉圆的平面的方程式/ em>的Y + C * Z + d = 0)。然后你将有三架飞机P12 P23 P31。

这些平面具有公共线L,通过球的三个中心垂直于平面Q.你要找的两点都在这条线上。点的中间是L和Q之间的交点H.

实现这个:

  • 计算P12 P23 P32的方程(球面方程的差异)
  • 计算Q的等式(求解线性系统,或计算叉积)
  • 计算这四个平面的点H交点的坐标。 (解决线性系统)
  • 从其等式(归一化矢量)得到法线向量U到Q
  • 计算H与解X之间的距离t:t ^ 2 = R1 ^ 2-HC1 ^ 2,(C1,R1)是第一个球体的中心和半径。
  • 溶液是H + t U和H-t U

alt text

Cabri 3D结构,显示各种平面和线L

答案 1 :(得分:6)

基本上你需要分三步完成。假设你有三个球体,S1,S2和S3。

  1. C12是由S1和S2的交点创建的圆圈。
  2. C23是由S2和S3的交点创建的圆圈。
  3. P1,P2,是C12和C13的交点。
  4. 这里唯一真正困难的部分是球体交叉点,谢天谢地Mathworld has that solved pretty well。事实上,Mathworld也有solution to the circle intersections

    根据这些信息,您应该能够创建算法。

答案 2 :(得分:6)

这是我在维基百科文章中提到的Python中的答案。不需要算法;有一个封闭的形式解决方案。

import numpy                                             
from numpy import sqrt, dot, cross                       
from numpy.linalg import norm                            

# Find the intersection of three spheres                 
# P1,P2,P3 are the centers, r1,r2,r3 are the radii       
# Implementaton based on Wikipedia Trilateration article.                              
def trilaterate(P1,P2,P3,r1,r2,r3):                      
    temp1 = P2-P1                                        
    e_x = temp1/norm(temp1)                              
    temp2 = P3-P1                                        
    i = dot(e_x,temp2)                                   
    temp3 = temp2 - i*e_x                                
    e_y = temp3/norm(temp3)                              
    e_z = cross(e_x,e_y)                                 
    d = norm(P2-P1)                                      
    j = dot(e_y,temp2)                                   
    x = (r1*r1 - r2*r2 + d*d) / (2*d)                    
    y = (r1*r1 - r3*r3 -2*i*x + i*i + j*j) / (2*j)       
    temp4 = r1*r1 - x*x - y*y                            
    if temp4<0:                                          
        raise Exception("The three spheres do not intersect!");
    z = sqrt(temp4)                                      
    p_12_a = P1 + x*e_x + y*e_y + z*e_z                  
    p_12_b = P1 + x*e_x + y*e_y - z*e_z                  
    return p_12_a,p_12_b                       

答案 3 :(得分:5)

考虑两个球体的交集。要使其可视化,请考虑连接球体两个中心的3D线段N.考虑这个横截面

alt text
(来源:googlepages.com

其中红线是具有法线N的平面的横截面。通过对称,您可以从任何角度旋转此横截面,并且红线段长度不能更改。这意味着两个球体相交的最终曲线是圆形,并且必须位于具有正常N的平面中。

话虽这么说,让我们找到交集。首先,我们想要描述两个球体交叉的结果圆。您不能使用1个等式执行此操作,3D中的圆基本上是3D曲线,您无法用3D方式描述3D中的曲线。

考虑一下图片 alt text
(来源:googlepages.com

让p成为蓝线和红线的交点。设h是从P点向上沿红线的线段长度。设两个中心之间的距离用d表示。设x是从小圆心到P的距离。那么我们必须

x^2 +h^2 = r1^2
(d-x)^2 +h^2 = r2^2
==> h = sqrt(r1^2 - 1/d^2*(r1^2-r2^2+d^2)^2)

即。你可以求解h,这是交叉圆的半径。您可以从x沿着连接2个圆心的线N找到圆的中心点C.

然后你可以完全描述圆(X,C,U,V都是向量)

X = C + (h * cos t) U + (h * sin t) V for t in [0,2*PI)

其中U和V是垂直向量,位于具有正常N的平面中。

最后一部分是最简单的。它仍然只是找到这个圆与最终球体的交点。这只是一个插头和方程式(在最后一个方程中为x,y,z插入x,y,z的参数形式,用t表示圆,并求解t。)

编辑---

你将获得的等式实际上非常难看,你将拥有一大堆正弦和余弦相等的东西。要解决这个问题,您可以通过两种方式实现:

  1. 使用相等性用指数写出余弦和正弦

    e ^(it)= cos t + i sin t

    然后对所有e ^(it)项进行分组,你应该得到e ^(it)的二次方程 您可以使用二次公式求解,然后求解t。这将为您提供准确的解决方案。这个方法实际上会告诉你一个解决方案是否存在,两个存在或一个存在,取决于二次方法中有多少点是真实的。

  2. 使用牛顿的方法来解决t,这个方法并不精确,但计算上更容易理解,并且在这种情况下它会很好用。

答案 4 :(得分:3)

在搜索网页后,这是第一次点击之一,所以我发布了经过几个小时的研究后找到的最干净,最简单的解决方案:Trilateration

这个维基站点包含一个快速且易于理解的向量方法的完整描述,因此可以轻松编写代码。

答案 5 :(得分:1)

以下是Eric在上面发布的图片的另一种解释:

设H是三个球体中心所跨越的平面。设C1,C2,C3为球体与H的交点,则C1,C2,C3为圆。设Lij为连接Ci和Cj的两个交点的线,则三条线L12,L23,L13在一点P处相交。设M是与H到P正交的线,那么你的两个交点位于线M;因此你只需要将M与任何一个球体相交。