#!/usr/bin/python # \$Id: bounce.py,v 1.16 2004/06/03 06:28:35 brinkman Exp \$ # (c) 2004, Peter Brinkmann (brinkman@math.uiuc.edu) # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation (http://www.gnu.org/copyleft/gpl.html). import sys from math import * from PySZG import * class Scene: def __init__(self,scene): self.scene=scene def update(self,g=arVector3(0,-9.81,0),dt=0.005): for x in self.scene: x.interact(self.scene,g,dt) class BounceObj: def interact(self,lst,g,dt): pass class Ball(BounceObj): def __init__(self,x=arVector3(0,0,0),v=arVector3(0,0,0), r=1.0,m=1.0,k=500.0,ancestor='world'): self.x=x # location self.v=v # velocity self.m=m # mass self.r=r # radius self.k=k # spring constant self.ID=dgTransform(`self`,ancestor,arMatrix4()) self.mesh=arSphereMesh(40) self.mesh.attachMesh(`self`+'mesh',`self`) self.shape=ar_scaleMatrix(self.r) self.force=arVector3() def bounce(self,x): # implements a simple model of bouncing balls: if flattened by # dx, they'll push back with a force equal to k*dx (Hooke's law) if isinstance(x,Ball): self.bounceOffBall(x) elif isinstance(x,Wall): self.bounceOffWall(x) else: raise "Don't know how to interact with "+`x` def bounceOffWall(self,w): d=(self.x-w.p)%w.n # signed distance from wall w if d>=self.r: return if d<=0: # keep balls from tunneling through walls self.v-=2*(self.v%w.n)*w.n else: self.force+=(self.r-abs(d))*(d/abs(d))*self.k*w.n q=abs(d)/self.r self.shape=self.shape*w.chBasisInv*ar_scaleMatrix( q,sqrt(1/q),sqrt(1/q))*w.chBasis # flatten the sphere appropriately, while preserving volume def bounceOffBall(self,b): v=self.x-b.x if not(self is b) and abs(v)