我正在寻找一种算法来找到3个球体之间的公共交叉点。
完整的算法,对数学的全面/详细描述将非常有用。
这是迄今为止我发现的唯一有用的资源: http://mathforum.org/library/drmath/view/63138.html
但是这里描述的方法都不够详细,我可以写一个算法。
我更喜欢第二篇文章中描述的纯粹代数方法,但它有用。
答案 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.
实现这个:
Cabri 3D结构,显示各种平面和线L
答案 1 :(得分:6)
基本上你需要分三步完成。假设你有三个球体,S1,S2和S3。
这里唯一真正困难的部分是球体交叉点,谢天谢地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.考虑这个横截面
(来源:googlepages.com)
其中红线是具有法线N的平面的横截面。通过对称,您可以从任何角度旋转此横截面,并且红线段长度不能更改。这意味着两个球体相交的最终曲线是圆形,并且必须位于具有正常N的平面中。
话虽这么说,让我们找到交集。首先,我们想要描述两个球体交叉的结果圆。您不能使用1个等式执行此操作,3D中的圆基本上是3D曲线,您无法用3D方式描述3D中的曲线。
考虑一下图片
(来源:googlepages.com)
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。)
编辑---
你将获得的等式实际上非常难看,你将拥有一大堆正弦和余弦相等的东西。要解决这个问题,您可以通过两种方式实现:
使用相等性用指数写出余弦和正弦
e ^(it)= cos t + i sin t
然后对所有e ^(it)项进行分组,你应该得到e ^(it)的二次方程 您可以使用二次公式求解,然后求解t。这将为您提供准确的解决方案。这个方法实际上会告诉你一个解决方案是否存在,两个存在或一个存在,取决于二次方法中有多少点是真实的。
使用牛顿的方法来解决t,这个方法并不精确,但计算上更容易理解,并且在这种情况下它会很好用。
答案 4 :(得分:3)
这个维基站点包含一个快速且易于理解的向量方法的完整描述,因此可以轻松编写代码。
答案 5 :(得分:1)
以下是Eric在上面发布的图片的另一种解释:
设H是三个球体中心所跨越的平面。设C1,C2,C3为球体与H的交点,则C1,C2,C3为圆。设Lij为连接Ci和Cj的两个交点的线,则三条线L12,L23,L13在一点P处相交。设M是与H到P正交的线,那么你的两个交点位于线M;因此你只需要将M与任何一个球体相交。