在tkinter画布上的两点之间绘制一条弧

时间:2016-04-30 18:11:19

标签: python canvas tkinter tkinter-canvas

我的问题很简单:我有两个椭圆,其中心是(x0,y0)和(x1,y1)。 如果我想在它们之间画一条线,我就会这样做 create_line(x0,y0,x1,y1)。

但我想在它们之间画一条弧。我在这里努力学习数学。情况如下:

  • 我有这两个中心:它们必须是椭圆的一部分
  • 这两个点有一个无穷大的椭圆,但是使用tkinter,我们只能绘制水平椭圆。 (对吧?)

我需要:

  • 包含椭圆的矩形的左上角和右下角坐标
  • 起弧角度和弧度

我也在想,也许画弧形是错误的方法?我可以做一些等同于一条线的东西,为此我在该弧上指定了很多点(即使它不是一个实际的弧)

编辑以回答Blindman:

使用tkinter,您可以像这样定义一个弧: http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/create_oval.html 我们不定义椭圆本身,而只定义包含椭圆的矩形的左上角和右下角坐标。

这两个椭圆是如何相互关联的:它们没有。你只需要在画布上的一个随机位置有两个椭圆形,你需要在它们之间有一个弧形。 我希望弧线连接这些椭圆形的两个中心。

最后,如果两个椭圆具有相同的y坐标,这里是我想要的想法:

ellipse

对于任何职位,我想要的就是这个。

和tkinter代码:

import tkinter as tk

class SampleApp(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        self.canvas = tk.Canvas(width=400, height=400)
        self.canvas.pack(fill="both", expand=True)

        self._create_token((100, 100), "white")
        self._create_token((200, 100), "pink")

        self.canvas.create_arc(100, 100 + 10, 200, 100 - 10, extent=180, style=tk.ARC)

    def _create_token(self, coord, color):
        '''Create a token at the given coordinate in the given color'''
        (x,y) = coord
        self.canvas.create_oval(x-5, y-5, x+5, y+5, 
                                outline=color, fill=color, tags="token")

if __name__ == "__main__":
    app = SampleApp()
    app.mainloop()

2 个答案:

答案 0 :(得分:2)

创建弧时有一个start选项,用于定义在给定角度时绘制图形的位置。使用此算法和一些数学运算,您可以使用create_arc - 方法为任何位置绘制弧:

import Tkinter as tk


class SampleApp(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        self.canvas = tk.Canvas(width=400, height=400)
        self.canvas.pack(fill="both", expand=True)

        self._create_token((100, 100), "white")
        self._create_token((200, 300), "pink")
        self._create_arc((100,100), (200, 300))

    def _create_token(self, coord, color):
        '''Create a token at the given coordinate in the given color'''
        (x,y) = coord
        self.canvas.create_oval(x-5, y-5, x+5, y+5, 
                                outline=color, fill=color, tags="token")

    def _create_arc(self, p0, p1):
        extend_x = (self._distance(p0,p1) -(p1[0]-p0[0]))/2 # extend x boundary 
        extend_y = (self._distance(p0,p1) -(p1[1]-p0[1]))/2 # extend y boundary
        startAngle = math.atan2(p0[0] - p1[0], p0[1] - p1[1]) *180 / math.pi # calculate starting angle  
        self.canvas.create_arc(p0[0]-extend_x, p0[1]-extend_y , 
                               p1[0]+extend_x, p1[1]+extend_y, 
                               extent=180, start=90+startAngle, style=tk.ARC)

        '''use this rectangle for visualisation'''
        #self.canvas.create_rectangle(p0[0]-extend_x, p0[1]-extend_y, 
        #                                p1[0]+extend_x, p1[1]+extend_y)       

    def _distance(self, p0, p1):
        '''calculate distance between 2 points'''
        return sqrt((p0[0] - p1[0])**2 + (p0[1] - p1[1])**2)   

if __name__ == "__main__":
    app = SampleApp()
    app.mainloop()

答案 1 :(得分:1)

实际上,我会回答我自己的问题,因为我找到了一个更好的方法。 VRage的答案很好,但是如果你希望弧线更接近两点之间的线,则很难适应。 正确的做法是在段的垂直bissector上使用带有第三个点的线,并结合“平滑”选项。

以下是我想要的一个例子:

Request