求三个球面交点的高效解法

文章目录

  • 一、问题描述
  • 二、推导步骤
    • 代数法
    • 几何法
  • 三、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} (xx1)2+(yy1)2+(zz1)2=r12(xx2)2+(yy2)2+(zz2)2=r22(xx3)2+(yy3)2+(zz3)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[(xx1)2+(yy1)2+(zz1)2r12]2+[(xx2)2+(yy2)2+(zz2)2r22]2+[(xx3)2+(yy3)2+(zz3)2r32]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(x3x1)x+2(y3y1)y+2(z3z1)z=r12r32x12+x32y12+y32z12+z322(x3x2)x+2(y3y2)y+2(z3z2)z=r22r32x22+x32y22+y32z22+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(x3x1)a12=2(y3y1)a13=2(z3z1)b1=r12r32x12+x32y12+y32z12+z32a21=2(x3x2)a22=2(y3y2)a23=2(z3z2)b2=r22r32x22+x32y22+y32z22+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=[(a22b1a12b2)+(a12a23a13a22)z]/(a11a22a12a21)y=[(a11b2a21b1)+(a13a21a11a23)z]/(a11a22a12a21)(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=(a12a23a13a22)/(a11a22a12a21)q1=(a22b1a12b2)/(a11a22a12a21)p2=(a13a21a11a23)/(a11a22a12a21)q2=(a11b2a21b1)/(a11a22a12a21)(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(p1q1z3+p2q2p1x3p2y3)c=q122q1x3+q222q2y3r32+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\} {exeyez}
  过点 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} cosAP1P2=(r12+d2r22)/(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 ∣∣cosAP1P2=(r12+d2r22)/(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} cosDCE=cosCEP3=(∣∣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} cosDCE=cosCEP3=(∣∣AE 2+j2r32)/(2j∣∣CE ∣∣)=[(∣∣AD 2+∣∣DE 2)+j2r32]/(2j∣∣CE ∣∣)=[r12x2+(ix)2+j2r32]/(2j∣∣CE ∣∣)=(r12r322ix+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 ∣∣cosDCE=(r12r322ix+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) =r12x2y2 (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)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/51854.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【小波尺度谱】从分段离散小波变换计算小波尺度谱研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Cpp学习——通过日期类来了解Cpp中的运算符重载

目录 一&#xff0c;日期类 二&#xff0c;运算符重载 运算符重载1(比较&#xff09; 1.< 2. 复用 3.> 4.! 5.< 6.> 运算符重载2(日期加减&#xff09; 0.准备条件------计算每月的日期函数 1. 2. 3.- 4.- 5.前置 6.后置 7前置-- 6.后置-- 7.计…

接口自动化测试平台

下载了大神的EasyTest项目demo修改了下<https://testerhome.com/topics/12648 原地址>。也有看另一位大神的HttpRunnerManager<https://github.com/HttpRunner/HttpRunnerManager 原地址>&#xff0c;由于水平有限&#xff0c;感觉有点复杂~~~ 【整整200集】超超超…

多线程案例 | 单例模式、阻塞队列、定时器、线程池

多线程案例 1、案例一&#xff1a;线程安全的单例模式 单例模式 单例模式是设计模式的一种 什么是设计模式&#xff1f; 设计模式好比象棋中的 “棋谱”&#xff0c;红方当头炮&#xff0c;黑方马来跳&#xff0c;针对红方的一些走法&#xff0c;黑方应招的时候有一些固定的…

在OK3588板卡上部署模型实现OCR应用

一、主机模型转换 我们依旧采用FastDeploy来部署应用深度学习模型到OK3588板卡上 进入主机Ubuntu的虚拟环境 conda activate ok3588 安装rknn-toolkit2&#xff08;该工具不能在OK3588板卡上完成模型转换&#xff09; git clone https://github.com/rockchip-linux/rknn-to…

SpringBoot自动装配介绍

SpringBoot是对Spring的一种扩展&#xff0c;其中比较重要的扩展功能就是自动装配&#xff1a;通过注解对常用的配置做默认配置&#xff0c;简化xml配置内容。本文会对Spring的自动配置的原理和部分源码进行解析&#xff0c;本文主要参考了Spring的官方文档。 自动装配的组件 …

Golang安装

目录 Go安装下载安装Go Go安装 下载安装Go 地址&#xff1a;https://studygolang.com/dl 1、根据系统来选择下载包。 2、我是Window&#xff0c;所以直接下载windows的安装包来安装。 3、在控制台窗口输入“go version”可查看Go版本&#xff0c;检测是否安装成功。 4、配置…

【环境配置】使用Docker搭建LAMP环境

这篇文章不是介绍DOCKER是什么&#xff0c;也不是阐述DOCKER的核心&#xff1a;镜像/容器和仓库之间的关系,它只是一篇让刚刚接触DOCKER的初学者&#xff0c;在没有完全了解DOCKER是什么之前,也能尽快的在Linux系统下面通过DOCKER来搭建一个LAMP环境&#xff0c;这是其一&#…

Open3D(C++) 根据索引提取点云

目录 一、功能概述1、主要函数2、源码二、代码实现三、结果展示本文由CSDN点云侠原创,原文链接。爬虫网站自重,把自己当个人 一、功能概述 1、主要函数 std::shared_ptr<PointCloud> SelectByIn

IDEA安装热部署插件JRebel详解

JRebel 简介 JRebel是一套JavaEE开发工具。JRebel允许开发团队在有限的时间内完成更多的任务修正更多的问题&#xff0c;发布更高质量的软件产品。 JRebel是收费软件&#xff0c;用户可以在JRebel官方站点下载30天的评估版本。 Jrebel 可快速实现热部署&#xff0c;节省了大量重…

代码随想录算法训练营第二十五天 | 读PDF复习环节3

读PDF复习环节3 本博客的内容只是做一个大概的记录&#xff0c;整个PDF看下来&#xff0c;内容上是不如代码随想录网站上的文章全面的&#xff0c;并且PDF中有些地方的描述&#xff0c;是很让我疑惑的&#xff0c;在困扰我很久后&#xff0c;无意间发现&#xff0c;其网站上的讲…

前端html中让两个或者多个div在一行显示,用style给div加上css样式

文章目录 前言一、怎么让多个div在一行显示 前言 DIV是层叠样式表中的定位技术&#xff0c;全称DIVision&#xff0c;即为划分。有时可以称其为图层。DIV在编程中又叫做整除&#xff0c;即只得商的整数。 DIV元素是用来为HTML&#xff08;标准通用标记语言下的一个应用&#x…

图像处理之hough圆形检测

hough检测原理 点击图像处理之Hough变换检测直线查看 下面直接描述检测圆形的方法 基于Hough变换的圆形检测方法 对于一个半径为 r r r&#xff0c;圆心为 &#xff08; a , b &#xff09; &#xff08;a,b&#xff09; &#xff08;a,b&#xff09;的圆&#xff0c;我们将…

别再分库分表了,试试TiDB!

什么是NewSQL 传统SQL的问题 升级服务器硬件 数据分片 NoSQL 的问题 优点 缺点 NewSQL 特性 NewSQL 的主要特性 三种SQL的对比 TiDB怎么来的 TiDB社区版和企业版 TIDB核心特性 水平弹性扩展 分布式事务支持 金融级高可用 实时 HTAP 云原生的分布式数据库 高度兼…

M 芯片的 macos 系统安装虚拟机 centos7 网络配置

centos 安装之前把网络配置配好或者是把网线插好 第一步找到这个 第二步打开网络适配器 选择图中所指位置 设置好之后 开机启动 centos 第三步 开机以后 编写网卡文件保存 重启网卡就可以了&#xff0c;如果重启网卡不管用&#xff0c;则重启虚拟机即可 “ ifcfg-ens160 ” 这…

HTML快速学习

目录 一、网页元素属性 1.全局属性 2.标签 2.1其他标签 2.2表单标签 2.3图像标签 2.4列表标签 2.5表格标签 2.6文本标签 二、编码 1.字符的数字表示法 2.字符的实体表示法 三、实践一下 一、网页元素属性 1.全局属性 id属性是元素在网页内的唯一标识符。 class…

iOS开发-实现获取下载主题配置动态切换主题

iOS开发-实现获取下载主题配置动态切换主题 iOS开发-实现获取下载主题配置更切换主题&#xff0c;主要是通过请求服务端配置的主题配置、下载主题、解压保存到本地。通知界面获取对应的图片及颜色等。 比如新年主题风格&#xff0c;常见的背景显示红色氛围图片、tabbar显示新…

【002 操作系统】进程的状态及状态转换图?

一、进程的状态 1. 创建状态 2. 就绪状态 3. 运行状态 4. 阻塞状态 5. 终止状态 图源&#xff1a;进程、线程基础知识全家桶&#xff0c;30 张图一套带走_Linux_小林coding_InfoQ写作社区 NULL -> 创建状态&#xff1a;一个新进程被创建时的第一个状态&#xff1b; 创建状态…

LT6911C 是一款HDMI 1.4到双端口MIPIDSI/CSI或者LVDS加音频的一款高性能芯片

LT6911C 1.描述&#xff1a; LT6911C是一款高性能的HDMI1.4到MIPIDSI/CSI/LVDS芯片&#xff0c;用于VR/智能手机/显示器应用程序。对于MIPIDSI/CSI输出&#xff0c;LT6911C具有可配置的单端口或双端口MIPIDSI/CSI&#xff0c;具有1个高速时钟通道和1个~4个高速数据通道&#…

nacos源码打包及相关配置

nacos 本地下载后&#xff0c;需要 install 下&#xff1a; mvn clean install -Dmaven.test.skiptrue -Dcheckstyle.skiptrue -Dpmd.skiptrue -Drat.skiptruenacos源码修改后&#xff0c;重新打包生成压缩包命令&#xff1a;在 distribution 目录中运行&#xff1a; mvn -Pr…