【问题标题】:Give 3 points and a plot circle给3分和一个情节圈
【发布时间】:2015-05-08 18:17:50
【问题描述】:

我想将点 [0,1],[1,0] 和 [0,-1] 提供给 python 并绘制经过它们的圆。是否存在一个可以做到这一点的python模块?我尝试过使用 matplotlib:

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

但只给了我两行。

【问题讨论】:

    标签: python matplotlib plot


    【解决方案1】:

    有一个与此完全匹配的“代码高尔夫”问题(除了要求圆的方程式,而不是绘制它)——请参阅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))
    

    好的,这仍然是“打印方程式”而不是“绘制圆圈”,但是,我们已经接近了:-)。要真正绘制matplotlib 中的圆,请参见例如plot a circle with pyplot——在上面的解决方案中,c 是圆的(取反)中心(作为复数,所以使用 . real 和 .imag 用于 x/y 坐标),abs(c+x) 半径(实数,abs 是这样)。

    【讨论】:

    • 这是有用的,因为我将使用复数。我忘了用这种方式更容易获得中心和半径。
    • 我想看到你的昵称清楚地纪念 Évariste Galois 引导我的潜意识走向这个数学上优雅的想法:-)。想起一个在我 1/3 岁时去世的人,只留下了 60 页笔记,彻底改变了 两个 数学的关键分支,让我保持谦虚(另外,我是 1/8 的法国人,所以也有助于让我保持适当的自豪感:-)。
    • 很高兴见到认识他的人。我是一个代数爱好者,因为他的发现:-)。
    • 我不记得我是否在某个时候了解过他是如何做到的,因为正如他所说,他从一个代码高尔夫问题中改编了一个解决方案,但我记得我在寻找我的用自己的方法来计算它,因为唯一让我兴奋的是“复数”这个短语。事实上,我认为您的链接更容易发布,因为它以扩展的方式进行了解释。
    • @iam_agf 我现在知道了!我在answer 中添加了一个解释,让未来的访问者生活更轻松。
    【解决方案2】:

    此代码还可以让您轻松检查 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调整)

    【讨论】:

      【解决方案3】:

      给定三个坐标:

      (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(单位圆)

      【讨论】:

        【解决方案4】:

        非常很好奇accepted answer by Alex Martelli 为何有效。无论如何,我必须为我的演讲创建一个报告,所以我将它粘贴在这里以供后代使用。

        【讨论】:

        • 很好地解决了代数问题,感谢您将其添加为解决方案的一部分 :-)
        【解决方案5】:

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

        circle = plt.Circle((0,0), 2)
        

        然后您必须将该艺术家添加到轴的实例中:

        fig, ax = plt.subplots()
        ax.add_artist(circle)
        

        那么你就可以放心地画了。

        plt.show()
        

        请注意,艺术家Circle 采用圆心的(x,y) 坐标和半径r。这意味着您将不得不自己计算这些值。

        【讨论】:

          猜你喜欢
          • 2020-08-05
          • 2015-02-22
          • 1970-01-01
          • 2018-05-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-04-11
          相关资源
          最近更新 更多