Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.Netron/3.0.2672.12446/Netron.Diagramming.Core-3.0.2672.12446/Layout/Force/ForceSimulator.cs @ 4068

Last change on this file since 4068 was 4068, checked in by swagner, 14 years ago

Sorted usings and removed unused usings in entire solution (#1094)

File size: 7.1 KB
Line 
1using System;
2using System.Collections.Generic;
3
4namespace Netron.Diagramming.Core.Layout.Force {
5  /// <summary>
6  ///  Manages a simulation of physical forces acting on bodies. To create a
7  /// custom ForceSimulator, add the desired <see cref="IForce"/> functions and choose an
8  /// appropriate <see cref="Integrator"/>.
9  /// </summary>
10  public class ForceSimulator {
11    #region Fields
12    /// <summary>
13    /// the force items
14    /// </summary>
15    private List<ForceItem> mItems;
16    /// <summary>
17    /// the spring items
18    /// </summary>
19    private List<Spring> springs;
20    /// <summary>
21    /// the forces
22    /// </summary>
23    private IForce[] iforces;
24    /// <summary>
25    /// the spring forces
26    /// </summary>
27    private IForce[] sforces;
28
29    private int iflen;
30    private int sflen;
31    private IIntegrator mIntegrator;
32    /// <summary>
33    /// the maximum speed allowed
34    /// </summary>
35    private float mSpeedLimit = 1.0f;
36    #endregion
37
38    #region Properties
39    /// <summary>
40    /// Get an iterator over all registered ForceItems.
41    /// </summary>
42    /// <value> the ForceItems.</value>
43    public List<ForceItem> Items {
44      get {
45        return mItems;
46      }
47    }
48    /// <summary>
49    /// Get an array of all the IForce functions used in this simulator.
50    /// </summary>
51    /// <value> an array of IForce functions</value>
52    public IForce[] Forces {
53      get {
54
55        IForce[] rv = new IForce[iflen + sflen];
56        Array.Copy(iforces, 0, rv, 0, iflen);
57        Array.Copy(sforces, 0, rv, iflen, sflen);
58        return rv;
59      }
60    }
61    /// <summary>
62    /// Gets all registered Springs.
63    /// </summary>
64    public List<Spring> Springs {
65      get {
66        return springs;
67      }
68    }
69    /// <summary>
70    /// Get or sets the speed limit, or maximum velocity value allowed by this
71    /// simulator.
72    /// </summary>
73    /// <returns>the "speed limit" maximum velocity value</returns>
74    public float SpeedLimit {
75      get {
76        return mSpeedLimit;
77      }
78      set { mSpeedLimit = value; }
79    }
80    /// <summary>
81    /// Get or sets the Integrator used by this simulator.
82    /// </summary>
83    public IIntegrator Integrator {
84      get {
85        return mIntegrator;
86      }
87      set { mIntegrator = value; }
88    }
89    #endregion
90
91    #region Constructor
92    /// <summary>
93    /// Create a new, empty ForceSimulator. A RungeKuttaIntegrator is used
94    /// by default.
95    /// </summary>
96    public ForceSimulator()
97      : this(new RungeKuttaIntegrator()) {
98    }
99
100    /// <summary>
101    /// Create a new, empty ForceSimulator.
102    /// </summary>
103    /// <param name="integr">the Integrator to use</param>
104    public ForceSimulator(IIntegrator integr) {
105      mIntegrator = integr;
106      iforces = new IForce[5];
107      sforces = new IForce[5];
108      iflen = 0;
109      sflen = 0;
110      mItems = new List<ForceItem>();
111      springs = new List<Spring>();
112    }
113    #endregion
114
115    #region Methods
116
117    /// <summary>
118    /// Clear this simulator, removing all ForceItem and Spring instances
119    /// for the simulator.
120    /// </summary>
121    public void Clear() {
122      mItems.Clear();
123      Spring.SpringFactory f = Spring.Factory;
124      foreach (Spring spring in springs)
125        f.reclaim(spring);
126      springs.Clear();
127    }
128
129    /// <summary>
130    /// Add a new IForce function to the simulator.
131    /// </summary>
132    /// <param name="f">the IForce function to add</param>
133    public void AddForce(IForce f) {
134      if (f.IsItemForce) {
135        if (iforces.Length == iflen) {
136          // resize necessary
137          IForce[] newf = new IForce[iflen + 10];
138          Array.Copy(iforces, 0, newf, 0, iforces.Length);
139          iforces = newf;
140        }
141        iforces[iflen++] = f;
142      }
143      if (f.IsSpringForce) {
144        if (sforces.Length == sflen) {
145          // resize necessary
146          IForce[] newf = new IForce[sflen + 10];
147          Array.Copy(sforces, 0, newf, 0, sforces.Length);
148          sforces = newf;
149        }
150        sforces[sflen++] = f;
151      }
152    }
153
154    /// <summary>
155    /// Add a ForceItem to the simulation.
156    /// </summary>
157    /// <param name="item"> item the ForceItem to add.</param>
158    public void addItem(ForceItem item) {
159      mItems.Add(item);
160    }
161
162    /// <summary>
163    /// Remove a ForceItem to the simulation.
164    /// </summary>
165    /// <param name="item">Item the ForceItem to remove.</param>
166    /// <returns></returns>
167    public bool removeItem(ForceItem item) {
168      return mItems.Remove(item);
169    }
170
171    /// <summary>
172    /// Add a Spring to the simulation.
173    /// </summary>
174    /// <param name="item1">the first endpoint of the spring</param>
175    /// <param name="item2">the second endpoint of the spring</param>
176    /// <returns>the Spring added to the simulation</returns>
177    public Spring addSpring(ForceItem item1, ForceItem item2) {
178      return addSpring(item1, item2, -1.0F, -1.0F);
179    }
180
181    /// <summary>
182    /// Add a Spring to the simulation.
183    /// </summary>
184    /// <param name="item1">the first endpoint of the spring</param>
185    /// <param name="item2">the second endpoint of the spring</param>
186    /// <param name="length">the spring length</param>
187    /// <returns>the Spring added to the simulation</returns>
188    public Spring addSpring(ForceItem item1, ForceItem item2, float length) {
189      return addSpring(item1, item2, -1.0F, length);
190    }
191
192    /// <summary>
193    /// Add a Spring to the simulation.
194    /// </summary>
195    /// <param name="item1">the first endpoint of the spring</param>
196    /// <param name="item2"> the second endpoint of the spring</param>
197    /// <param name="coeff">the spring coefficient</param>
198    /// <param name="length">the spring length</param>
199    /// <returns> the Spring added to the simulation</returns>
200    public Spring addSpring(ForceItem item1, ForceItem item2, float coeff, float length) {
201      if (item1 == null || item2 == null)
202        throw new ArgumentException("ForceItems must be non-null");
203      Spring s = Spring.Factory.getSpring(item1, item2, coeff, length);
204      springs.Add(s);
205      return s;
206    }
207
208    /// <summary>
209    /// Run the simulator for one timestep.
210    /// </summary>
211    /// <param name="timestep">the span of the timestep for which to run the simulator</param>
212    public void RunSimulator(long timestep) {
213      Accumulate();
214      mIntegrator.Integrate(this, timestep);
215    }
216
217    /// <summary>
218    /// Accumulate all forces acting on the items in this simulation
219    /// </summary>
220    public void Accumulate() {
221      for (int i = 0; i < iflen; i++)
222        iforces[i].Init(this);
223      for (int i = 0; i < sflen; i++)
224        sforces[i].Init(this);
225      foreach (ForceItem item in mItems) {
226        item.Force[0] = 0.0f; item.Force[1] = 0.0f;
227        for (int i = 0; i < iflen; i++)
228          iforces[i].GetForce(item);
229      }
230      foreach (Spring s in springs) {
231        for (int i = 0; i < sflen; i++) {
232          sforces[i].GetForce(s);
233        }
234      }
235    }
236    #endregion
237
238  }
239}
Note: See TracBrowser for help on using the repository browser.