Welcome, guest | Sign In | My Account | Store | Cart
```'''Module for physics simulation.

This module provides two classes that allow the
approximation of physics behind bouncing balls.'''

################################################################################

__version__ = '\$Revision: 0 \$'
__date__ = 'February 20, 2007'
__author__ = 'Stephen "Zero" Chappell <my.bios@gmail.com>'
__credits__ = '''\
S. Schaub, for introducing me to programming.
B. Brown, for teaching me some math courses.

################################################################################

import math as _math
import sys as _sys

################################################################################

class Vector:

'Vector(x, y) -> Vector'

def __init__(self, x, y):
'Initialize the Vector object.'
self.x = float(x)
self.y = float(y)

def __repr__(self):
'Return the vector\'s representation.'
return 'Vector(%r, %r)' % (self.x, self.y)

'Return the sum of vector addition.'
return Vector(self.x + vector.x, self.y + vector.y)

def __sub__(self, vector):
'Return the difference of vector subtraction.'
return Vector(self.x - vector.x, self.y - vector.y)

def __mul__(self, number):
'Return the product of vector multiplication.'
return Vector(self.x * number, self.y * number)

def __div__(self, number):
'Return the quotient of vector division.'
return Vector(self.x / number, self.y / number)

self.x += vector.x
self.y += vector.y
return self

def __isub__(self, vector):
'Execute subtraction in-place.'
self.x -= vector.x
self.y -= vector.y
return self

def __imul__(self, number):
'Execute multiplication in-place.'
self.x *= number
self.y *= number
return self

def __idiv__(self, number):
'Execute division in-place.'
self.x /= number
self.y /= number
return self

def __abs__(self):
'Return the vector\'s magnitude.'
return _math.hypot(self.x, self.y)

def unit(self):
'Return the unit vector.'
return self / abs(self)

################################################################################

class Ball:

'Initialize the Ball object.'
self.pos = Vector(x, y)
self.vel = Vector(0, 0)
self.err = Vector(0, 0)

def crash(self, ball):
'Try to crash two balls together.'
p = ball.pos - self.pos
a = abs(p)
v = self.vel - ball.vel
s = _sub(_ang(p), _ang(v))
if s < _PI_D_2:
e =  p * (_math.cos(s) * abs(v) / a)
ball.err += e
self.err -= e

def move(self, frames_per_second):
'Update the ball\'s position.'
self.vel += self.err
self.err = Vector(0, 0)
self.pos += self.vel / frames_per_second

################################################################################

_PI_M_2 = _math.pi * 2
_PI_D_2 = _math.pi / 2

################################################################################

def _ang(vector):
'Private module function.'
return _math.atan2(vector.x, vector.y) % _PI_M_2

def _sub(angle_a, angle_b):
'Private module function.'
diff = abs(angle_a - angle_b)
return _PI_M_2 - diff if diff > _math.pi else diff

################################################################################

if __name__ == '__main__':
_sys.stdout.write('Content-Type: text/plain\n\n')