如何在python tkinter canvas中使用create_line创建五边形和六边形?

时间:2019-04-25 05:37:00

标签: python python-3.x tkinter geometry tkinter-canvas

这是我使用create_lines在python tkinter画布中绘制三角形和正方形的代码,我将如何使用create_lines创建五边形和六边形?

注意:对于五边形和六边形,长度和宽度是指形状所包含的总正方形区域,而不是侧面的宽度和长度。

valueB

1 个答案:

答案 0 :(得分:1)

要从边界框创建规则的多边形,您需要计算边长和振幅。
边长是根据半径(从中心到顶点的距离)计算的
Apothem(从中心到侧面的中点的距离)是根据侧面的长度计算得出的。
more here

在下面的示例中,bbox位于所创建多边形的中心;您可以根据需要将其偏移以匹配您的首选锚点。

在同一个边界框内,所有多边形被计算为内接在同一圆上-外接圆,这是边数趋于无穷大时多边形的极限,请参见下图。

import tkinter as tk
import math


WIDTH, HEIGHT = 500, 500


class Point:
    """convenience for point arithmetic"""
    def __init__(self, x, y):
        self.x, self.y = x, y
    def __add__(self, other):
        return Point(self.x + other.x, self.y + other.y)
    def __iter__(self):
        yield self.x
        yield self.y


class RegularPolygon:

    def __init__(self, num_sides, bbox_side, x, y):   # x, y are bbox center canvas coordinates
        self.bbox_side = bbox_side
        self.num_sides = num_sides
        self.side_length = None
        self.apothem = None
        self._calc_side_length()
        self.points = [Point(x - self.side_length // 2, y - self.apothem)]
        self._make_points()
        self.lines = []
        self._make_lines()

    def _calc_side_length(self):
        """Side length given the radius (circumradius):
        i/e the distance from the center to a vertex
        """
        self.side_length = 2 * (self.bbox_side // 2) * math.sin(math.pi / self.num_sides)

        # Apothem, i/e distance from the center of the polygon 
        # to the midpoint of any side, given the side length 
        self.apothem = self.side_length / (2 * math.tan(math.pi / self.num_sides))

    def _make_points(self):
        _angle = 2 * math.pi / self.num_sides
        for pdx in range(self.num_sides):
            angle = _angle * pdx
            _x = math.cos(angle) * self.side_length
            _y = math.sin(angle) * self.side_length
            self.points.append(self.points[-1] + Point(_x, _y))

    def _make_lines(self):
        for p0, p1 in zip(self.points[:-1], self.points[1:]):
            self.lines.append((*p0, *p1))

    def draw(self, canvas):
        for line in self.lines:
            canvas.create_line(line)
        # alternatively, use canvas.create_polygon(points coordinates) instead


root = tk.Tk()

canvas = tk.Canvas(root, width=WIDTH, height=HEIGHT, bg="cyan")
canvas.pack()

CENTER = Point(WIDTH // 2, HEIGHT // 2)

for n_sides in range(3, 12):
    p = RegularPolygon(n_sides, 300, *CENTER)
    p.draw(canvas)


root.mainloop()  

从3到12个面(包括边)绘制常规多边形

enter image description here

在相同的边界框内,所有多边形被计算为内接在同一圆(外接圆)上。

enter image description here