gpt4 book ai didi

python - 使用 Python 和 Tkinter 的傅里叶级数/变换中的 Missalgined 圆

转载 作者:行者123 更新时间:2023-12-05 03:28:24 25 4
gpt4 key购买 nike

我制作了一个傅立叶级数/变换 Tkinter 应用程序,到目前为止,一切都按我想要的方式运行,除了我遇到了圆圈未对齐的问题。这是一张解释我的问题的图片(事后添加了绿色和粉红色以更好地解释问题):

enter image description here

我已将问题缩小到线条的开头,因为它们似乎在正确的位置结束,圆圈也在正确的位置。正确位置和线条开始位置之间的距离似乎在增长,但实际上与圆圈旋转的速度成正比,因为圆圈旋转的幅度越大,因此转得越快。

代码如下:

from tkinter import *
import time
import math
import random
root = Tk()
myCanvas = Canvas(root, width=1300, height=750)
myCanvas.pack()
myCanvas.configure(bg="#0A2239")

global x,y, lines, xList, yList


NumOfCircles = 4

rList = [200]
n=3
for i in range(0, NumOfCircles):
rList.append(rList[0]/n)
n=n+2
print(rList)

num = 250/sum(rList)

for i in range(0, NumOfCircles):
rList[i] = rList[i]*num



x=0
y=0
lines = []
circles = []

centerXList = [300]
for i in range(0,NumOfCircles):
centerXList.append(0)

centerYList = [300]
for i in range(0,NumOfCircles):
centerYList.append(0)

xList = [0]*NumOfCircles
yList = [0]*NumOfCircles

waveLines = []
wavePoints = []
con=0



endCoord = []
for i in range(0, NumOfCircles):
endCoord.append([0,0])

lastX = 0
lastY = 0

count = 0

randlist = []
n=1
for i in range(0, NumOfCircles):
randlist.append(200/n)
n=n+2

def createCircle(x, y, r, canvasName):
x0 = x - r
y0 = y - r
x1 = x + r
y1 = y + r
return canvasName.create_oval(x0, y0, x1, y1, width=r/50, outline="#094F9A")

def updateCircle(i):
newX = endCoord[i-1][0]
newY = endCoord[i-1][1]
centerXList[i] = newX
centerYList[i] = newY
x0 = newX - rList[i]
y0 = newY - rList[i]
x1 = newX + rList[i]
y1 = newY + rList[i]
myCanvas.coords(circles[i], x0, y0, x1, y1)


def circleWithLine(i):
global line, lines
circle = createCircle(centerXList[i], centerYList[i], rList[i], myCanvas)
circles.append(circle)
line = myCanvas.create_line(centerXList[i], centerYList[i], centerXList[i], centerYList[i], width=2, fill="#1581B7")
lines.append(line)


def update(i, x, y):
endCoord[i][0] = x+(rList[i]*math.cos(xList[i]))
endCoord[i][1] = y+(rList[i]*math.sin(yList[i]))
myCanvas.coords(lines[i], x, y, endCoord[i][0], endCoord[i][1])
xList[i] += (math.pi/randlist[i])
yList[i] += (math.pi/randlist[i])

def lineBetweenTwoPoints(x, y, x2, y2):
line = myCanvas.create_line(x, y, x2, y2, fill="white")
return line

def lineForWave(y1, y2, y3, y4, con):
l = myCanvas.create_line(700+con, y1, 702+con, y2, 704+con, y3, 706+con, y4, smooth=1, fill="white")
waveLines.append(l)

for i in range(0,NumOfCircles):
circleWithLine(i)

myCanvas.create_line(700, 20, 700, 620, fill="black", width = 3)
myCanvas.create_line(700, 300, 1250, 300, fill="red")

myCanvas.create_line(0, 300, 600, 300, fill="red", width = 0.5)
myCanvas.create_line(300, 0, 300, 600, fill="red", width = 0.5)

