Python 计算给定3点的圆(代码说明)

Python 计算给定3点的圆(代码说明),python,math,2d,geometry,Python,Math,2d,Geometry,当搜索代码以计算出3个点的圆时,我会找到以下代码: def circleRadius(b, c, d): temp = c[0]**2 + c[1]**2 bc = (b[0]**2 + b[1]**2 - temp) / 2 cd = (temp - d[0]**2 - d[1]**2) / 2 det = (b[0] - c[0]) * (c[1] - d[1]) - (c[0] - d[0]) * (b[1] - c[1]) if abs(det) < 1.0e

当搜索代码以计算出3个点的圆时,我会找到以下代码:

def circleRadius(b, c, d):
  temp = c[0]**2 + c[1]**2
  bc = (b[0]**2 + b[1]**2 - temp) / 2
  cd = (temp - d[0]**2 - d[1]**2) / 2
  det = (b[0] - c[0]) * (c[1] - d[1]) - (c[0] - d[0]) * (b[1] - c[1])

  if abs(det) < 1.0e-10:
    return None

  # Center of circle
  cx = (bc*(c[1] - d[1]) - cd*(b[1] - c[1])) / det
  cy = ((b[0] - c[0]) * cd - (c[0] - d[0]) * bc) / det

  radius = ((cx - b[0])**2 + (cy - b[1])**2)**.5

  return radius
def循环(b、c、d):
温度=c[0]**2+c[1]**2
bc=(b[0]**2+b[1]**2-温度)/2
cd=(温度-d[0]**2-d[1]**2)/2
det=(b[0]-c[0])*(c[1]-d[1])-(c[0]-d[0])*(b[1]-c[1])
如果abs(det)<1.0e-10:
一无所获
#圆心
cx=(bc*(c[1]-d[1])-cd*(b[1]-c[1])/det
cy=((b[0]-c[0])*cd-(c[0]-d[0])*bc)/det
半径=((cx-b[0])**2+(cy-b[1])**2)**.5
返回半径
基于和。代码工作得很完美,但我不明白代码如何符合在上给出的解释

有人能帮我理解代码为什么工作以及变量中实现了哪些子步骤吗?

您看到的代码是“简化的”和数学博士页面中描述的过程的简明公式

让我们一步一步地看一下

  • 为了简单起见并遵循数学符号,让三角形上的点为准。[b是第1点,c是第2点,d是第3点]

  • 对于此类三角形,面积定义为:

    函数中的该变量
    det
    等于三角形的2*面积

    如果abs(det)<1.0e-10:正在检查共线性,则
    。如果面积接近零,则给出的点是共线的,即它们是单线上的点

  • 求通过点b、c和c、d的直线L1、L2的斜率

  • 求直线L3、L4的方程,它们分别是直线sL1和L2的垂直平分线。

  • 找到线L3和L4的交点,它只是圆环的中心

  • 做所有的替换,你可以看到所有的组合

  • 通过求圆心和三个点之一之间的欧几里德距离来计算圆的半径

  • 这并不是一个真正的答案,我在这里展示的是另一种方法

    p
    q
    r
    为三点。我们翻译它们,以便
    p
    到达原点。向量上,
    q-=p
    r-=p

    现在原点的一个点的方程是

    2.xc.x + 2.yc.y = x² + y²
    
    其中,
    xc
    yc
    是中心的坐标

    通过插入
    p
    q
    的坐标,我们得到了一个2x2系统

    xc.xp + yc.yp = xp² + yp²
    xc.xq + yc.yq = xq² + yq²
    
    下面给出了实现这一点的代码

    # Translate to the origin
    xq-= xp
    yq-= yp
    q2= xp * xp + yp * yp
    xr-= xq
    yr-= yq
    r2= xr * xr + yr * yr
    
    # Solve for the center coordinates
    d= 2 * (xp * yq - xq * yp)
    xc= (p2 * yq - q2 * yp) / d
    yc= (p2 * xp - q2 * xq) / d
    
    # Radius
    r= math.sqrt(xc * xc + yc * yc)
    
    # Untranslate
    xc+= xp
    yc+= yp
    

    它计算直线
    BC
    CD
    的垂直平分线的交点。代数涉及的内容相当多,但证明起来并不难——只需要小学几何。但它在哪里计算垂直平分线呢。BC和CD是值,没有点,我应该计算什么行列式(以确定斜率?),它们如何在cx,cy处结合在一起?我确实理解这种方法背后的基本思想,但无法将代码中的步骤映射到它……如果您将此代码“反压缩”到相关步骤中,它将归结为以下内容:1)计算
    BC
    CD
    的中点;2) 计算到
    BC
    CD
    的垂直方向;3) 使用(1)和(2)的结果定义垂直平分线;4) 求解一对联立方程组以获得交点坐标–这是使用行列式的地方。算出这些变量,做一大堆繁琐的代数来简化,你就能得到上面代码中的方程。变量bc和dc的值是多少,斜率从哪里来?为了计算(1),我建议使用BC=((B[0]+C[0])/2,(B[1],C[1])/2)和(2)这样的代码,使用-1/(BC的斜率)。。。但是这种计算是在哪里进行的呢?@Seppelandrio忘了斜坡吧。关于交点的简单数学描述:如果
    y1=y2或y3=y2或x2=x1
    等,你会怎么做?谢谢!所以我理解了这个词@MBo,在所有变量被替换后,导致被零除的差异项将被消除。这在用于计算
    cx
    cy
    的公式中很明显。我认为被零除是这段代码不计算斜率的原因。通过避免事先计算斜率,我们可以避免灾难性的零除/零乘问题。