Пример #1
0
        /// <summary>
        /// Initialize the simulation with the provided enclosing simulation. After
        /// this call has been made, the simulation can be queried for the
        /// n-body force acting on a given item.
        /// </summary>
        /// <param name="fsim">the encompassing ForceSimulator</param>
        public override void Init(ForceSimulator fsim)
        {
            clear(); // clear internal state

            // compute and squarify bounds of quadtree
            float x1 = float.MaxValue, y1 = float.MaxValue;
            float x2 = float.MinValue, y2 = float.MinValue;

            foreach (ForceItem item in fsim.Items)
            {
                float x = item.Location[0];
                float y = item.Location[1];
                if (x < x1)
                {
                    x1 = x;
                }
                if (y < y1)
                {
                    y1 = y;
                }
                if (x > x2)
                {
                    x2 = x;
                }
                if (y > y2)
                {
                    y2 = y;
                }
            }
            float dx = x2 - x1, dy = y2 - y1;

            if (dx > dy)
            {
                y2 = y1 + dx;
            }
            else
            {
                x2 = x1 + dy;
            }
            setBounds(x1, y1, x2, y2);

            // Insert items into quadtree
            foreach (ForceItem item in fsim.Items)
            {
                Insert(item);
            }

            // calculate magnitudes and centers of mass
            CalculateMass(root);
        }
Пример #2
0
 /// <summary>
 /// Initialize this force function. This default implementation does nothing.
 /// Subclasses should override this method with any needed initialization.
 /// </summary>
 /// <param name="fsim">the encompassing ForceSimulator</param>
 public virtual void Init(ForceSimulator fsim)
 {
     // do nothing.
 }
Пример #3
0
        /// <summary>
        /// Integrates the specified simulation.
        /// </summary>
        /// <param name="sim">The sim.</param>
        /// <param name="timestep">The timestep.</param>
        public void Integrate(ForceSimulator sim, long timestep)
        {
            float speedLimit = sim.SpeedLimit;
            float vx, vy, v, coeff;

            float[,] k, l;

            foreach (ForceItem item in sim.Items)
            {
                coeff = timestep / item.Mass;
                k     = item.RungeKuttaTemp1;
                l     = item.RungeKuttaTemp2;
                item.PreviousLocation[0] = item.Location[0];
                item.PreviousLocation[1] = item.Location[1];
                k[0, 0] = timestep * item.Velocity[0];
                k[0, 1] = timestep * item.Velocity[1];
                l[0, 0] = coeff * item.Force[0];
                l[0, 1] = coeff * item.Force[1];

                // Set the position to the new predicted position
                item.Location[0] += 0.5f * k[0, 0];
                item.Location[1] += 0.5f * k[0, 1];
            }

            // recalculate forces
            sim.Accumulate();

            foreach (ForceItem item in sim.Items)
            {
                coeff = timestep / item.Mass;
                k     = item.RungeKuttaTemp1;
                l     = item.RungeKuttaTemp2;
                vx    = item.Velocity[0] + .5f * l[0, 0];
                vy    = item.Velocity[1] + .5f * l[0, 1];
                v     = (float)Math.Sqrt(vx * vx + vy * vy);
                if (v > speedLimit)
                {
                    vx = speedLimit * vx / v;
                    vy = speedLimit * vy / v;
                }
                k[1, 0] = timestep * vx;
                k[1, 1] = timestep * vy;
                l[1, 0] = coeff * item.Force[0];
                l[1, 1] = coeff * item.Force[1];

                // Set the position to the new predicted position
                item.Location[0] = item.PreviousLocation[0] + 0.5f * k[1, 0];
                item.Location[1] = item.PreviousLocation[1] + 0.5f * k[1, 1];
            }

            // recalculate forces
            sim.Accumulate();

            foreach (ForceItem item in sim.Items)
            {
                coeff = timestep / item.Mass;
                k     = item.RungeKuttaTemp1;
                l     = item.RungeKuttaTemp2;
                vx    = item.Velocity[0] + .5f * l[1, 0];
                vy    = item.Velocity[1] + .5f * l[1, 1];
                v     = (float)Math.Sqrt(vx * vx + vy * vy);
                if (v > speedLimit)
                {
                    vx = speedLimit * vx / v;
                    vy = speedLimit * vy / v;
                }
                k[2, 0] = timestep * vx;
                k[2, 1] = timestep * vy;
                l[2, 0] = coeff * item.Force[0];
                l[2, 1] = coeff * item.Force[1];

                // Set the position to the new predicted position
                item.Location[0] = item.PreviousLocation[0] + 0.5f * k[2, 0];
                item.Location[1] = item.PreviousLocation[1] + 0.5f * k[2, 1];
            }

            // recalculate forces
            sim.Accumulate();

            foreach (ForceItem item in sim.Items)
            {
                coeff = timestep / item.Mass;
                k     = item.RungeKuttaTemp1;
                l     = item.RungeKuttaTemp2;
                float[] p = item.PreviousLocation;
                vx = item.Velocity[0] + l[2, 0];
                vy = item.Velocity[1] + l[2, 1];
                v  = (float)Math.Sqrt(vx * vx + vy * vy);
                if (v > speedLimit)
                {
                    vx = speedLimit * vx / v;
                    vy = speedLimit * vy / v;
                }
                k[3, 0]          = timestep * vx;
                k[3, 1]          = timestep * vy;
                l[3, 0]          = coeff * item.Force[0];
                l[3, 1]          = coeff * item.Force[1];
                item.Location[0] = p[0] + (k[0, 0] + k[3, 0]) / 6.0f + (k[1, 0] + k[2, 0]) / 3.0f;
                item.Location[1] = p[1] + (k[0, 1] + k[3, 1]) / 6.0f + (k[1, 1] + k[2, 1]) / 3.0f;

                vx = (l[0, 0] + l[3, 0]) / 6.0f + (l[1, 0] + l[2, 0]) / 3.0f;
                vy = (l[0, 1] + l[3, 1]) / 6.0f + (l[1, 1] + l[2, 1]) / 3.0f;
                v  = (float)Math.Sqrt(vx * vx + vy * vy);
                if (v > speedLimit)
                {
                    vx = speedLimit * vx / v;
                    vy = speedLimit * vy / v;
                }
                item.Velocity[0] += vx;
                item.Velocity[1] += vy;
            }
        }