public void Bounce(Ball2D ball)
 {
     foreach (Line2D line in lines)
     {
         line.Bounce(ball);
     }
 }
Beispiel #2
0
 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;
 }
Beispiel #3
0
 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;
 }
Beispiel #4
0
        /// <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;
        }
Beispiel #5
0
        /// <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);
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        /// <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);
        }
Beispiel #8
0
 public Line2D()
 {
     p1           = new Point2D(); p2 = new Point2D();
     endPoints[0] = new Ball2D();
     endPoints[1] = new Ball2D();
 }