问题描述
我正在尝试生成和绘制正弦波。我正在使用我在网上找到的这个公式 y = Amp * sin(2 * PI * frequency * time + shift)
import pygame
import math
import time
window = pygame.display.set_mode((600,600))
class Point:
def __init__(self):
self.x = 0
self.y = 0
class Line:
def __init__(self):
self.points = []
def generateLine(startX,nPoints,length,y):
line = Line()
for i in range(nPoints):
p = Point()
p.x = startX + ((i / nPoints) * length)
p.y = y
line.points.append(p)
return line;
nPoints = 100
line = generateLine(10,590,300)
start = time.time()
accNPoints = 0
frequency = 100
amplitude = 30
overallY = 300
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
window.fill((255,255,255))
keys = pygame.key.get_pressed()
if (keys[pygame.K_a]): frequency -= 0.002
if (keys[pygame.K_d]): frequency += 0.002
if (keys[pygame.K_s]): amplitude -= 0.05
if (keys[pygame.K_w]): amplitude += 0.05
if (keys[pygame.K_q]): overallY += 0.5
if (keys[pygame.K_e]): overallY -= 0.5
if (keys[pygame.K_p]): accNPoints += 0.5
if (keys[pygame.K_o]): accNPoints -= 0.5
if accNPoints > 50:
line = generateLine(10,300)
accNPoints = 0
nPoints += 1
elif accNPoints < -50:
line = generateLine(10,300)
accNPoints = 0
nPoints -= 1
for i in range(1,len(line.points)):
#calculate y based on x
#y = A * sin(2 * PI * f * t + shift)
#yStart = (amplitude * math.sin(2 * math.pi * frequency * ((time.time() - start) * 0.01) + line.points[i].x)) + overallY
#yEnd = (amplitude * math.sin(2 * math.pi * frequency * ((time.time() - start) * 0.01) + line.points[i - 1].x)) + overallY
yStart = (amplitude * math.sin(2 * math.pi * frequency + line.points[i].x)) + overallY
yEnd = (amplitude * math.sin(2 * math.pi * frequency + line.points[i - 1].x)) + overallY
pygame.draw.circle(window,(255,0),(line.points[i].x,yStart),1)
pygame.draw.circle(window,(line.points[i - 1].x,yEnd),1)
pygame.draw.aaline(
window,(0,yEnd)
)
pygame.display.flip()
似乎有两个问题。改变 frequency
值似乎并没有真正改变波的频率。频率似乎取决于生成行的函数中的 nPoints
变量,即 def generateLine(startX,y):
。
解决方法
公式有误。 x 坐标取决于循环的控制变量 (i
)。 y 坐标需要依赖于 x 坐标:
例如:频率 5(5 波)
frequency = 5
amplitude = 50
overallY = 300
while True:
# [...]
no_pts = window.get_width()
for i in range(no_pts):
x = i/no_pts * 2 * math.pi
y = (amplitude * math.cos(x * frequency)) + overallY
if i > 0:
pygame.draw.aaline(window,(0,0),prev_pt,(i,y))
prev_pt = (i,y)
# [...]