gpt4 book ai didi

python - 在 Tkinter Canvas 上旋转一个正方形

转载 作者:行者123 更新时间:2023-11-28 21:47:22 24 4
gpt4 key购买 nike

我已经很接近了,但是有两个问题。一个是旋转正方形的最终位置(不再位于中心)。第二个是我的原始顶点列表发生了变化,尽管我使用 list(..) 制作了一个副本。

像往常一样非常感谢您的帮助。

from Tkinter import *
import math


WIDTH = 400
HEIGHT = 400
CANVAS_MID_X = WIDTH/2
CANVAS_MID_Y = HEIGHT/2
SIDE = WIDTH/4

root = Tk()
canvas = Canvas(root, bg="black", height=HEIGHT, width=WIDTH)
canvas.pack()

vertices = [
[CANVAS_MID_X - SIDE/2, CANVAS_MID_Y - SIDE/2],
[CANVAS_MID_X + SIDE/2, CANVAS_MID_Y - SIDE/2],
[CANVAS_MID_X + SIDE/2, CANVAS_MID_Y + SIDE/2],
[CANVAS_MID_X - SIDE/2, CANVAS_MID_Y + SIDE/2]]

def rotate(points, angle):
new_points = list(points)
rad = angle * (math.pi/180)
cos_val = math.cos(rad)
sin_val = math.sin(rad)
for coords in new_points:
x_val = coords[0]
y_val = coords[1]
coords[0] = x_val * cos_val - y_val * sin_val
coords[1] = x_val * sin_val + y_val * cos_val
return new_points

def draw_square(points):
canvas.create_polygon(points, fill="red")

def test():
print "vertices: ", vertices, "should be: ", "[[150, 150], [250, 150], [250, 250], [150, 250]]"


new_square = rotate(vertices, 30)
draw_square(new_square)
test()
mainloop()

最佳答案

您的第一个问题是您使用的公式围绕原点旋转。我假设您想围绕其中心旋转正方形。为此,您只需平移正方形,使其中心位于原点,旋转它,然后再平移回来。

第二个问题是 list(points) 确实创建了一个新的外部列表,但它没有points 中的列表。有一些方法可以制作深拷贝,为这些内部列表创建新列表,但您实际上不需要在此处执行此操作。只需从旋转的顶点构建一个新列表。

我的代码版本以蓝色绘制原始正方形,以便我们可以看到旋转后的正方形最终位于正确的位置。

from Tkinter import *
import math

WIDTH = 400
HEIGHT = 400
CANVAS_MID_X = WIDTH/2
CANVAS_MID_Y = HEIGHT/2
SIDE = WIDTH/4

root = Tk()
canvas = Canvas(root, bg="black", height=HEIGHT, width=WIDTH)
canvas.pack()

vertices = [
[CANVAS_MID_X - SIDE/2, CANVAS_MID_Y - SIDE/2],
[CANVAS_MID_X + SIDE/2, CANVAS_MID_Y - SIDE/2],
[CANVAS_MID_X + SIDE/2, CANVAS_MID_Y + SIDE/2],
[CANVAS_MID_X - SIDE/2, CANVAS_MID_Y + SIDE/2],
]

def rotate(points, angle, center):
angle = math.radians(angle)
cos_val = math.cos(angle)
sin_val = math.sin(angle)
cx, cy = center
new_points = []
for x_old, y_old in points:
x_old -= cx
y_old -= cy
x_new = x_old * cos_val - y_old * sin_val
y_new = x_old * sin_val + y_old * cos_val
new_points.append([x_new + cx, y_new + cy])
return new_points

def draw_square(points, color="red"):
canvas.create_polygon(points, fill=color)

def test():
old_vertices = [[150, 150], [250, 150], [250, 250], [150, 250]]
print "vertices: ", vertices, "should be: ", old_vertices
print vertices == old_vertices

draw_square(vertices, "blue")

center = (CANVAS_MID_X, CANVAS_MID_Y)
new_square = rotate(vertices, 30, center)
test()
draw_square(new_square)

mainloop()

我还对您的代码做了一些其他的小改动。

顺便说一句,你可能应该这样做

from __future__ import division

在您的其他导入之前。这告诉 Python 使用真除法。没有它,SIDE/2 进行整数除法。这在这里工作正常,但如果 SIDE 是奇数,它将不正确。


你应该试着改掉这样做的习惯

from Tkinter import *

相反,做

import Tkinter as tk

然后像这样调用 Tkinter 函数:

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

这稍微多了一些输入,但它使代码更易于阅读和维护,并防止当您的代码意外使用 Tkinter 定义的名称之一时可能发生的错误。 FWIW,执行 from Tkinter import * 将超过 170 个名称导入您的命名空间。你不需要那么困惑!

关于python - 在 Tkinter Canvas 上旋转一个正方形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36620766/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com