public MightBeCollision Enact(GridManager gridManager, EventManager eventManager, double endtime) { if (myPhysicsObject.X != start_x || myPhysicsObject.Y != start_y || myPhysicsObject.Vx != start_vx || myPhysicsObject.Vy != start_vy) { return(new MightBeCollision()); } myPhysicsObject.RemoveFromGrid(gridManager); myPhysicsObject.X = myPhysicsObject.X + (Time - myPhysicsObject.Time) * myPhysicsObject.Vx; myPhysicsObject.Y = myPhysicsObject.Y + (Time - myPhysicsObject.Time) * myPhysicsObject.Vy; myPhysicsObject.Time = Time; var dx = otherPhysicsObject.X - myPhysicsObject.X; var dy = otherPhysicsObject.Y - myPhysicsObject.Y; var normal = new Vector(dx, dy).NewUnitized(); callback(myPhysicsObject); EventManager.WhatHappensNext(myPhysicsObject, gridManager, eventManager, endtime); return(new MightBeCollision(new Collision( myPhysicsObject.X + normal.NewScaled((myPhysicsObject as PhysicsObject <Ball>).shape.Radius).x, myPhysicsObject.Y + normal.NewScaled((myPhysicsObject as PhysicsObject <Ball>).shape.Radius).y, normal.x, normal.y, true ))); }
public MightBeCollision Enact(GridManager gridManager, EventManager eventManager, double endtime) { if (physicsObject.X != start_x || physicsObject.Y != start_y || physicsObject.Vx != start_vx || physicsObject.Vy != start_vy) { return(new MightBeCollision()); } physicsObject.RemoveFromGrid(gridManager); physicsObject.X = x; physicsObject.Y = y; physicsObject.Time = Time; WhatHappensNext(physicsObject, gridManager, eventManager, endtime); return(new MightBeCollision()); }
public MightBeCollision Enact(GridManager gridManager, EventManager eventManager, double endTime) { if (physicsObject1.X != start_x1 || physicsObject1.Y != start_y1 || physicsObject2.X != start_x2 || physicsObject2.Y != start_y2 || physicsObject1.Vx != start_vx1 || physicsObject1.Vy != start_vy1 || physicsObject2.Vx != start_vx2 || physicsObject2.Vy != start_vy2) { return(new MightBeCollision()); } physicsObject1.RemoveFromGrid(gridManager); physicsObject2.RemoveFromGrid(gridManager); physicsObject1.X = x1; physicsObject1.Y = y1; physicsObject1.Time = Time; physicsObject2.X = x2; physicsObject2.Y = y2; physicsObject2.Time = Time; // update the V of both // when a collision happen how does it go down? // the velocities we care about are normal to the line // we find the normal and take the dot product var dx = physicsObject1.X - physicsObject2.X; var dy = physicsObject1.Y - physicsObject2.Y; var normal = new Vector(dx, dy).NewUnitized(); var v1 = normal.Dot(physicsObject1.Velocity); var m1 = physicsObject1.Mass; var v2 = normal.Dot(physicsObject2.Velocity); var m2 = physicsObject2.Mass; MightBeCollision res; if (physicsObject1.Mobile == false) { physicsObject2.Velocity = normal.NewScaled(-2 * v2).NewAdded(physicsObject2.Velocity); res = new MightBeCollision(new Collision( physicsObject2.X + normal.NewScaled((physicsObject2 as PhysicsObject <Ball>).shape.Radius).x, physicsObject2.Y + normal.NewScaled((physicsObject2 as PhysicsObject <Ball>).shape.Radius).y, normal.NewScaled(-2 * v2 * m2).x, normal.NewScaled(-2 * v2 * m2).y, false )); } else if (physicsObject2.Mobile == false) { physicsObject1.Velocity = normal.NewScaled(-2 * v1).NewAdded(physicsObject1.Velocity); res = new MightBeCollision(new Collision( physicsObject2.X + normal.NewScaled((physicsObject2 as PhysicsObject <Ball>).shape.Radius).x, physicsObject2.Y + normal.NewScaled((physicsObject2 as PhysicsObject <Ball>).shape.Radius).y, normal.NewScaled(-2 * v1 * m1).x, normal.NewScaled(-2 * v1 * m1).y, false )); } else { // we do the physics and we get a quadratic for vf2 var c1 = (v1 * m1) + (v2 * m2); var c2 = (v1 * v1 * m1) + (v2 * v2 * m2); var A = (m2 * m2) + (m2 * m1); var B = -2 * m2 * c1; var C = (c1 * c1) - (c2 * m1); double vf2; if (A != 0) { // b^2 - 4acS var D = (B * B) - (4 * A * C); if (D >= 0) { var vf2_plus = (-B + Math.Sqrt(D)) / (2 * A); var vf2_minus = (-B - Math.Sqrt(D)) / (2 * A); if (IsGood(vf2_minus, v2) && IsGood(vf2_plus, v2) && vf2_plus != vf2_minus) { if (Math.Abs(v2 - vf2_plus) > Math.Abs(v2 - vf2_minus)) { if (Math.Abs(v2 - vf2_minus) > CLOSE) { throw new Exception("we are getting physicsObject2 vf2s: " + vf2_plus + "," + vf2_minus + " for vi2: " + v2); } vf2 = vf2_plus; } else { if (Math.Abs(v2 - vf2_plus) > CLOSE) { throw new Exception("we are getting physicsObject2 vf2s: " + vf2_plus + "," + vf2_minus + " for vi2: " + v2); } vf2 = vf2_minus; } } else if (IsGood(vf2_minus, v2)) { vf2 = vf2_minus; } else if (IsGood(vf2_plus, v2)) { vf2 = vf2_plus; } else { throw new Exception("we are getting no vfs"); } } else { throw new Exception("should not be negative"); } } else { throw new Exception("A should not be 0! if A is zer something has 0 mass"); } physicsObject2.Velocity = normal.NewScaled(vf2).NewAdded(normal.NewScaled(-v2)).NewAdded(physicsObject2.Velocity); var f = (vf2 - v2) * m2; var vf1 = v1 - (f / m1); physicsObject1.Velocity = normal.NewScaled(vf1).NewAdded(normal.NewScaled(-v1)).NewAdded(physicsObject1.Velocity); res = new MightBeCollision(new Collision( physicsObject2.X + normal.NewScaled((physicsObject2 as PhysicsObject <Ball>).shape.Radius).x, physicsObject2.Y + normal.NewScaled((physicsObject2 as PhysicsObject <Ball>).shape.Radius).y, normal.NewScaled(vf1).x, normal.NewScaled(vf1).y, false )); } WhatHappensNext(physicsObject1, gridManager, eventManager, endTime); WhatHappensNext(physicsObject2, gridManager, eventManager, endTime); return(res); }