// Handles collision with disk (usually player or bullet) public void Collide(Disk disk) { // closest point on the segment to the player Vector2 closePoint = ClosePoint(disk); // closePoint is the one to do all the collision Disk temp = new Disk(closePoint, Vector2.Zero, radius, Color.Transparent); temp.Collide(disk); }
//public void DeterministicMove(float elapsed) //{ // if ((velocity + accel * elapsed).Length() > maxSpeed) // { // float elapsed1 = 0; // if (velocity.Length() < maxSpeed) // { // float dotProduct = Vector2.Dot(velocity, accel); // elapsed1 = (-dotProduct + (float)Math.Sqrt(dotProduct * dotProduct - accel.LengthSquared() * (velocity.LengthSquared() - maxSpeed * maxSpeed))) / accel.LengthSquared(); // position += velocity * elapsed1 + accel * elapsed1 * elapsed1 / 2; // velocity += accel * elapsed1; // } // velocity.Normalize(); // velocity *= maxSpeed; // position += velocity * (elapsed - elapsed1); // } // else // { // position += velocity * elapsed + accel * elapsed * elapsed / 2; // velocity += accel * elapsed; // } //} public void Collide(Disk disk, int colCount = 1) { if (!IfIntersects(disk) || !ifCollides || !disk.ifCollides) { return; } Vector2 direction = position - disk.position; direction.Normalize(); if (mass == float.PositiveInfinity) { if (disk.mass != float.PositiveInfinity) { disk.position = position - direction * (disk.radius + radius); disk.velocity -= 2 * Vector2.Dot(disk.velocity - velocity, direction) * direction; } } else { if (disk.mass == float.PositiveInfinity) { position = disk.position + direction * (disk.radius + radius); velocity -= 2 * Vector2.Dot(velocity - disk.velocity, direction) * direction; } else { //Vector2 center = (position * mass + disk.position * disk.mass) / (mass + disk.mass); //float reducedMass = mass * disk.mass / (mass + disk.mass); //Vector2 positionExchange = (reducedMass * (radius + disk.radius)) * direction; //position = center + positionExchange / mass; //disk.position = center - positionExchange / disk.mass; //float impSpeed = Vector2.Dot(direction, velocity), diskImpSpeed = Vector2.Dot(direction, disk.velocity); //Vector2 finalVel = direction * (mass * impSpeed + disk.mass * diskImpSpeed) / (mass + disk.mass); //force += (-direction * impSpeed + finalVel) * mass / colCount; //disk.force += (-direction * diskImpSpeed + finalVel) * disk.mass / colCount; Vector2 center = (position * mass + disk.position * disk.mass) / (mass + disk.mass); float reducedMass = mass * disk.mass / (mass + disk.mass); Vector2 positionExchange = reducedMass * (radius + disk.radius) * direction; position = center + positionExchange / mass; disk.position = center - positionExchange / disk.mass; float impSpeed = Vector2.Dot(direction, velocity), diskImpSpeed = Vector2.Dot(direction, disk.velocity); Vector2 momentumExchange = reducedMass * 2 * (diskImpSpeed - impSpeed) * direction; force += momentumExchange / colCount; disk.force -= momentumExchange / colCount; } } Collide(); disk.Collide(); }