public void AddCircle(MovingCircle c)
 {
     World.Objects.Add(c);
     Canvas.Children.Add(c.circle);
     Canvas.SetLeft(c.circle, c.Position.X);
     Canvas.SetTop(c.circle, c.Position.Y);
 }
예제 #2
0
        public void CalculateSpeedAndPositionFromCollisions(MovingCircle obj, int myIndex, int len)
        {
            // We only detect collisions for bodies after us in the list
            for (int i = myIndex + 1; i < len; ++i)
            {
                MovingCircle other = Objects[i];

                Vector centerToCenter = (other.Center - obj.Center);
                double centerToCenterLen = centerToCenter.Length;

                // If they collide
                if ( centerToCenterLen <= other.Radius + obj.Radius )
                {
                    // We get the translation necessary to move one
                    Vector a = centerToCenter * (obj.Radius / centerToCenterLen);
                    Vector b = centerToCenter * (centerToCenterLen - other.Radius) / centerToCenterLen;
                    Vector middle = (a - b) / 2;

                    obj.Position -= middle;
                    other.Position += middle;

                    // Now we've positioned the cicles, we can normalize the centerToCenter vector in order to convert it into a unit vector
                    centerToCenter.Normalize();

                    // http://ericleong.me/research/circle-circle/#static-circle-circle-collision-detection
                    double p = 2 * (obj.Speed.X * centerToCenter.X + obj.Speed.Y * centerToCenter.Y - other.Speed.X * centerToCenter.X - other.Speed.Y * centerToCenter.Y) / (obj.Mass + other.Mass);
                    obj.Speed = new Vector(obj.Speed.X - p * other.Mass * centerToCenter.X,
                                           obj.Speed.Y - p * other.Mass * centerToCenter.Y)
                                           * obj.BounceFactor;
                    other.Speed = new Vector(other.Speed.X + p * obj.Mass * centerToCenter.X,
                                             other.Speed.Y + p * obj.Mass * centerToCenter.Y)
                                             * other.BounceFactor;
                    /* Original: Seems to have switched both masses, since a high-mass sphere bounces like heck
                    obj.Speed = new Vector(obj.Speed.X - p * obj.Mass * centerToCenter.X,
                                           obj.Speed.Y - p * obj.Mass * centerToCenter.Y)
                                           * obj.BounceFactor;
                    other.Speed = new Vector(other.Speed.X + p * other.Mass * centerToCenter.X,
                                             other.Speed.Y + p * other.Mass * centerToCenter.Y)
                                             * other.BounceFactor;
                    */
                }
            }

            if (obj.Position.Y < 0) {
                obj.Speed = new Vector(obj.Speed.X, Math.Abs(obj.Speed.Y) * obj.BounceFactor);
                obj.Position = new Point(obj.Position.X, 0);
            } else if (obj.Position.Y + obj.Diameter > this.Height) {
                obj.Speed = new Vector(obj.Speed.X, -Math.Abs(obj.Speed.Y) * obj.BounceFactor);
                obj.Position = new Point(obj.Position.X, this.Height - obj.Diameter);
            }

            if (obj.Position.X < 0) {
                obj.Position = new Point(0, obj.Position.Y);
                obj.Speed = new Vector(-obj.Speed.X * obj.BounceFactor, obj.Speed.Y);
            } else if (obj.Position.X + obj.Diameter > this.Width) {
                obj.Position = new Point(this.Width - obj.Diameter, obj.Position.Y);
                obj.Speed = new Vector(-obj.Speed.X * obj.BounceFactor, obj.Speed.Y);
            }
        }
예제 #3
0
        public Vector force(MovingCircle obj, int myIndex, int len)
        {
            Vector f = PrecalculatedDeltaFCache[myIndex];

            // Vector f = new Vector(0.0, 9.8) * obj.Mass
            // Actually the gravity is in px/s/s... Lol
            f += new Vector(0.0, this.Gravity) * obj.Mass; // Gravity

            // We only detect collisions for bodies after us in the list
            for (int i = myIndex + 1; i < len; ++i)
            {
                MovingCircle other = Objects[i];

                Vector centerToCenter = (other.Center - obj.Center);

                // If they collide
                // NOTE: Instead of length < o1.radius + o2.radius we use LengthSquared, since it's faster
                // (Obtaining the length needs a square root)
                if ( centerToCenter.LengthSquared < other.Radius * other.Radius + obj.Radius * obj.Radius )
                {
                    // Now we've positioned the cicles, we can normalize the centerToCenter vector in order to convert it into a unit vector
                    centerToCenter.Normalize();

                    // Add the linear momentum and substract the normal
                    f += other.Speed * other.Mass;
                    f -= obj.Speed * obj.Mass;

                    PrecalculatedDeltaFCache[i] += obj.Speed * obj.Mass;
                    PrecalculatedDeltaFCache[i] -= other.Speed * other.Mass;
                }
            }

            // if ( object touches boundary )
            //     f += normal; (f = 0);
            // TODO: Consider using < instead of <=
            if (obj.Position.Y < 0) {
                if (Gravity < 0)
                    f += new Vector(0, obj.Mass * -this.Gravity);
                f += new Vector(0, -obj.Speed.Y * obj.Mass);
            } else if (obj.Position.Y + obj.Diameter > this.Height) {
                if (Gravity > 0)
                    f += new Vector(0, obj.Mass * -this.Gravity);
                f += new Vector(0, -obj.Speed.Y * obj.Mass);
            }

            if (obj.Position.X < 0) {
                // Lineal moment:
                // p = m * v
                // F = dp/dt
                f += new Vector(obj.Mass * -obj.Speed.X, 0);
            } else if (obj.Position.X + obj.Diameter > this.Width) {
                // Lineal moment:
                // p = m * v
                // F = dp/dt
                f += new Vector(obj.Mass * -obj.Speed.X, 0);
            }

            return f;
        }