class Particle(object): def __init__(self, x=0, y=0, vx=0.0, vy=0.0, size=0, mass=1): self.velocity = Vector(vx, vy) self.mass = mass self.boundCircle = Circle(x, y, size) def setMovable(self): self.mass -= 1000000 def setUnMovable(self): self.mass += 1000000 @property def momentum(self): return self.mass * self.velocity def isBeClicked(self, x, y): l = (self.boundCircle.pos - Vector(x, y)).length() if l < self.boundCircle.radius: # be clicked, set v to zero self.velocity = Vector(0, 0) self.boundCircle.pos.point = (x, y) self.setUnMovable() return True return False def calKinetic(self): return 0.5 * self.mass * (self.velocity.length()**2) def collision(self, obj): ''' 2d collision -- split in two part first -- v parallel to the line connected the two circle center second -- v vertical to the line connected the two circle center inelastic case, both will has the same velocity.... v1' = (m1-m2)v1/(m1+m2) + 2 m2v2/(m1+m2) v2' = (2m1)v1/(m1+m2) + (m2-m1)v2/(m1+m2) ''' if self.boundCircle.isCollision(obj.boundCircle): # compare two circle p1 = obj.boundCircle.pos - self.boundCircle.pos v1, v2 = self.velocity, obj.velocity v1L, v2L = self.velocity.length(), obj.velocity.length() try: rad1 = math.acos(v1.dot(p1) / (p1.length() * v1L)) except: rad1 = 0 try: rad2 = math.acos(v2.dot(-p1) / (p1.length() * v2L)) except: rad2 = 0 v1 = p1.normalize() * v1L * math.cos(rad1) v2 = -p1.normalize() * v2L * math.cos(rad2) m1, m2 = self.mass, obj.mass v1f = (m1 - m2) * v1 / (m1 + m2) + 2 * m2 * v2 / (m1 + m2) v2f = 2 * m1 * v1 / (m1 + m2) + (m2 - m1) * v2 / (m1 + m2) self.velocity = v1f + (self.velocity - v1) obj.velocity = v2f + (obj.velocity - v2) def update(self, dt): # self.velocity*dt = Vector(dx,dy) self.boundCircle.pos += (self.velocity * dt)
class Particle(object): def __init__(self, x=0, y=0, vx=0.0, vy=0.0, size=0, mass=1): self.velocity = Vector(vx, vy) self.mass = mass self.boundCircle = Circle(x, y, size) def setMovable(self): self.mass -= 1000000 def setUnMovable(self): self.mass += 1000000 @property def momentum(self): return self.mass * self.velocity def isBeClicked(self, x, y): l = (self.boundCircle.pos - Vector(x, y)).length() if l < self.boundCircle.radius: # be clicked, set v to zero self.velocity = Vector(0, 0) self.boundCircle.pos.point = (x, y) self.setUnMovable() return True return False def calKinetic(self): return 0.5 * self.mass * (self.velocity.length() ** 2) def collision(self, obj): ''' 2d collision -- split in two part first -- v parallel to the line connected the two circle center second -- v vertical to the line connected the two circle center inelastic case, both will has the same velocity.... v1' = (m1-m2)v1/(m1+m2) + 2 m2v2/(m1+m2) v2' = (2m1)v1/(m1+m2) + (m2-m1)v2/(m1+m2) ''' if self.boundCircle.isCollision(obj.boundCircle): # compare two circle p1 = obj.boundCircle.pos - self.boundCircle.pos v1, v2 = self.velocity, obj.velocity v1L, v2L = self.velocity.length(), obj.velocity.length() try: rad1 = math.acos(v1.dot(p1) / (p1.length() * v1L)) except: rad1 = 0 try: rad2 = math.acos(v2.dot(-p1) / (p1.length() * v2L)) except: rad2 = 0 v1 = p1.normalize() * v1L * math.cos(rad1) v2 = -p1.normalize() * v2L * math.cos(rad2) m1, m2 = self.mass, obj.mass v1f = (m1 - m2) * v1 / (m1 + m2) + 2 * m2 * v2 / (m1 + m2) v2f = 2 * m1 * v1 / (m1 + m2) + (m2 - m1) * v2 / (m1 + m2) self.velocity = v1f + (self.velocity - v1) obj.velocity = v2f + (obj.velocity - v2) def update(self, dt): # self.velocity*dt = Vector(dx,dy) self.boundCircle.pos += (self.velocity * dt)
def test_vector_length(self): v1 = Vector(3, 4) self.assertEqual(v1.length(), 5)