Tkinter canvas create arc sometimes displays incorrectly

85 Views Asked by At

First time submitting a question.

One of my object visualization programs uses arcs as a connector between lines. The starting angle and extent are calculated. With some combinations of angle and extent, the arc or pie slice appears as an almost complete circle instead of the desired shape.

Like this: Tkinter arc Here is the code that produced this:

import tkinter as tk
import math

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_arc((100,100), (200, 300), 153.2, .570)
        # self._create_arc((200,200), (300, 400), 153.2, .571)
        self._create_arc((100,100), (200, 300), 172.07636660550887, .32)
        self._create_arc((200,200), (300, 400), 172.07636660550887, .50)

    def _create_arc(self, p0, p1, startAngle, ext):
        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
        self.canvas.create_arc(p0[0]-extend_x, p0[1]-extend_y , 
                               p1[0]+extend_x, p1[1]+extend_y, 
                               extent=ext, start=startAngle,
                               style=tk.PIESLICE)

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

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

I am running python 3.10.4. Tcl/Tk version is 8.6

Edit:

The original problem I ran into is with a much larger program that attempts to display the tool path for a CNC. Have a look a this Tkinter arc 2 picture. The object being contoured consists of two lines and a bezier curve. Because GRBL does not support the curve directly, it has to be broken into line segments. These segments are then extended outwards to form the outline. In places where the extended segments don't meet, I have decided to use an arc. As you can see from the picture, some arcs are not displayed correctly. The values for angle and extent in the code segment I posted come from funning the code that formulates the display.

Hope this helps.

1

There are 1 best solutions below

3
WithDueConsideration On

From what I can find, the most probable issue you are facing is based on how the create_arc function is processing the extend parameter. In your code, you are using 0.32 and 0.50 to represent the endpoint angles. Tkinter needs to interpret these angles as degrees like so:

def _create_arc(self, p0, p1, startAngle, ext):
    extend_x = (self._distance(p0,p1) -(p1[0]-p0[0]))/2 # extend x boundary
    extend_y = (self._distance(p0,p1) -(p1[1]-p1[1]))/2 # extend y boundary
    self.canvas.create_arc(p0[0]-extend_x, p0[1]-extend_y ,
                           p1[0]+extend_x, p1[1]+extend_y,
                           extent=ext*360, start=startAngle,
                           style=tk.PIESLICE)

Looking forward to hearing from you.