Pygameで簡単な振り子シミュレーションを書こうとしています。重要なのは、動きを表す微分方程式を解くのではなく、振り子にかかる力(重力と張力)を直接シミュレートしようとしているということです。最初に、ベクトルを取得し、軸システムをある角度で回転させ、このベクトルのコンポーネントを新しい回転した軸システムに返す関数を作成しました。この関数のコードは問題なく、期待どおりに機能します。
シミュレーションの各ティックで、重力ベクトルを振り子とロープの間の角度で回転させ、新しいコンポーネントを取得します。1つはロープの方向に、もう1つはロープに直交します。ロープの方向の張力と成分が互いに打ち消し合うため、直交成分のみが重要です。計算した後、加速度ベクトルを回転させて通常の座標系に戻し、積分します。ただし、結果として生じる動作は意図したとおりではありません。理由は何ですか?
これはコードです:
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()
ありがとうございました。