import random import math class Particle(object): """Describes a particle in 2D, with position, direction, and speed.""" # Primitive methods begin here. ############################################ def __init__(self, x, y, dir, speed): """Initializes the particle with (x, y) position, direction of movement, and speed of movement.""" self.setXY((x, y)) # Set the speed manually, because self.setSpeed() requires direction. self.speed = speed self.setDirection(dir) def getXY(self): """Returns the (x, y) position of the particle, as a tuple.""" return self.xy def setXY(self, xy): """Sets the (x, y) position of the particle to the given tuple.""" self.xy = xy def getDirection(self): """Returns the direction of movement of the particle, as an angle in radians, measured counterclockwise from east.""" return self.dir def setDirection(self, dir): """Sets the direction of movement of the particle, as an angle in radians, measured counterclockwise from east.""" self.dir = dir # Update the velocity vector. self.v = (self.speed * math.cos(self.dir), self.speed * math.sin(self.dir)) def getSpeed(self): """Returns the speed of the particle in distance/second.""" return self.speed def setSpeed(self, speed): """Sets the speed of the particle in distance/second.""" self.speed = speed # Update the velocity vector. self.v = (self.speed * math.cos(self.dir), self.speed * math.sin(self.dir)) def updatePosition(self, delta): """Updates the particle's position by advancing time delta seconds.""" self.setXY((self.xy[0] + delta * self.v[0], self.xy[1] + delta * self.v[1])) def getVelocity(self): """Returns the velocity vector as a tuple (vx, vy).""" return self.v # Convenience methods begin here. ########################################## def setX(self, x): """Sets the x-position of the particle, leaving the y-position unchanged.""" self.setXY((x, self.getXY()[1])) def setY(self, y): """Sets the y-position of the particle, leaving the x-position unchanged.""" self.setXY((self.getXY()[0], y)) def setVelocity(self, v): """Sets the velocity vector of the particle as a tuple v = (vx, vy).""" # The speed is the length of the velocity vector. self.setSpeed(math.sqrt(v[0]**2 + v[1]**2)) # The direction is computed using arctangent, with some special cases. if v[0] == 0.0: if v[1] == 0.0: # There is no well-defined direction; arbitrarily pick 0.0. self.setDirection(0.0) elif v[1] > 0.0: self.setDirection(0.5 * math.pi) else: self.setDirection(-0.5 * math.pi) elif v[0] > 0.0: self.setDirection(math.atan(v[1] / v[0])) else: self.setDirection(math.atan(v[1] / v[0]) - math.pi) # If the user ran (rather than imported) this file, then run the demo. if __name__ == "__main__": # Make a particle with random position and velocity. x = random.random() * 256.0 + 128.0 y = random.random() * 256.0 + 128.0 dir = random.random() * 2.0 * math.pi speed = random.random() * 10.0 particle = Particle(x, y, dir, speed) # See where the particle goes for a few seconds. print particle.getXY() particle.updatePosition(1.0) print particle.getXY() particle.updatePosition(1.0) print particle.getXY() particle.updatePosition(1.0) print particle.getXY() particle.updatePosition(1.0) print particle.getXY()