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中的圆,请参见例如plot a circle with pyplot--在上面的解中,c是(取反的)圆心(作为复数,所以使用.真实的和.imag表示x/y坐标),abs(c+x)是半径(实数,abs使其如此)。
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)
又解决了原来的问题:
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)
5条答案
按热度按时间qc6wkl3g1#
有一个“代码高尔夫”问题与此完全匹配(除了要求圆的方程,而不是绘制它)--参见https://codegolf.stackexchange.com/questions/2289/circle-through-three-points。将第一个也是最短的(Python)解决方案展开为更可读、更简单的形式,以符合您的具体要求--但保留了使用复数进行更简单计算的核心思想:
好的,这仍然是“打印方程”,而不是“绘制圆”,但是,我们已经很接近了:-).要真正绘制
matplotlib
中的圆,请参见例如plot a circle with pyplot--在上面的解中,c
是(取反的)圆心(作为复数,所以使用.真实的和.imag表示x/y坐标),abs(c+x)
是半径(实数,abs
使其如此)。1qczuiv02#
此代码还可让您轻松检查3个点是否形成一条线。
又解决了原来的问题:
(根据here调整)
jslywgbw3#
我非常好奇为什么accepted answer by Alex Martelli能工作,而且我必须为我的演讲做一个报告,所以我把它贴在这里给后代看。
第一次
o4hqfura4#
给定三个点,其坐标为:
(p,t)(q,u)(s,z)
...方程的圆所定义的这三个点是:
x^2 + y^2 + Ax + By + C = 0
其中:
以上是通解。你可以把A、B和C的公式放进你的程序里,找到任何圆的方程,给定3个点。
对于点(0,1)(1,0)(0,-1)的特定问题,您将得到:
A=0
B=0
C=-1
...因此等式为
x^2 + y^2 -1 = 0(单位圆)
xdnvmnnf5#
要在matplotlib中绘制圆,首先需要声明一个艺术家
然后必须将艺术家添加到axes示例中:
那么你就可以安全地画它了。
请注意,艺术家
Circle
取圆心的(x,y)
坐标和半径r
,这意味着你必须自己计算这些值。