public void Bounce(Ball2D ball) { foreach (Line2D line in lines) { line.Bounce(ball); } }
public Line2D(double x1, double x2, double y1, double y2) { p1 = new Point2D(x1, y1); p2 = new Point2D(x2, y2); endPoints[0] = new Ball2D(p1, new Point2D(0, 0), 0.005); endPoints[0].Mass = double.MaxValue; endPoints[1] = new Ball2D(p2, new Point2D(0, 0), 0.005); endPoints[1].Mass = double.MaxValue; }
public Line2D(Point2D p1, Point2D p2) { this.p1 = p1; this.p2 = p2; endPoints[0] = new Ball2D(p1, new Point2D(0, 0), 0.005); endPoints[0].Mass = double.MaxValue; endPoints[1] = new Ball2D(p2, new Point2D(0, 0), 0.005); endPoints[1].Mass = double.MaxValue; }
/// <summary> /// Perform the collision between two ball objects, this and other ball /// </summary> /// <param name="otherBall"></param> public void PerformCollision(Ball2D otherBall) { //nothing to do if not colliding if (!IsColliding(otherBall)) { return; } Point2D difference = this - otherBall; double distance = difference.Magnitude; //minimum translation distance //fudge by a small factor of 1.1 to force them to move apart by at least a slight gap Point2D mtd = difference * (this.Radius + otherBall.Radius - distance) / distance * 1.1; //get the reciprocal of the masses double thisMassReciprocal = 1 / mass; double otherMassReciprocal = 1 / otherBall.Mass; //push the balls apart by the minimum translation difference Point2D center = mtd * (thisMassReciprocal / (thisMassReciprocal + otherMassReciprocal)); this.X += center.X; this.Y += center.Y; Point2D otherBallCenter = mtd * (otherMassReciprocal / (thisMassReciprocal + otherMassReciprocal)); otherBall.X -= otherBallCenter.X; otherBall.Y -= otherBallCenter.Y; //now we "normalize" the mtd to get a unit vector of length 1 in the direction of the mtd mtd.Normalize(); //impact the velocity due to the collision Point2D v = this.velocity - otherBall.velocity; double vDotMtd = v * mtd; if (double.IsNaN(vDotMtd)) { return; } if (vDotMtd > 0) { return; //the balls are already moving in opposite directions } //work out collision effect double i = -(1 + elasticity) * vDotMtd / (thisMassReciprocal + otherMassReciprocal); Point2D impulse = mtd * i; //change the balls velocities this.velocity += impulse * thisMassReciprocal; otherBall.velocity -= impulse * otherMassReciprocal; }
/// <summary> /// determine the line that is normal from this line to a ball center /// </summary> /// <param name="ball"></param> /// <returns></returns> public Point2D NormalToBall(Ball2D ball) { Point2D v = p1 - p2; Point2D ballToLine = ball - p1; Point2D normal = v.Normal; //make normal a unit vector normal.Normalize(); if (normal * ballToLine < 0) { normal *= -1; } return(normal); }
public bool Bounce(Ball2D ball) { //determine the normla vector from the line to the ball Point2D normal = NormalToBall(ball); //make a temporary line of this line moved one radius towards ball (bounce off center) Line2D aLineTemp = new Line2D(P1 + normal * ball.Radius, p2 + normal * ball.Radius); //we need to kmow where the ball will be in one step Point2D ballNextStep = ball + ball.Velocity; //make a line from where the ball is now to the location at the next step Line2D ballPath = new Line2D(ball, ballNextStep); //find point of intersection between line and path of the ball Point2D intersectionPoint = aLineTemp.LineIntersectionPoint(ballPath); //perfrom the bounce if necessary //bounce off endpoints if necessary if (endPoints[0].IsColliding(ball)) { endPoints[0].PerformCollision(ball); return(true); } else if (endPoints[1].IsColliding(ball)) { endPoints[1].PerformCollision(ball); return(true); } //if the intersection point is within line segment //and the ball is moving towards the line else if (ball.Velocity.Magnitude < (intersectionPoint - ball).Magnitude && normal * ball.Velocity < 0) { return(false); } else if (aLineTemp.Contains(intersectionPoint) && normal * ball.Velocity < 0) { Line2D reflectionLine = new Line2D(ball + ball.Velocity, intersectionPoint); Point2D velocityDirection = -1 * reflectionLine.Reflection(NormalToBall(ball)); velocityDirection.Normalize(); ball.Velocity = velocityDirection * ball.Velocity.Magnitude * ball.Elasticity; Point2D ballLocation = intersectionPoint - reflectionLine.Reflection(NormalToBall(ball)) * ball.Elasticity; ball.X = ballLocation.X; ball.Y = ballLocation.Y; return(true); } return(false); }
/// <summary> /// Check to see if this ball is colliding with another ball /// </summary> /// <param name="otherBall"></param> /// <returns></returns> public bool IsColliding(Ball2D otherBall) { Point2D distance = this - otherBall; return(distance.Magnitude < this.Radius + otherBall.Radius); }
public Line2D() { p1 = new Point2D(); p2 = new Point2D(); endPoints[0] = new Ball2D(); endPoints[1] = new Ball2D(); }