create changelog entry
[debian/openrocket] / core / src / net / sf / openrocket / rocketcomponent / TrapezoidFinSet.java
1 package net.sf.openrocket.rocketcomponent;
2
3 import net.sf.openrocket.l10n.Translator;
4 import net.sf.openrocket.startup.Application;
5 import net.sf.openrocket.util.Coordinate;
6 import net.sf.openrocket.util.MathUtil;
7
8 import java.util.ArrayList;
9 import java.util.List;
10
11 /**
12  * A set of trapezoidal fins.  The root and tip chords are perpendicular to the rocket
13  * base line, while the leading and aft edges may be slanted.
14  *
15  * @author Sampo Niskanen <sampo.niskanen@iki.fi>
16  */
17
18 public class TrapezoidFinSet extends FinSet {
19         private static final Translator trans = Application.getTranslator();
20         
21         public static final double MAX_SWEEP_ANGLE = (89 * Math.PI / 180.0);
22         
23         /*
24          *           sweep   tipChord
25          *           |    |___________
26          *           |   /            |
27          *           |  /             |
28          *           | /              |  height
29          *            /               |
30          * __________/________________|_____________
31          *                length
32          *              == rootChord
33          */
34         
35         // rootChord == length
36         private double tipChord = 0;
37         private double height = 0;
38         private double sweep = 0;
39         
40         
41         public TrapezoidFinSet() {
42                 this(3, 0.05, 0.05, 0.025, 0.03);
43         }
44         
45         // TODO: HIGH:  height=0 -> CP = NaN
46         public TrapezoidFinSet(int fins, double rootChord, double tipChord, double sweep,
47                         double height) {
48                 super();
49                 
50                 this.setFinCount(fins);
51                 this.length = rootChord;
52                 this.tipChord = tipChord;
53                 this.sweep = sweep;
54                 this.height = height;
55         }
56         
57         
58         public void setFinShape(double rootChord, double tipChord, double sweep, double height,
59                         double thickness) {
60                 if (this.length == rootChord && this.tipChord == tipChord && this.sweep == sweep &&
61                                 this.height == height && this.thickness == thickness)
62                         return;
63                 this.length = rootChord;
64                 this.tipChord = tipChord;
65                 this.sweep = sweep;
66                 this.height = height;
67                 this.thickness = thickness;
68                 fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
69         }
70         
71         public double getRootChord() {
72                 return length;
73         }
74         
75         public void setRootChord(double r) {
76                 if (length == r)
77                         return;
78                 length = Math.max(r, 0);
79                 fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
80         }
81         
82         public double getTipChord() {
83                 return tipChord;
84         }
85         
86         public void setTipChord(double r) {
87                 if (tipChord == r)
88                         return;
89                 tipChord = Math.max(r, 0);
90                 fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
91         }
92         
93         /**
94          * Get the sweep length.
95          */
96         public double getSweep() {
97                 return sweep;
98         }
99         
100         /**
101          * Set the sweep length.
102          */
103         public void setSweep(double r) {
104                 if (sweep == r)
105                         return;
106                 sweep = r;
107                 fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
108         }
109         
110         /**
111          * Get the sweep angle.  This is calculated from the true sweep and height, and is not
112          * stored separately.
113          */
114         public double getSweepAngle() {
115                 if (height == 0) {
116                         if (sweep > 0)
117                                 return Math.PI / 2;
118                         if (sweep < 0)
119                                 return -Math.PI / 2;
120                         return 0;
121                 }
122                 return Math.atan(sweep / height);
123         }
124         
125         /**
126          * Sets the sweep by the sweep angle.  The sweep is calculated and set by this method,
127          * and the angle itself is not stored.
128          */
129         public void setSweepAngle(double r) {
130                 if (r > MAX_SWEEP_ANGLE)
131                         r = MAX_SWEEP_ANGLE;
132                 if (r < -MAX_SWEEP_ANGLE)
133                         r = -MAX_SWEEP_ANGLE;
134                 double sweep = Math.tan(r) * height;
135                 if (Double.isNaN(sweep) || Double.isInfinite(sweep))
136                         return;
137                 setSweep(sweep);
138         }
139         
140         public double getHeight() {
141                 return height;
142         }
143         
144         public void setHeight(double r) {
145                 if (height == r)
146                         return;
147                 height = Math.max(r, 0);
148                 fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
149         }
150         
151         
152         
153         /**
154          * Returns the geometry of a trapezoidal fin.
155          */
156         @Override
157         public Coordinate[] getFinPoints() {
158                 List<Coordinate> list = new ArrayList<Coordinate>(4);
159                 
160                 list.add(Coordinate.NUL);
161                 list.add(new Coordinate(sweep, height));
162                 if (tipChord > 0.0001) {
163                         list.add(new Coordinate(sweep + tipChord, height));
164                 }
165                 list.add(new Coordinate(MathUtil.max(length, 0.0001), 0));
166                 
167                 return list.toArray(new Coordinate[list.size()]);
168         }
169         
170         /**
171          * Returns the span of a trapezoidal fin.
172          */
173         @Override
174         public double getSpan() {
175                 return height;
176         }
177         
178         
179         @Override
180         public String getComponentName() {
181                 //// Trapezoidal fin set
182                 return trans.get("TrapezoidFinSet.TrapezoidFinSet");
183         }
184         
185 }