Python 给出3个点和一个绘图圆

Python 给出3个点和一个绘图圆,python,matplotlib,plot,Python,Matplotlib,Plot,我想给python点[0,1]、[1,0]和[0,-1],并画出经过它们的圆。是否存在一个python模块来实现这一点?我已尝试使用matplotlib: import matplotlib.pyplot as plt plt.plot([0,1,0],[1,0,-1]) plt.show() 但只给了我两条线。要在matplotlib中画一个圆,首先需要声明一个艺术家 circle = plt.Circle((0,0), 2) 然后必须将该艺术家添加到轴的实例中: fig, ax = pl

我想给python点[0,1]、[1,0]和[0,-1],并画出经过它们的圆。是否存在一个python模块来实现这一点?我已尝试使用matplotlib:

import matplotlib.pyplot as plt
plt.plot([0,1,0],[1,0,-1])
plt.show()

但只给了我两条线。

要在matplotlib中画一个圆,首先需要声明一个艺术家

circle = plt.Circle((0,0), 2)
然后必须将该艺术家添加到轴的实例中:

fig, ax = plt.subplots()
ax.add_artist(circle)
然后你可以安全地画出来

plt.show()
请注意,艺术家
Circle
采用
(x,y)
圆的中心坐标和半径
r
。这意味着你必须自己计算这些值

有一个与此完全匹配的“代码高尔夫”问题(除了要求圆的方程式,而不是绘制它)——请参见。将第一个和最短的(Python)解决方案分解为更易读、更简单的形式,以符合您的具体规格-但保留使用复数进行更简单计算的核心思想:

x, y, z = 0+1j, 1+0j, 0-1j
w = z-x
w /= y-x
c = (x-y)*(w-abs(w)**2)/2j/w.imag-x
print '(x%+.3f)^2+(y%+.3f)^2 = %.3f^2' % (c.real, c.imag, abs(c+x))

好的,这仍然是“打印等式”而不是“绘制圆”,但是,我们越来越接近:-)。若要实际绘制matplotlib中的圆,请参见,例如——在上面的解决方案中,
c
是圆的(求反)中心(作为复数,因此使用.real和.imag表示x/y坐标),
abs(c+x)
半径(实数,
abs
).

给定三个点,其坐标为:

(p,t)(q,u)(s,z)

…由这三个点定义的圆的方程为:

x^2+y^2+Ax+By+C=0

其中:

A=((u-t)*z^2+(-u^2+t^2-q^2+p^2)*z+t*u^2+(-t^2+s^2-p^2)*u+(q^2-s^2)*t)/((q-p)*z+(p-s)*u+(s-q)*t)

B=-((q-p)*z^2+(p-s)*u^2+(s-q)*t^2+(q-p)*s^2+(p^2-q^2)*s+p*q^2-p^2*q)/((q-p)*z+(p-s)*u+(s-q)*t)

C=-((p*u-q*t)*z^2+(-p*u^2+q*t^2-p*q^2+p^2*q)*z+s*t*u^2+(-s*t^2+p*s^2-p^2*s)*u+(q^2*s-q*s^2)*t)/((q-p)*z+(p-s)*u+(s-q)*t)
以上是一般解决方案。可以将A、B和C的公式放入程序中 求任意圆的方程,给定3点

对于点(0,1)(1,0)(0,-1)的特定问题,您将得到:

A=0

B=0

C=-1

。。。所以方程是


x^2+y^2-1=0(单位圆)

此代码还可以让您轻松检查这3个点是否形成一条直线

def define_circle(p1, p2, p3):
    """
    Returns the center and radius of the circle passing the given 3 points.
    In case the 3 points form a line, returns (None, infinity).
    """
    temp = p2[0] * p2[0] + p2[1] * p2[1]
    bc = (p1[0] * p1[0] + p1[1] * p1[1] - temp) / 2
    cd = (temp - p3[0] * p3[0] - p3[1] * p3[1]) / 2
    det = (p1[0] - p2[0]) * (p2[1] - p3[1]) - (p2[0] - p3[0]) * (p1[1] - p2[1])

    if abs(det) < 1.0e-6:
        return (None, np.inf)

    # Center of circle
    cx = (bc*(p2[1] - p3[1]) - cd*(p1[1] - p2[1])) / det
    cy = ((p1[0] - p2[0]) * cd - (p2[0] - p3[0]) * bc) / det

    radius = np.sqrt((cx - p1[0])**2 + (cy - p1[1])**2)
    return ((cx, cy), radius)
(调整自)

我很好奇为什么它能起作用。无论如何,我必须为我的演讲制作一份报告,所以我将它粘贴在这里,供子孙后代使用


这是很有用的一个,因为我将处理复数。我忘了用这种方法更容易得到圆心和半径。我想看到你的刻痕清楚地纪念埃瓦里斯特·伽罗瓦引导我的潜意识走向了这个数学上优雅的想法:-)。想起一个在我1/3岁时去世的家伙,只留下60页的笔记,彻底改变了数学的两个关键分支,让我保持了适当的谦卑(另外,我是1/8的法国人,所以这也让我感到适当的骄傲:-)。很高兴看到一个认识他的人。由于他的发现,我是一个代数爱好者:-)。我不记得是否在某个时候我理解了他是如何做到的,因为正如他所说,他根据一个密码高尔夫问题改编了一个解决方案,但我记得我寻找了自己的计算方法,因为唯一让我感到振奋的是“复数”这个短语。事实上,我认为您的链接更容易发布,因为它是以扩展的方式解释的。我在我的中添加了一个解释,以使未来的访问者的生活更轻松。解决代数问题做得很好,感谢您将此作为解决方案的一部分添加:-)
center, radius = define_circle((0,1), (1,0), (0,-1))
if center is not None:
    plt.figure(figsize=(4, 4))
    circle = plt.Circle(center, radius)
    plt.gcf().gca().add_artist(circle)