There are a bunch of problems here. I'll fix a few and leave a few for you.
What I fixed was: 1) since you've imported numpy, you should use it, and write things in terms of the vectors; 2) it's an unreasonable demand on yourself to write everything and have it work immediately; so you need to plot intermediate results, etc, like here I plot a
as well, so you can see whether it makes sense; 3) your whole "rotation" approach is confusing; instead think of component parts; which I calculate here directly (it's shorter, easier to read and understand, etc); 4) in all simulations where you use a time step, you should explicitly use dt so you can change the timestep without changing other parameters.
Now if you watch it you can see it looks almost reasonable. Notice though that the acceleration never goes upward, so the ball just falls while it oscillates. The reason for this is that you did not include the tension of the rope into the forces on the ball. I'll leave that part to you.
import pygame
import math
import numpy as np
clock = pygame.time.Clock()
pygame.init()
size = (width, height) = (600,500)
screen = pygame.display.set_mode(size)
class pendulum:
def __init__(self,x,y,x0,y0):
self.x0 = np.array((x0, y0))
self.x = np.array((x, y), dtype=float)
self.v = np.zeros((2,), dtype=float)
self.a = np.zeros((2,), dtype=float)
def CalcForce(self):
dx = self.x0 - self.x
angle = math.atan2(-dx[0], dx[1])
a = g[1]*math.sin(angle) # tangential accelation due to gravity
self.a[0] = at*math.cos(angle)
self.a[1] = at*math.sin(angle)
def move(self):
#print np.dot(self.a, self.x-self.x0) #is a perp to string?
self.x += dt*self.v
self.v += dt*self.a
def draw(self):
pygame.draw.circle(screen, (0,0,0), self.x0, 5)
pygame.draw.line(screen, (0,0,0), self.x0, self.x.astype(int),3)
pygame.draw.circle(screen, (0,0,255), self.x.astype(int), 14,0)
pygame.draw.line(screen, (255, 0, 0), (self.x+200*self.a).astype(int), self.x.astype(int), 4)
dt = .001
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()
for i in range(100): # don't plot every timestep
p.CalcForce()
p.move()
p.draw()
clock.tick(60)
pygame.display.flip()