create changelog entry
[debian/openrocket] / core / src / net / sf / openrocket / aerodynamics / AbstractAerodynamicCalculator.java
1 package net.sf.openrocket.aerodynamics;
2
3 import java.util.Map;
4
5 import net.sf.openrocket.logging.LogHelper;
6 import net.sf.openrocket.rocketcomponent.Configuration;
7 import net.sf.openrocket.rocketcomponent.RocketComponent;
8 import net.sf.openrocket.startup.Application;
9 import net.sf.openrocket.util.Coordinate;
10
11
12 /**
13  * An abstract aerodynamic calculator implementation, that offers basic implementation
14  * of some methods and methods for cache validation and purging.
15  * 
16  * @author Sampo Niskanen <sampo.niskanen@iki.fi>
17  */
18
19 public abstract class AbstractAerodynamicCalculator implements AerodynamicCalculator {
20         private static final LogHelper log = Application.getLogger();
21         
22         /** Number of divisions used when calculating worst CP. */
23         public static final int DIVISIONS = 360;
24         
25         /**
26          * A <code>WarningSet</code> that can be used if <code>null</code> is passed
27          * to a calculation method.
28          */
29         protected WarningSet ignoreWarningSet = new WarningSet();
30         
31         /** The aerodynamic modification ID of the latest rocket */
32         private int rocketAeroModID = -1;
33         private int rocketTreeModID = -1;
34         
35         
36
37
38         ////////////////  Aerodynamic calculators  ////////////////
39         
40         @Override
41         public abstract Coordinate getCP(Configuration configuration, FlightConditions conditions,
42                         WarningSet warnings);
43         
44         @Override
45         public abstract Map<RocketComponent, AerodynamicForces> getForceAnalysis(Configuration configuration, FlightConditions conditions,
46                                 WarningSet warnings);
47         
48         @Override
49         public abstract AerodynamicForces getAerodynamicForces(Configuration configuration,
50                         FlightConditions conditions, WarningSet warnings);
51         
52         
53
54         /*
55          * The worst theta angle is stored in conditions.
56          */
57         @Override
58         public Coordinate getWorstCP(Configuration configuration, FlightConditions conditions,
59                         WarningSet warnings) {
60                 FlightConditions cond = conditions.clone();
61                 Coordinate worst = new Coordinate(Double.MAX_VALUE);
62                 Coordinate cp;
63                 double theta = 0;
64                 
65                 for (int i = 0; i < DIVISIONS; i++) {
66                         cond.setTheta(2 * Math.PI * i / DIVISIONS);
67                         cp = getCP(configuration, cond, warnings);
68                         if (cp.x < worst.x) {
69                                 worst = cp;
70                                 theta = cond.getTheta();
71                         }
72                 }
73                 
74                 conditions.setTheta(theta);
75                 
76                 return worst;
77         }
78         
79         
80
81         /**
82          * Check the current cache consistency.  This method must be called by all
83          * methods that may use any cached data before any other operations are
84          * performed.  If the rocket has changed since the previous call to
85          * <code>checkCache()</code>, then {@link #voidAerodynamicCache()} is called.
86          * <p>
87          * This method performs the checking based on the rocket's modification IDs,
88          * so that these method may be called from listeners of the rocket itself.
89          * 
90          * @param       configuration   the configuration of the current call
91          */
92         protected final void checkCache(Configuration configuration) {
93                 if (rocketAeroModID != configuration.getRocket().getAerodynamicModID() ||
94                                 rocketTreeModID != configuration.getRocket().getTreeModID()) {
95                         rocketAeroModID = configuration.getRocket().getAerodynamicModID();
96                         rocketTreeModID = configuration.getRocket().getTreeModID();
97                         log.debug("Voiding the aerodynamic cache");
98                         voidAerodynamicCache();
99                 }
100         }
101         
102         
103
104         /**
105          * Void cached aerodynamic data.  This method is called whenever a change occurs in 
106          * the rocket structure that affects the aerodynamics of the rocket and when a new 
107          * Rocket is set.  This method must be overridden to void any cached data 
108          * necessary.  The method must call <code>super.voidAerodynamicCache()</code> during 
109          * its execution.
110          */
111         protected void voidAerodynamicCache() {
112                 // No-op
113         }
114         
115
116 }