给3分和一个情节圈
Give 3 points and a plot circle
我想将点 [0,1]、[1,0] 和 [0,-1] 赋予 python 并绘制经过它们的圆。是否存在一个 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
。这意味着您将不得不自己计算这些值。
有一个 "code golf" 问题与此完全匹配(除了要求圆的方程式,而不是绘制它)——参见 https://codegolf.stackexchange.com/questions/2289/circle-through-three-points 。将第一个和最短的 (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))
好的,这仍然是 "prints the equation" 而不是 "plotting the circle",但是,我们越来越接近了:-)。要实际 绘制 matplotlib
中的圆,参见例如 plot a circle with pyplot——在上面的解决方案中,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)
并解决原题:
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)
(根据 here 调整)
我 非常 好奇为什么 有效。无论如何,我必须为我的讲座创建一个报告,所以我将它粘贴在这里以供后代使用。
我想将点 [0,1]、[1,0] 和 [0,-1] 赋予 python 并绘制经过它们的圆。是否存在一个 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
。这意味着您将不得不自己计算这些值。
有一个 "code golf" 问题与此完全匹配(除了要求圆的方程式,而不是绘制它)——参见 https://codegolf.stackexchange.com/questions/2289/circle-through-three-points 。将第一个和最短的 (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))
好的,这仍然是 "prints the equation" 而不是 "plotting the circle",但是,我们越来越接近了:-)。要实际 绘制 matplotlib
中的圆,参见例如 plot a circle with pyplot——在上面的解决方案中,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)
并解决原题:
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)
(根据 here 调整)
我 非常 好奇为什么