我想在Pygame中編寫簡單的鐘擺模擬。重點是我試圖直接模擬擺錘上的力(重力和張力),而不是求解描述運動的微分方程。首先我寫了一個函數,它獲得一個矢量,以某個角度旋轉軸系,並將這個矢量的分量返回到新的旋轉軸系統;這個函數的代碼很好,它按預期工作。鐘擺模擬
模擬中的每個勾號I將重力矢量旋轉擺錘和繩索之間的角度,並獲得新組件 - 一個在繩索方向,一個與其正交。繩索方向上的張力和分量相互抵消,因此只有正交分量是重要的。計算完後,我將加速度矢量旋轉回正常座標系並進行積分。但是,由此產生的行爲並非如預期的那樣。可能是什麼原因?
這是代碼:
from __future__ import division
import copy
import pygame
import random
import math
import numpy as np
import time
clock = pygame.time.Clock()
pygame.init()
size = (width, height) = (600,500)
screen = pygame.display.set_mode(size)
def rotate(vector,theta):
#rotate the vector by theta radians around the x-axis
Vx,Vy = vector[0],vector[1]
cos,sin = math.cos(theta),math.sin(theta)
newX,newY = Vx*cos-Vy*sin, Vy*cos+Vx*sin #the newX axis is the result of rotating x axis by theta
return [newX,newY]
class pendulum:
def __init__(self,x,y,x0,y0):
self.x = x
self.y = y
self.x0 = x0
self.y0 = y0
self.velocity = [0,0]
self.a= [0,0]
self.angle = 0
def CalcForce(self):
self.angle = math.atan2(-(self.y-self.y0),self.x-self.x0)
gravity = rotate(g,self.angle)
self.a[1]=gravity[1]
self.a[0] = 0 #This component is cancelled by the tension
self.a = rotate(self.a,-self.angle)
def move(self):
#print pylab.dot(self.velocity,[self.x-self.x0,self.y-self.y0])
self.velocity[0]+=self.a[0]
self.velocity[1]+=self.a[1]
self.x+=self.velocity[0]
self.y+=self.velocity[1]
def draw(self):
pygame.draw.circle(screen, (0,0,0), (self.x0,self.y0), 5)
pygame.draw.line(screen, (0,0,0), (self.x0,self.y0), (int(self.x), int(self.y)),3)
pygame.draw.circle(screen, (0,0,255), (int(self.x),int(self.y)), 14,0)
g = [0,0.4]
p = pendulum(350,100,300,20)
while 1:
screen.fill((255,255,255))
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
p.CalcForce()
p.move()
p.draw()
clock.tick(60)
pygame.display.flip()
謝謝。
你看到了什麼意外的行爲? – theJollySin 2013-03-19 21:34:05
運動不是週期性運動。 – user1767774 2013-03-19 21:50:18
可能不相關,但我看到你正在使用整數而不是浮點數來表示矢量。這可能會導致問題。 – ninMonkey 2013-03-19 22:30:10