while True:
for i in range(0, len(lines)):
update(i, centerXList[i], centerYList[i])
for i in range(1, len(lines)):
updateCircle(i)
if count >= 8:
lineBetweenTwoPoints(lastX, lastY, endCoord[i][0], endCoord[i][1])
if count % 6 == 0 and con<550:
lineForWave(wavePoints[-7],wavePoints[-5],wavePoints[-3],wavePoints[-1], con)
con += 6
wavePoints.append(endCoord[i][1])
myCanvas.update()



lastX = endCoord[i][0]
lastY = endCoord[i][1]

if count != 108:
count += 1
else:
count = 8

time.sleep(0.01)



root.mainloop()

我知道这不是实现我想要实现的目标的最佳方法,因为使用类会好得多。我打算这样做,以防万一没人能找到解决方案,并希望重写时不会再出现这个问题。

最佳答案

您面临的主要问题是您从计算中收到 float ,但您只能对像素使用整数。在下文中,我将向您展示您失败的地方以及解决问题的最快方法。

首先你的目标是连接线,你在这里计算点数:

def update(i, x, y):
endCoord[i][0] = x+(rList[i]*math.cos(xList[i]))
endCoord[i][1] = y+(rList[i]*math.sin(yList[i]))
myCanvas.coords(lines[i], x, y, endCoord[i][0], endCoord[i][1])
xList[i] += (math.pi/randlist[i])
yList[i] += (math.pi/randlist[i])

当您将以下代码添加到此函数中时,您会发现它在那里失败了。

if i != 0:
print(i,x,y)
print(i,endCoord[i-1][0], endCoord[i-1][1])

因为 xy 应该始终与最后一个点(上一行的结尾)匹配,即 endCoord[i-1][0] endCoord[i-1][1]

为了解决您的问题,我只是跳过了 后续行 起始点的匹配,并使用以下替代函数获取了前一行的坐标:

def update(i, x, y):
endCoord[i][0] = x+(rList[i]*math.cos(xList[i]))
endCoord[i][1] = y+(rList[i]*math.sin(yList[i]))
if i == 0:
points = x, y, endCoord[i][0], endCoord[i][1]
else:
points = endCoord[i-1][0], endCoord[i-1][1], endCoord[i][0], endCoord[i][1]
myCanvas.coords(lines[i], *points)
xList[i] += (math.pi/randlist[i])
yList[i] += (math.pi/randlist[i])

其他建议是:

  • 不要使用通配符导入
  • 仅导入您在代码中真正使用的内容 随机 未在您的示例中使用
  • global 命名空间中使用global 是没有用的
  • 创建函数以避免重复代码

def listinpt_times_circles(inpt):
return [inpt]*CIRCLES

x_list = listinpt_times_circles(0)
y_list = listinpt_times_circles(0)
center_x_list = listinpt_times_circles(0)
center_x_list.insert(0,300)
center_y_list = listinpt_times_circles(0)
center_y_list.insert(0,300)
  • 使用 .after(ms,func,*args) 而不是中断 while 循环和阻塞调用 time.sleep

def animate():
global count,con,lastX,lastY
for i in range(0, len(lines)):
update(i, centerXList[i], centerYList[i])
for i in range(1, len(lines)):
updateCircle(i)
if count >= 8:
lineBetweenTwoPoints(lastX, lastY, endCoord[i][0], endCoord[i][1])
if count % 6 == 0 and con<550:
lineForWave(wavePoints[-7],wavePoints[-5],wavePoints[-3],wavePoints[-1], con)
con += 6
wavePoints.append(endCoord[i][1])
myCanvas.update_idletasks()

lastX = endCoord[i][0]
lastY = endCoord[i][1]

if count != 108:
count += 1
else:
count = 8

root.after(10,animate)

animate()
root.mainloop()

list_of_radii = [200] #instead of rList

  • 如前所述,像素将用整数而不是 float 表示

myCanvas.create_line(0, 300, 600, 300, fill="red", width = 1) #0.5 has no effect compare 0.1 to 1

关于python - 使用 Python 和 Tkinter 的傅里叶级数/变换中的 Missalgined 圆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71271840/

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