# copied from KineticsKit - http://kineticskit.sourceforge.net/ # modified to remove it from visual # May 2003 class Physics: """Mass Spring simulation """ def __init__(self, timestep, oversample=1, gravity=None, viscosity=None): """Construct a system. """ self.timestep = timestep self.rate = 1.0 / timestep self.oversample = oversample self.gravity = gravity self.viscosity = viscosity self.masses = [] self.springs = [] self.dragObject = None self.click = None self.distance = None self.rememberFixed = None self.rememberColor = None def insertMass(self, mass): """Insert mass into the system. """ self.masses.append(mass) def insertMassList(self, masslist): """Insert all Masses in masslist into the system. """ map(self.insertMass, masslist) def insertSpring(self, spring): """Insert spring into the system. """ self.springs.append(spring) def insertSpringList(self, springlist): """Insert all Springs in springlist into the system. """ map(self.insertSpring, springlist) def advance(self): """Perform one Iteration of the system by advancing one timestep. """ microstep = self.timestep / self.oversample for i in range(self.oversample): for spring in self.springs: spring.calcSpringForce() if spring.damping: spring.calcDampingForce() for mass in self.masses: if not mass.fixed: if self.gravity: mass.calcGravityForce(self.gravity) if self.viscosity: mass.calcViscosityForce(self.viscosity) mass.calcNewLocation(microstep) mass.clearForce() def step(self): """Perform one step. This is a convenience method. It actually calls dispatchDnD() and advance(). """ # self.dispatchDnD() self.advance() # visual.rate(self.rate) # best when placed after advance() and before dispatchDnD() def SetGravity(self, graveness): self.gravity = graveness def SetViscosity(self, stiffness): self.viscosity = stiffness