文章目录
- 一、问题描述
- 二、推导步骤
- 代数法
- 几何法
- 三、MATLAB代码
一、问题描述
如图,已知三个球面的球心坐标分别为
P
1
(
x
1
,
y
1
,
z
1
)
,
P
2
(
x
2
,
y
2
,
z
2
)
,
P
3
(
x
3
,
y
3
,
z
3
)
P_1(x_1,y_1,z_1),P_2(x_2,y_2,z_2),P_3(x_3,y_3,z_3)
P1(x1,y1,z1),P2(x2,y2,z2),P3(x3,y3,z3)。球半径分别为
r
1
,
r
2
,
r
3
r_1,r_2,r_3
r1,r2,r3,求三个球面的交点
A
A
A和
B
B
B的坐标。
三个球面方程可以联立得到非线性方程组:
{
(
x
−
x
1
)
2
+
(
y
−
y
1
)
2
+
(
z
−
z
1
)
2
=
r
1
2
(
1.1
)
(
x
−
x
2
)
2
+
(
y
−
y
2
)
2
+
(
z
−
z
2
)
2
=
r
2
2
(
1.2
)
(
x
−
x
3
)
2
+
(
y
−
y
3
)
2
+
(
z
−
z
3
)
2
=
r
3
2
(
1.3
)
(1)
\begin{cases} (x-x_1)^2+(y-y_1)^2+(z-z_1)^2=r_1^2 &(1.1) &\\ (x-x_2)^2+(y-y_2)^2+(z-z_2)^2=r_2^2 &(1.2) &\\ (x-x_3)^2+(y-y_3)^2+(z-z_3)^2=r_3^2 &(1.3) &\\ \tag 1 \end{cases}
⎩
⎨
⎧(x−x1)2+(y−y1)2+(z−z1)2=r12(x−x2)2+(y−y2)2+(z−z2)2=r22(x−x3)2+(y−y3)2+(z−z3)2=r32(1.1)(1.2)(1.3)(1)
三球面交点的求解问题,一种很自然的想法是采用迭代法求解以上非线性方程组。然而非线性方程组的迭代求解方法存在以上问题:迭代初值选择不当,可能会导致迭代不收敛,并且迭代初值不容易确定;计算量较大;通过迭代的方法一次只能迭代计算一个解。
读者可能会想到这样的方法:对于方程组(1)中的三个式子,两两作差刚好可以消去非线性方程组中的项
x
2
,
y
2
,
z
2
x^2,y^2,z^2
x2,y2,z2,得到三元一次方程组,将非线性方程组的求解问题转化为线性方程组的求解问题。线性方程组的求解问题存在唯一的全局最优解且求解算法简单,真是一个完美的解决方法?!但是,细想一下,发现不对劲:第一个球与第二个球相交为一个空间圆弧,空间圆弧与第三个球相交则(一般来说)有两个交点。那么问题出在哪里呢?这是由于,在对方程组(1)中的三个式子两两做差的过程中,关于待求变量
x
,
y
,
z
x,y,z
x,y,z的平方项均被消去,约束条件变弱了。这个例子提醒了我,算法推导过程中切忌想当然!
另外一种读者可能会想到的方法是:将式(1)的非线性方程组转化为无约束非线性优化模型:
m
i
n
[
(
x
−
x
1
)
2
+
(
y
−
y
1
)
2
+
(
z
−
z
1
)
2
−
r
1
2
]
2
+
[
(
x
−
x
2
)
2
+
(
y
−
y
2
)
2
+
(
z
−
z
2
)
2
−
r
2
2
]
2
+
[
(
x
−
x
3
)
2
+
(
y
−
y
3
)
2
+
(
z
−
z
3
)
2
−
r
3
2
]
2
(2)
min [(x-x_1)^2+(y-y_1)^2+(z-z_1)^2-r_1^2]^2 \\ +[(x-x_2)^2+(y-y_2)^2+(z-z_2)^2-r_2^2]^2 \\ +[(x-x_3)^2+(y-y_3)^2+(z-z_3)^2-r_3^2]^2 \tag 2
min[(x−x1)2+(y−y1)2+(z−z1)2−r12]2+[(x−x2)2+(y−y2)2+(z−z2)2−r22]2+[(x−x3)2+(y−y3)2+(z−z3)2−r32]2(2)
求解无约束非线性优化模型与求解非线性方程组存在一样的问题。
那么,有没有求三个球面交点的高效、有效、简洁的解法呢?本博文分别从代数法和几何法推导三个球面交点的高效解法。
二、推导步骤
代数法
式(1.1)与式(1.3)相减,式(1.2)与式(1.3)相减,整理可得:
{
2
(
x
3
−
x
1
)
x
+
2
(
y
3
−
y
1
)
y
+
2
(
z
3
−
z
1
)
z
=
r
1
2
−
r
3
2
−
x
1
2
+
x
3
2
−
y
1
2
+
y
3
2
−
z
1
2
+
z
3
2
2
(
x
3
−
x
2
)
x
+
2
(
y
3
−
y
2
)
y
+
2
(
z
3
−
z
2
)
z
=
r
2
2
−
r
3
2
−
x
2
2
+
x
3
2
−
y
2
2
+
y
3
2
−
z
2
2
+
z
3
2
(3)
\begin{cases} 2(x_3-x_1)x+2(y_3-y_1)y+2(z_3-z_1)z=r_1^2 - r_3^2 - x_1^2 + x_3^2 - y_1^2 + y_3^2 - z_1^2 + z_3^2 &\\ 2(x_3-x_2)x+2(y_3-y_2)y+2(z_3-z_2)z=r_2^2 - r_3^2 - x_2^2 + x_3^2 - y_2^2 + y_3^2 - z_2^2 + z_3^2 &\\ \tag 3 \end{cases}
{2(x3−x1)x+2(y3−y1)y+2(z3−z1)z=r12−r32−x12+x32−y12+y32−z12+z322(x3−x2)x+2(y3−y2)y+2(z3−z2)z=r22−r32−x22+x32−y22+y32−z22+z32(3)
作变量代换,令
{
a
11
=
2
(
x
3
−
x
1
)
a
12
=
2
(
y
3
−
y
1
)
a
13
=
2
(
z
3
−
z
1
)
b
1
=
r
1
2
−
r
3
2
−
x
1
2
+
x
3
2
−
y
1
2
+
y
3
2
−
z
1
2
+
z
3
2
a
21
=
2
(
x
3
−
x
2
)
a
22
=
2
(
y
3
−
y
2
)
a
23
=
2
(
z
3
−
z
2
)
b
2
=
r
2
2
−
r
3
2
−
x
2
2
+
x
3
2
−
y
2
2
+
y
3
2
−
z
2
2
+
z
3
2
(4)
\begin{cases} a_{11}=2(x_3-x_1) &\\ a_{12}=2(y_3-y_1) &\\ a_{13}=2(z_3-z_1) &\\ b_1=r_1^2 - r_3^2 - x_1^2 + x_3^2 - y_1^2 + y_3^2 - z_1^2 + z_3^2&\\ a_{21}=2(x_3-x_2) &\\ a_{22}=2(y_3-y_2) &\\ a_{23}=2(z_3-z_2) &\\ b_2=r_2^2 - r_3^2 - x_2^2 + x_3^2 - y_2^2 + y_3^2 - z_2^2 + z_3^2&\\ \tag 4 \end{cases}
⎩
⎨
⎧a11=2(x3−x1)a12=2(y3−y1)a13=2(z3−z1)b1=r12−r32−x12+x32−y12+y32−z12+z32a21=2(x3−x2)a22=2(y3−y2)a23=2(z3−z2)b2=r22−r32−x22+x32−y22+y32−z22+z32(4)
式(3)写成:
{
a
11
x
+
a
12
y
+
a
13
z
=
b
1
a
21
x
+
a
22
y
+
a
23
z
=
b
2
(5)
\begin{cases} a_{11}x+a_{12}y+a_{13}z=b_1 &\\ a_{21}x+a_{22}y+a_{23}z=b_2 &\\ \tag 5 \end{cases}
{a11x+a12y+a13z=b1a21x+a22y+a23z=b2(5)
将式(5)看成关于未知数x和y的二元一次方程组,解得:
{
x
=
[
(
a
22
b
1
−
a
12
b
2
)
+
(
a
12
a
23
−
a
13
a
22
)
z
]
/
(
a
11
a
22
−
a
12
a
21
)
y
=
[
(
a
11
b
2
−
a
21
b
1
)
+
(
a
13
a
21
−
a
11
a
23
)
z
]
/
(
a
11
a
22
−
a
12
a
21
)
(6)
\begin{cases} x=[(a_{22}b_1-a_{12}b_2) + (a_{12}a_{23}- a_{13}a_{22})z]/(a_{11}a_{22} - a_{12}a_{21}) &\\ y=[(a_{11}b_2 - a_{21}b_1) + (a_{13}a_{21}- a_{11}a_{23})z]/(a_{11}a_{22} - a_{12}a_{21}) &\\ \tag 6 \end{cases}
{x=[(a22b1−a12b2)+(a12a23−a13a22)z]/(a11a22−a12a21)y=[(a11b2−a21b1)+(a13a21−a11a23)z]/(a11a22−a12a21)(6)
作变量代换,令
{
p
1
=
(
a
12
a
23
−
a
13
a
22
)
/
(
a
11
a
22
−
a
12
a
21
)
q
1
=
(
a
22
b
1
−
a
12
b
2
)
/
(
a
11
a
22
−
a
12
a
21
)
p
2
=
(
a
13
a
21
−
a
11
a
23
)
/
(
a
11
a
22
−
a
12
a
21
)
q
2
=
(
a
11
b
2
−
a
21
b
1
)
/
(
a
11
a
22
−
a
12
a
21
)
(7)
\begin{cases} p_1=(a_{12}a_{23}- a_{13}a_{22})/(a_{11}a_{22} - a_{12}a_{21}) &\\ q_1=(a_{22}b_1-a_{12}b_2)/(a_{11}a_{22} - a_{12}a_{21}) &\\ p_2=(a_{13}a_{21}- a_{11}a_{23})/(a_{11}a_{22} - a_{12}a_{21}) &\\ q_2=(a_{11}b_2 - a_{21}b_1) /(a_{11}a_{22} - a_{12}a_{21}) &\\ \tag 7 \end{cases}
⎩
⎨
⎧p1=(a12a23−a13a22)/(a11a22−a12a21)q1=(a22b1−a12b2)/(a11a22−a12a21)p2=(a13a21−a11a23)/(a11a22−a12a21)q2=(a11b2−a21b1)/(a11a22−a12a21)(7)
式(6)写成:
{
x
=
p
1
z
+
q
1
y
=
p
2
z
+
q
2
(8)
\begin{cases} x=p_1z+q_1 &\\ y=p_2z+q_2 &\\ \tag 8 \end{cases}
{x=p1z+q1y=p2z+q2(8)
将式(8)代入式(1.3),展开并化简得到关于z的一元二次方程:
a
z
2
+
b
z
+
c
=
0
(9)
az^2+bz+c=0 \tag 9
az2+bz+c=0(9)
其中,
{
a
=
p
1
2
+
p
2
2
+
1
b
=
2
(
p
1
q
1
−
z
3
+
p
2
q
2
−
p
1
x
3
−
p
2
y
3
)
c
=
q
1
2
−
2
q
1
x
3
+
q
2
2
−
2
q
2
y
3
−
r
3
2
+
x
3
2
+
y
3
2
+
z
3
2
(10)
\begin{cases} a=p_1^2 + p_2^2 + 1 &\\ b=2(p_1q_1 - z_3 + p_2q_2 - p_1x_3 - p_2y_3) &\\ c=q_1^2 - 2q_1x_3 + q_2^2 - 2q_2y_3 - r_3^2 + x_3^2 + y_3^2 + z_3^2 &\\ \tag {10} \end{cases}
⎩
⎨
⎧a=p12+p22+1b=2(p1q1−z3+p2q2−p1x3−p2y3)c=q12−2q1x3+q22−2q2y3−r32+x32+y32+z32(10)
求解式(9)的一元二次方程得到z,再将z代入式(8)得到x和y,至此求三个球面交点的代数解法推导完成。
几何法
参考Andrew Wagner的python程序,自己推导三个球面交点的几何解法,推导过程如下:
如上图,
A
A
A为三个球面的一个交点,四面体
A
P
1
P
2
P
3
AP_1P_2P_3
AP1P2P3的棱长均已知。
∣
∣
A
P
1
⃗
∣
∣
=
r
1
||\vec{AP_1}||=r_1
∣∣AP1∣∣=r1,
∣
∣
A
P
2
⃗
∣
∣
=
r
2
||\vec{AP_2}||=r_2
∣∣AP2∣∣=r2,
∣
∣
A
P
3
⃗
∣
∣
=
r
3
||\vec{AP_3}||=r_3
∣∣AP3∣∣=r3,
∣
∣
P
1
P
2
⃗
∣
∣
||\vec{P_1P_2}||
∣∣P1P2∣∣、
∣
∣
P
2
P
3
⃗
∣
∣
||\vec{P_2P_3}||
∣∣P2P3∣∣和
∣
∣
P
1
P
3
⃗
∣
∣
||\vec{P_1P_3}||
∣∣P1P3∣∣为球心的距离。
以
P
1
P_1
P1为原点,向量
P
1
P
2
⃗
\vec{P_1P_2}
P1P2为x方向,垂直于面
P
1
P
2
P
3
P_1P_2P_3
P1P2P3向上的法向量为z方向,y方向根据右手法则确定,建立局部坐标系
{
e
x
−
e
y
−
e
z
}
\{e_x-e_y-e_z\}
{ex−ey−ez}。
过点
A
A
A作线段
A
C
AC
AC垂直于面
P
1
P
2
P
3
P_1P_2P_3
P1P2P3交于
C
C
C,过点
C
C
C作
C
D
CD
CD垂直于
P
1
P
2
P_1P_2
P1P2交于点
D
D
D,过点
P
3
P_3
P3作
P
3
E
P_3E
P3E垂直于
P
1
P
2
P_1P_2
P1P2交于点
E
E
E,连结
A
D
,
C
P
1
,
C
P
3
,
C
E
,
P
3
E
AD,CP_1,CP_3,CE,P_3E
AD,CP1,CP3,CE,P3E。
令
∣
∣
P
1
D
⃗
∣
∣
=
x
,
∣
∣
D
C
⃗
∣
∣
=
y
,
∣
∣
C
A
⃗
∣
∣
=
z
||\vec{P_1D}||=x, ||\vec{DC}||=y, ||\vec{CA}||=z
∣∣P1D∣∣=x,∣∣DC∣∣=y,∣∣CA∣∣=z,则点
A
A
A的坐标可以写成:
A
=
P
1
+
x
e
x
⃗
+
y
e
y
⃗
+
z
e
z
⃗
(11)
A = P_1 +x \vec{e_x}+y \vec{e_y}+z \vec{e_z} \tag {11}
A=P1+xex+yey+zez(11)
计算单位方向向量
e
x
⃗
,
e
y
⃗
,
e
z
⃗
\vec{e_x}, \vec{e_y},\vec{e_z}
ex,ey,ez及步长
x
,
y
,
z
x,y,z
x,y,z则三球面的交点
A
A
A便可计算。
计算
e
x
⃗
\vec{e_x}
ex:
令
∣
∣
P
1
P
2
⃗
∣
∣
=
d
|| \vec{P_1P_2} ||=d
∣∣P1P2∣∣=d
e
x
⃗
=
P
1
P
2
⃗
/
∣
∣
P
1
P
2
⃗
∣
∣
=
P
1
P
2
⃗
/
d
(12)
\vec{e_x} = \vec{P_1P_2} / || \vec{P_1P_2} ||= \vec{P_1P_2} / d \tag {12}
ex=P1P2/∣∣P1P2∣∣=P1P2/d(12)
计算
e
y
⃗
\vec{e_y}
ey:
令
∣
∣
P
1
E
⃗
∣
∣
=
i
|| \vec{P_1E} ||=i
∣∣P1E∣∣=i,容易得到:
e
y
⃗
=
E
P
3
⃗
/
∣
∣
E
P
3
⃗
∣
∣
(13)
\vec{e_y} = \vec{EP_3} / || \vec{EP_3} || \tag {13}
ey=EP3/∣∣EP3∣∣(13)
E
P
3
⃗
=
P
1
P
3
⃗
−
P
1
E
⃗
=
P
1
P
3
⃗
−
∣
∣
P
1
E
⃗
∣
∣
e
x
⃗
=
P
1
P
3
⃗
−
i
e
x
⃗
(14)
\vec{EP_3} =\vec{P_1P_3}-\vec{P_1E}=\vec{P_1P_3}-||\vec{P_1E}|| \vec{e_x} =\vec{P_1P_3}-i\vec{e_x} \tag {14}
EP3=P1P3−P1E=P1P3−∣∣P1E∣∣ex=P1P3−iex(14)
i
i
i为
P
1
P
3
⃗
\vec{P_1P_3}
P1P3在
e
x
⃗
\vec{e_x}
ex的投影,故有:
i
=
e
x
⃗
⋅
P
1
P
3
⃗
(15)
i =\vec{e_x} \cdot \vec{P_1P_3} \tag {15}
i=ex⋅P1P3(15)
计算
e
z
⃗
\vec{e_z}
ez:
e
z
⃗
=
e
x
⃗
×
e
y
⃗
(16)
\vec{e_z} =\vec{e_x} \times \vec{e_y} \tag {16}
ez=ex×ey(16)
计算
x
x
x:
在三角形
A
P
1
P
2
AP_1P_2
AP1P2中,根据余弦定理:
c
o
s
∠
A
P
1
P
2
=
(
r
1
2
+
d
2
−
r
2
2
)
/
(
2
r
1
d
)
(17)
cos{\angle AP_1P_2}=(r_1^2+d^2-r_2^2)/(2r_1d) \tag {17}
cos∠AP1P2=(r12+d2−r22)/(2r1d)(17)
由于线段
A
C
AC
AC垂直于面
P
1
P
2
P
3
P_1P_2P_3
P1P2P3,线段
P
1
P
2
P_1P_2
P1P2在面
P
1
P
2
P
3
P_1P_2P_3
P1P2P3内,因而线段
A
C
AC
AC垂直线段
P
1
P
2
P_1P_2
P1P2。由于线段
P
1
P
2
P_1P_2
P1P2垂直于线段
C
D
CD
CD,因而线段
P
1
P
2
P_1P_2
P1P2垂直于面
A
C
D
ACD
ACD。由于线段
A
D
AD
AD在面
A
C
D
ACD
ACD内,因而线段
P
1
P
2
P_1P_2
P1P2垂直于线段
A
D
AD
AD。在直角三角形
A
D
P
1
ADP_1
ADP1中,易得:
x
=
∣
∣
P
1
D
⃗
∣
∣
=
∣
∣
A
P
1
⃗
∣
∣
c
o
s
∠
A
P
1
P
2
=
(
r
1
2
+
d
2
−
r
2
2
)
/
(
2
d
)
(18)
x=||\vec{P_1D}||=||\vec{AP_1}||cos{\angle AP_1P_2}=(r_1^2+d^2-r_2^2)/(2d) \tag {18}
x=∣∣P1D∣∣=∣∣AP1∣∣cos∠AP1P2=(r12+d2−r22)/(2d)(18)
计算
y
y
y:
令
∣
∣
P
2
P
3
⃗
∣
∣
=
j
||\vec{P_2P_3}||=j
∣∣P2P3∣∣=j,
j
j
j为
P
1
P
3
⃗
\vec{P_1P_3}
P1P3在
e
y
⃗
\vec{e_y}
ey的投影,故有:
j
=
e
y
⃗
⋅
P
1
P
3
⃗
(19)
j=\vec{e_y} \cdot \vec{P_1P_3} \tag {19}
j=ey⋅P1P3(19)
在三角形
C
E
P
3
CEP_3
CEP3中,由余弦定理,可得:
c
o
s
∠
D
C
E
=
c
o
s
∠
C
E
P
3
=
(
∣
∣
C
E
⃗
∣
∣
2
+
j
2
−
∣
∣
C
P
3
⃗
∣
∣
2
)
/
(
2
j
∣
∣
C
E
⃗
∣
∣
)
(20)
cos{\angle DCE}=cos{\angle CEP_3}=(||\vec{CE}||^2+j^2-||\vec{CP_3}||^2)/(2j||\vec{CE}||) \tag {20}
cos∠DCE=cos∠CEP3=(∣∣CE∣∣2+j2−∣∣CP3∣∣2)/(2j∣∣CE∣∣)(20)
根据勾股定理:
{
∣
∣
C
E
⃗
∣
∣
2
=
∣
∣
A
E
⃗
∣
∣
2
−
∣
∣
A
C
⃗
∣
∣
2
∣
∣
C
P
3
⃗
∣
∣
2
=
∣
∣
A
P
3
⃗
∣
∣
2
−
∣
∣
A
C
⃗
∣
∣
2
(21)
\begin{cases} ||\vec{CE}||^2=||\vec{AE}||^2-||\vec{AC}||^2 &\\ ||\vec{CP_3}||^2=||\vec{AP_3}||^2-||\vec{AC}||^2 &\\ \tag {21} \end{cases}
{∣∣CE∣∣2=∣∣AE∣∣2−∣∣AC∣∣2∣∣CP3∣∣2=∣∣AP3∣∣2−∣∣AC∣∣2(21)
将式(21)代入式(20)得:
c
o
s
∠
D
C
E
=
c
o
s
∠
C
E
P
3
=
(
∣
∣
A
E
⃗
∣
∣
2
+
j
2
−
r
3
2
)
/
(
2
j
∣
∣
C
E
⃗
∣
∣
)
=
[
(
∣
∣
A
D
⃗
∣
∣
2
+
∣
∣
D
E
⃗
∣
∣
2
)
+
j
2
−
r
3
2
]
/
(
2
j
∣
∣
C
E
⃗
∣
∣
)
=
[
r
1
2
−
x
2
+
(
i
−
x
)
2
+
j
2
−
r
3
2
]
/
(
2
j
∣
∣
C
E
⃗
∣
∣
)
=
(
r
1
2
−
r
3
2
−
2
i
x
+
i
2
+
j
2
)
/
(
2
j
∣
∣
C
E
⃗
∣
∣
)
(22)
cos{\angle DCE}=cos{\angle CEP_3}=(||\vec{AE}||^2+j^2-r_3^2)/(2j||\vec{CE}||) \\ =[(||\vec{AD}||^2+||\vec{DE}||^2)+j^2-r_3^2]/(2j||\vec{CE}||) \\ =[r_1^2-x^2+(i-x)^2+j^2-r_3^2]/(2j||\vec{CE}||) \\ = (r_1^2-r_3^2-2ix+i^2+j^2)/(2j||\vec{CE}||) \tag {22}
cos∠DCE=cos∠CEP3=(∣∣AE∣∣2+j2−r32)/(2j∣∣CE∣∣)=[(∣∣AD∣∣2+∣∣DE∣∣2)+j2−r32]/(2j∣∣CE∣∣)=[r12−x2+(i−x)2+j2−r32]/(2j∣∣CE∣∣)=(r12−r32−2ix+i2+j2)/(2j∣∣CE∣∣)(22)
在直角三角形
C
D
E
CDE
CDE中,
y
=
∣
∣
D
C
⃗
∣
∣
=
∣
∣
C
E
⃗
∣
∣
c
o
s
∠
D
C
E
=
(
r
1
2
−
r
3
2
−
2
i
x
+
i
2
+
j
2
)
/
(
2
j
)
(23)
y=||\vec{DC}||=||\vec{CE}||cos{\angle DCE}=(r_1^2-r_3^2-2ix+i^2+j^2)/(2j) \tag {23}
y=∣∣DC∣∣=∣∣CE∣∣cos∠DCE=(r12−r32−2ix+i2+j2)/(2j)(23)
计算
z
z
z:
z
=
∣
∣
C
A
⃗
∣
∣
=
∣
∣
A
P
1
⃗
∣
∣
2
−
∣
∣
C
P
1
⃗
∣
∣
2
=
r
1
2
−
(
x
2
+
y
2
)
=
r
1
2
−
x
2
−
y
2
(24)
z=||\vec{CA}||=\sqrt{||\vec{AP_1}||^2-||\vec{CP_1}||^2}=\sqrt{r_1^2-(x^2+y^2)}=\sqrt{r_1^2-x^2-y^2} \tag {24}
z=∣∣CA∣∣=∣∣AP1∣∣2−∣∣CP1∣∣2=r12−(x2+y2)=r12−x2−y2(24)
至此,三球面交点的几何解法推导完成。
三、MATLAB代码
function [A, B, sta] = calc_intersection_points_of_three_spheres2(P1, P2, P3, r1, r2, r3)
sta = 0;
A = [];
B = [];
x1 = P1(1);
y1 = P1(2);
z1 = P1(3);
x2 = P2(1);
y2 = P2(2);
z2 = P2(3);
x3 = P3(1);
y3 = P3(2);
z3 = P3(3);
a11 = 2 * (x3 - x1);
a12 = 2 * (y3 - y1);
a13 = 2 * (z3 - z1);
b1 = (r1 + r3) * (r1 - r3) + (x3 + x1) * (x3 - x1) + (y3 + y1) * (y3 - y1) + (z3 + z1) * (z3 - z1);
a21 = 2 * (x3 - x2);
a22 = 2 * (y3 - y2);
a23 = 2 * (z3 - z2);
b2 = (r2 + r3) * (r2 - r3) + (x3 + x2) * (x3 - x2) + (y3 + y2) * (y3 - y2) + (z3 + z2) * (z3 - z2);
temp = a11 * a22 - a12 * a21;
if abs(temp) < 1.0e-10
sta = 1;
return;
end
p1 = (a12 * a23 - a13 * a22) / temp;
q1 = (a22 * b1 - a12 * b2) / temp;
p2 = (a13 * a21 - a11 * a23) / temp;
q2 = (a11 * b2 - a21 * b1) / temp;
a = p1^2 + p2^2 + 1;
b = 2 * (p1 * q1 - z3 + p2 * q2 - p1 * x3 - p2 * y3);
c = q1^2 - 2 * q1 * x3 + q2^2 - 2 * q2 * y3 - r3^2 + x3^2 + y3^2 + z3^2;
delta = b^2 - 4 * a * c;
if delta < 0
sta = 1;
return;
end
z = [(-b + sqrt(delta)) / (2 * a); (-b - sqrt(delta)) / (2 * a)];
x = p1 * z + q1;
y = p2 * z + q2;
A = [x(1), y(1), z(1)];
B = [x(2), y(2), z(2)];
end
function [A, B, sta] = calc_intersection_points_of_three_spheres(P1, P2, P3, r1, r2, r3)
sta = 0;
A = [];
B = [];
%计算e_x
vectorP1P2 = P2 - P1;
d = norm(vectorP1P2);
if abs(d) < 1.0e-10
sta = 1;
return;
end
e_x = vectorP1P2 / d;
%计算e_y
vectorP1P3 = P3 - P1;
i = dot(e_x, vectorP1P3);
vectorEP3 = vectorP1P3 - i * e_x;
if norm(vectorEP3) < 1.0e-10
sta = 1;
return;
end
e_y = vectorEP3 / norm(vectorEP3);
%计算e_z
e_z = cross(e_x, e_y);
%计算x
x = (r1*r1 + d*d - r2*r2) / (2*d);
%计算y
j = dot(e_y, vectorP1P3);
if abs(j) < 1.0e-10
sta = 1;
return;
end
y = (r1*r1 - r3*r3 -2*i*x + i*i + j*j) / (2*j);
%计算z
temp = r1*r1 - x*x - y*y;
if temp < 0.0
sta = 1;
return;
end
z = sqrt(temp);
%计算交点坐标
A = P1 + x*e_x + y*e_y + z*e_z;
B = P1 + x*e_x + y*e_y - z*e_z;
end
clc
clear
close all
figure('color', 'w')
[xs,ys,zs] = sphere(50);
h = surf(xs + 0,ys + 0.5,zs + 1);
set(h, 'FaceAlpha', 0.2, 'LineWidth', 0.1)
hold on
h = surf(xs + 0.5,ys + 0,zs + 1);
set(h, 'FaceAlpha', 0.2, 'LineWidth', 0.1)
h = surf(xs + 1,ys + 1,zs + 0);
set(h, 'FaceAlpha', 0.2, 'LineWidth', 0.1)
axis equal tight
shading interp
axis off
P1 = [0 0.5 1];
P2 = [0.5 0 1];
P3 = [1 1 0];
r1 = 1;
r2 = 1;
r3 = 1;
[p_12_a, p_12_b, sta] = calc_intersection_points_of_three_spheres(P1, P2, P3, r1, r2, r3)
[p_12_A, p_12_B, sta] = calc_intersection_points_of_three_spheres2(P1, P2, P3, r1, r2, r3)
plot3([P1(1), P2(1), P3(1), P1(1)], [P1(2), P2(2), P3(2), P1(2)], [P1(3), P2(3), P3(3), P1(3)], '-o', 'linewidth', 1)
plot3(p_12_a(1), p_12_a(2), p_12_a(3), '+', 'linewidth', 2)
plot3(p_12_b(1), p_12_b(2), p_12_b(3), '+', 'linewidth', 2)
text(P1(1)-0.1, P1(2)+0.1, P1(3), 'P_1')
text(P2(1), P2(2)-0.1, P2(3), 'P_2')
text(P3(1), P3(2)-0.1, P3(3), 'P_3')
text(p_12_a(1), p_12_a(2), p_12_a(3)+0.2, 'A')
text(p_12_b(1), p_12_b(2)-0.2, p_12_b(3), 'B')
view(0,49)