Beispiel #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);
        }
 /// <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.
 }
Beispiel #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;
            }
        }
Beispiel #4
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);
    }
 /// <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.
 }
    /// <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;
      }
    }
    /// <summary>
    /// Loads the simulator with all relevant force items and springs.
    /// </summary>
    /// <param name="fsim"> the force simulator driving this layout.</param>
    protected void InitializeSimulator(ForceSimulator fsim) {
      //TODO: some checks here...?

      float startX = (referrer == null ? 0f : (float)referrer.X);
      float startY = (referrer == null ? 0f : (float)referrer.Y);
      startX = float.IsNaN(startX) ? 0f : startX;
      startY = float.IsNaN(startY) ? 0f : startY;
      if (Nodes != null && Nodes.Count > 0) {
        foreach (INode item in Nodes) {
          ForceItem fitem = Pars[item.Uid.ToString()];
          fitem.Mass = getMassValue(item);
          double x = item.X;
          double y = item.Y;
          fitem.Location[0] = (Double.IsNaN(x) ? startX : (float)x);
          fitem.Location[1] = (Double.IsNaN(y) ? startY : (float)y);
          fsim.addItem(fitem);
        }
      }
      if (Edges != null && Edges.Count > 0) {
        foreach (IEdge e in Edges) {
          INode n1 = e.SourceNode;
          if (n1 == null) continue;
          ForceItem f1 = Pars[n1.Uid.ToString()];
          INode n2 = e.TargetNode;
          if (n2 == null) continue;
          ForceItem f2 = Pars[n2.Uid.ToString()];
          float coeff = getSpringCoefficient(e);
          float slen = getSpringLength(e);
          fsim.addSpring(f1, f2, (coeff >= 0 ? coeff : -1.0F), (slen >= 0 ? slen : -1.0F));
        }
      }
    }
    private bool Init() {

      mEnforceBounds = false;
      m_runonce = true;
      m_fsim = new ForceSimulator();

      m_fsim.AddForce(new NBodyForce());
      m_fsim.AddForce(new SpringForce());
      m_fsim.AddForce(new DragForce());

      this.Graph = this.Model as IGraph;

      if (Graph == null)
        throw new InconsistencyException("The model has not been set and the Graph property is hence 'null'");

      //Graph.ClearSpanningTree();
      //Graph.MakeSpanningTree(LayoutRoot as INode);


      if (Graph.Nodes.Count == 0)
        return false;
      if (Graph.Edges.Count == 0) //this layout is base on embedded springs in the connections
        return false;

      Pars = new Dictionary<string, ForceItem>();

      foreach (INode node in Nodes) {
        Pars.Add(node.Uid.ToString(), new ForceItem());
      }
      return true;
    }