예제 #1
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="system"></param>
        /// <param name="emitter"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="minks">Minimum Spring Constant</param>
        /// <param name="maxks">Maximum Spring Constant</param>
        /// <param name="minkd">Minimum Dampening Constant</param>
        /// <param name="maxkd">Maximum Dampening Constant</param>
        /// <param name="minrest">Minimum Rest Length</param>
        /// <param name="maxrest">Maximum Rest Length</param>
        public Meatball(ParticleSystem system, Emitter emitter, double x, double y, 
            double minks, double maxks, double minkd, double maxkd, double minrest, 
            double maxrest, bool anchored)
        {
            // create thre particles
            mParticles[0] = new Particle();
            mParticles[0].IsAnchor = anchored; // anchors the first particle if so desired
            mParticles[1] = new Particle();
            mParticles[2] = new Particle();

            // update the particles
            Update(emitter, x, y);

            // Create the spring between particles 0 and 1
            Spring s = new Spring();
            s.ThisParticle = mParticles[0];
            s.ConnectedParticle = mParticles[1];
            s.SpringConstant = ParticleSystem.random.NextDouble(minks, maxks); //1.0, 4.0);
            s.DampingConstant = ParticleSystem.random.NextDouble(minkd, maxkd); //0.10, 0.30);
            s.RestLength = ParticleSystem.random.NextDouble(minrest, maxrest); //1.0, 6.0);
            mParticles[0].Connections.Add(s);
            mParticles[1].Connections.Add(s);
            //system.Forces.Add(s);

            // Create the spring between particles 0 and 2
            s = new Spring();
            s.ThisParticle = mParticles[0];
            s.ConnectedParticle = mParticles[2];
            s.SpringConstant = ParticleSystem.random.NextDouble(minks, maxks); //1.0, 4.0);
            s.DampingConstant = ParticleSystem.random.NextDouble(minkd, maxkd); //0.10, 0.30);
            s.RestLength = ParticleSystem.random.NextDouble(minrest, maxrest); //1.0, 6.0);
            mParticles[0].Connections.Add(s);
            mParticles[2].Connections.Add(s);
            //system.Forces.Add(s);

            // Create the spring between particles 1 and 2
            s = new Spring();
            s.ThisParticle = mParticles[1];
            s.ConnectedParticle = mParticles[2];
            s.SpringConstant = ParticleSystem.random.NextDouble(minks, maxks); //1.0, 4.0);
            s.DampingConstant = ParticleSystem.random.NextDouble(minkd, maxkd); //0.10, 0.30);
            s.RestLength = ParticleSystem.random.NextDouble(minrest, maxrest); //1.0, 6.0);
            mParticles[1].Connections.Add(s);
            mParticles[2].Connections.Add(s);
            //system.Forces.Add(s);

            // Add the particles to the system
            system.Particles.Add(mParticles[0]);
            system.Particles.Add(mParticles[1]);
            system.Particles.Add(mParticles[2]);
        }
        /// <summary>
        /// Calculate all the forces acting on a particle at a given time
        /// </summary>
        /// <param name="particle"></param>
        /// <param name="time"></param>
        /// <returns></returns>
        private Vector ComputeForces(Particle particle, double time)
        {
            // set all the forces for a particle at a time and position
            double forceX = (particle.Mass * Gravity.X) - (particle.Velocity.X * Drag.X);
            double forceY = (particle.Mass * Gravity.Y) - (particle.Velocity.Y * Drag.Y);

            // If there are spring force connections on this particle then for every connection update
            // the forces acting upon the particle
            if (particle.Connections.Count > 0)
            {
                foreach (Spring s in particle.Connections)
                {
                    // apply the spring force
                    Vector force = s.ApplyForce(particle);
                    forceX += force.X;
                    forceY += force.Y;
                }
            }
            // for every other force in the global list of forces, apply and update the force.
            foreach (Force f in Forces)
            {
                Vector force = f.ApplyForce(particle);
                forceX += force.X;
                forceY += force.Y;
            }
            return new Vector(forceX, forceY); // return the force vector.
        }
        /// <summary>
        /// Update the particle
        /// </summary>
        /// <param name="particle"></param>
        public override void UpdateParticle(Particle particle)
        {
            base.UpdateParticle(particle);

            // Find a new x and corresponding y
            double x = ParticleSystem.random.NextDouble(X1, X2);
            particle.Position = new Point(x + ParticleSystem.random.NextDouble(MinPositionOffset, MaxPositionOffset),
                LinearEquation(x) + ParticleSystem.random.NextDouble(MinPositionOffset, MaxPositionOffset));
        }
        /// <summary>
        /// Add a particle to the system
        /// </summary>
        /// <param name="system"></param>
        /// <param name="particle"></param>
        public override void AddParticle(ParticleSystem system, Particle particle)
        {
            base.AddParticle(system, particle);

            // pick a random X between X1 and X2
            // then get the corresponding y
            double x = ParticleSystem.random.NextDouble(X1, X2);
            particle.Position = new Point(x + ParticleSystem.random.NextDouble(MinPositionOffset, MaxPositionOffset),
                LinearEquation(x) + ParticleSystem.random.NextDouble(MinPositionOffset, MaxPositionOffset));
        }
        /// <summary>
        /// Add a particle to the system.
        /// </summary>
        /// <param name="system"></param>
        /// <param name="particle"></param>
        public override void AddParticle(ParticleSystem system, Particle particle)
        {
            base.AddParticle(system, particle);

            // overwrite the position based on the emitters X and Y position
            particle.Position = new Point(this.X + ParticleSystem.random.NextDouble(MinPositionOffset, MaxPositionOffset),
                this.Y + ParticleSystem.random.NextDouble(MinPositionOffset, MaxPositionOffset));
        }
        /// <summary>
        /// Update the particle
        /// </summary>
        /// <param name="particle"></param>
        public override void UpdateParticle(Particle particle)
        {
            base.UpdateParticle(particle);

            // Update the particles position
            particle.Position = new Point(this.X + ParticleSystem.random.NextDouble(MinPositionOffset, MaxPositionOffset),
                this.Y + ParticleSystem.random.NextDouble(MinPositionOffset, MaxPositionOffset));
        }
        /// <summary>
        /// Create a meatball which adds three particles with springs to the system. 
        /// </summary>
        /// <param name="system"></param>
        /// <param name="particle"></param>
        public override void AddParticle(ParticleSystem system, Particle particle)
        {
            //base.AddParticle(system, particle); // ignore the base

            double x = ParticleSystem.random.NextDouble(X1, X2);
            Meatball meatball = new Meatball(system, this, x, LinearEquation(x),
                MinSpringConstant, MaxSpringConstant, MinDampeningConstant, MaxDampeningConstant,
                MinRestLength, MaxRestLength, true);
            // add each particle to the dictionary and its associated meatball.
            foreach (Particle p in meatball.Particles)
            {
                mMeatballs.Add(p, meatball);
            }
        }
        /// <summary>
        /// Update the particle. Ignore the base and use the meatball update. 
        /// </summary>
        /// <param name="particle"></param>
        public override void UpdateParticle(Particle particle)
        {
            //base.UpdateParticle(particle);

            double x = ParticleSystem.random.NextDouble(X1, X2);
            // Get the meatball this particle is a part of.
            ((Meatball)mMeatballs[particle]).Update(this, x, LinearEquation(x));
        }
 /// <summary>
 /// Used by the Particle System to apply a force vector to a particle.
 /// </summary>
 /// <param name="particle"></param>
 /// <returns></returns>
 public virtual Vector ApplyForce(Particle particle)
 {
     return new Vector();
 }
