import math

class ball:
	def __init__(self,x,y,mass=1.0):
		self.x = x
		self.y = y
		self.mass = mass
		self.vx = 0
		self.vy = 0

	def move(self):
		#limiter of force, no greater than 1.0
		if self.vx < -1.0:
			self.vx = -1.0
		if self.vx > 1.0:
			self.vx = 1.0
		if self.vy < -1.0:
			self.vy = -1.0
		if self.vy > 1.0:
			self.vy = 1.0
		self.x += self.vx
		self.y += self.vy

def wall(b,w,h):
	if b.x < 0:
		b.x = 1
		b.vx = -b.vx * 0.618
	if b.x > w:
		b.x = w-1
		b.vx = -b.vx * 0.618
	if b.y < 0:
		b.y = 1
		b.vy = -b.vy * 0.618
	if b.y > h:
		b.y = h-1
		b.vy = -b.vy * 0.618

class spring:
	def __init__(self,b1,b2,ratio=0.0707):
		self.b1 = b1
		self.b2 = b2
		self.length = math.hypot(b2.x - b1.x, b2.y - b1.y)
		self.spring = ratio

	def pull(self):
		deltaX = self.b2.x - self.b1.x
		deltaY = self.b2.y - self.b1.y
		length = math.hypot(deltaX, deltaY)
		force = ((length - self.length) * self.spring)/2
		self.b1.vx += deltaX*force
		self.b1.vy += deltaY*force
		self.b2.vx -= deltaX*force
		self.b2.vy -= deltaY*force

if __name__ == "__main__":
	import pyg
	
	balls = []
	springs = []
	center = ball(250,250)
	balls.append(center)
	r = 0.0
	l = 15
	c,e = None,None
	first = None
	first2 = None
	for i in range(15):
		r = i*2*math.pi/l
		x = (math.sin(r) * 50)+center.x
		y = (math.cos(r) * 50)+center.y
		b = ball(x,y)
		x = (math.sin(r) * 60)+center.x
		y = (math.cos(r) * 60)+center.y
		d = ball(x,y)
		balls.append(b)
		balls.append(d)
		springs.append(spring(center,b,0.00618))
		springs.append(spring(b,d))
		if c:
			springs.append(spring(b,c,0.1))
			springs.append(spring(d,e,0.1))
			springs.append(spring(c,d,0.1))
		else:
			first = b
			first2 = d
		c = b
		e = d
	springs.append(spring(c,first,0.1))
	springs.append(spring(e,first2,0.1))
	springs.append(spring(c,first2,0.1))

	while pyg.main():
		for i in balls:
			pyg.circle(i.x,i.y)
			i.vy += 0.618
			wall(i,pyg.width,pyg.height)
			i.move()
		for i in springs:
			i.pull()
			pyg.line(i.b1.x, i.b1.y, i.b2.x, i.b2.y)