예제 #10
0
 /// <summary>
 /// Updates the particle by reinitializing its parameters. Used when a particle is first created and 
 /// when a particle is resurrected.
 /// </summary>
 /// <param name="particle"></param>
 public virtual void UpdateParticle(Particle particle)
 {
     particle.Owner = this;
     particle.Mass = ParticleSystem.random.NextDouble(MinMass, MaxMass);
     particle.StartOpacity = this.StartOpacity;
     particle.EndOpacity = this.EndOpacity;
     particle.Force = new Vector(0, 0);
     particle.Velocity = new Vector(
         ParticleSystem.random.NextDouble(MinHorizontalVelocity, MaxHorizontalVelocity),
         ParticleSystem.random.NextDouble(MinVerticalVelocity, MaxVerticalVelocity));
     particle.LifeSpan = ParticleSystem.random.NextDouble(MinLifeSpan, MaxLifeSpan);
     particle.BackgroundColors = this.ColorKeyFrames;
 }
예제 #11
0
 /// <summary>
 /// Generates the particles for an emitter, called once at creation by the Particle System.
 /// </summary>
 /// <param name="system"></param>
 public virtual void GenerateParticles(ParticleSystem system)
 {
     // Init the particles for the emitter
     for (int i = 0; i < MaxParticles; i++)
     {
         Particle mParticle = new Particle();
         UpdateParticle(mParticle);
         this.AddParticle(system, mParticle);
         system.Particles.Add(mParticle);
     }
 }
예제 #12
0
 /// <summary>
 /// Method which is used to perform additional processing when adding a particle to the system for the
 /// first time.
 /// </summary>
 /// <param name="system"></param>
 /// <param name="particle"></param>
 public virtual void AddParticle(ParticleSystem system, Particle particle)
 {
 }
        /// <summary>
        /// Apply the spring force to ThisParticle and the ConnectedParticle
        /// </summary>
        /// <param name="particle"></param>
        /// <returns></returns>
        public override Vector ApplyForce(Particle particle)
        {
            // The particle to apply the force to must be one if the two particles which
            // connects this spring
            if (ThisParticle.Equals(particle) || ConnectedParticle.Equals(particle))
            {
                // if the particle is ThisParticle the the other particle is the ConnectedParticle and vice-versa
                Particle con = ConnectedParticle;
                if (ConnectedParticle.Equals(particle))
                    con = ThisParticle;

                // Calculate the change in position (x and y) for the particle and its connection
                double deltaX = particle.Position.X - con.Position.X;
                double deltaY = particle.Position.Y - con.Position.Y;

                // Calculate the change in velocity (x and y) for the particle and its connection
                double deltaVX = particle.Velocity.X - con.Velocity.X;
                double deltaVY = particle.Velocity.Y - con.Velocity.Y;

                // Calculate the x and y forces generate on the particle by the spring
                double fx1 = -(SpringConstant * (Math.Abs(deltaX) - RestLength) + DampingConstant * ((deltaVX * deltaX) / Math.Abs(deltaX))) * (deltaX / Math.Abs(deltaX));
                double fy1 = -(SpringConstant * (Math.Abs(deltaY) - RestLength) + DampingConstant * ((deltaVY * deltaY) / Math.Abs(deltaY))) * (deltaY / Math.Abs(deltaY));

                // The negative of that force is applied to the connected particle
                double fx2 = -fx1;
                double fy2 = -fy1;

                // Apply the negative force
                Vector cForce = con.Force;
                con.Force = new Vector(cForce.X + fx2, cForce.Y + fy2);

                // Return the spring force to be applied to this particle
                return new Vector(fx1, fy1);
            }
            else
                return new Vector(0, 0);
        }