create changelog entry
[debian/openrocket] / core / src / net / sf / openrocket / rocketcomponent / LaunchLug.java
1 package net.sf.openrocket.rocketcomponent;
2
3 import java.util.ArrayList;
4 import java.util.Collection;
5
6 import net.sf.openrocket.l10n.Translator;
7 import net.sf.openrocket.preset.ComponentPreset;
8 import net.sf.openrocket.preset.ComponentPreset.Type;
9 import net.sf.openrocket.startup.Application;
10 import net.sf.openrocket.util.Coordinate;
11 import net.sf.openrocket.util.MathUtil;
12
13
14
15 public class LaunchLug extends ExternalComponent implements Coaxial {
16         
17         private static final Translator trans = Application.getTranslator();
18         
19         private double radius;
20         private double thickness;
21         
22         private double radialDirection = 0;
23         
24         /* These are calculated when the component is first attached to any Rocket */
25         private double shiftY, shiftZ;
26         
27         
28
29         public LaunchLug() {
30                 super(Position.MIDDLE);
31                 radius = 0.01 / 2;
32                 thickness = 0.001;
33                 length = 0.03;
34         }
35         
36         
37         @Override
38         public double getOuterRadius() {
39                 return radius;
40         }
41         
42         @Override
43         public void setOuterRadius(double radius) {
44                 if (MathUtil.equals(this.radius, radius))
45                         return;
46                 this.radius = radius;
47                 this.thickness = Math.min(this.thickness, this.radius);
48                 clearPreset();
49                 fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
50         }
51         
52         @Override
53         public double getInnerRadius() {
54                 return radius - thickness;
55         }
56         
57         @Override
58         public void setInnerRadius(double innerRadius) {
59                 setOuterRadius(innerRadius + thickness);
60         }
61         
62         @Override
63         public double getThickness() {
64                 return thickness;
65         }
66         
67         public void setThickness(double thickness) {
68                 if (MathUtil.equals(this.thickness, thickness))
69                         return;
70                 this.thickness = MathUtil.clamp(thickness, 0, radius);
71                 clearPreset();
72                 fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
73         }
74         
75         
76         public double getRadialDirection() {
77                 return radialDirection;
78         }
79         
80         public void setRadialDirection(double direction) {
81                 direction = MathUtil.reduce180(direction);
82                 if (MathUtil.equals(this.radialDirection, direction))
83                         return;
84                 this.radialDirection = direction;
85                 fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
86         }
87         
88         
89
90         public void setLength(double length) {
91                 if (MathUtil.equals(this.length, length))
92                         return;
93                 this.length = length;
94                 fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
95         }
96         
97         
98
99
100
101         @Override
102         public void setRelativePosition(RocketComponent.Position position) {
103                 super.setRelativePosition(position);
104                 fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
105         }
106         
107         
108         @Override
109         public void setPositionValue(double value) {
110                 super.setPositionValue(value);
111                 fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
112         }
113         
114         
115
116         @Override
117         protected void loadFromPreset(ComponentPreset preset) {
118                 if ( preset.has(ComponentPreset.OUTER_DIAMETER) )  {
119                         double outerDiameter = preset.get(ComponentPreset.OUTER_DIAMETER);
120                         this.radius = outerDiameter/2.0;
121                         if ( preset.has(ComponentPreset.INNER_DIAMETER) ) {
122                                 double innerDiameter = preset.get(ComponentPreset.INNER_DIAMETER);
123                                 this.thickness = (outerDiameter-innerDiameter) / 2.0;
124                         }
125                 }
126
127                 super.loadFromPreset(preset);
128
129                 fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
130         }
131
132
133         @Override
134         public Type getPresetType() {
135                 return ComponentPreset.Type.LAUNCH_LUG;
136         }
137
138
139         @Override
140         public Coordinate[] shiftCoordinates(Coordinate[] array) {
141                 array = super.shiftCoordinates(array);
142                 
143                 for (int i = 0; i < array.length; i++) {
144                         array[i] = array[i].add(0, shiftY, shiftZ);
145                 }
146                 
147                 return array;
148         }
149         
150         
151         @Override
152         public void componentChanged(ComponentChangeEvent e) {
153                 super.componentChanged(e);
154                 
155                 /*
156                  * shiftY and shiftZ must be computed here since calculating them
157                  * in shiftCoordinates() would cause an infinite loop due to .toRelative
158                  */
159                 RocketComponent body;
160                 double parentRadius;
161                 
162                 for (body = this.getParent(); body != null; body = body.getParent()) {
163                         if (body instanceof SymmetricComponent)
164                                 break;
165                 }
166                 
167                 if (body == null) {
168                         parentRadius = 0;
169                 } else {
170                         SymmetricComponent s = (SymmetricComponent) body;
171                         double x1, x2;
172                         x1 = this.toRelative(Coordinate.NUL, body)[0].x;
173                         x2 = this.toRelative(new Coordinate(length, 0, 0), body)[0].x;
174                         x1 = MathUtil.clamp(x1, 0, body.getLength());
175                         x2 = MathUtil.clamp(x2, 0, body.getLength());
176                         parentRadius = Math.max(s.getRadius(x1), s.getRadius(x2));
177                 }
178                 
179                 shiftY = Math.cos(radialDirection) * (parentRadius + radius);
180                 shiftZ = Math.sin(radialDirection) * (parentRadius + radius);
181                 
182                 //              System.out.println("Computed shift: y="+shiftY+" z="+shiftZ);
183         }
184         
185         
186
187
188         @Override
189         public double getComponentVolume() {
190                 return length * Math.PI * (MathUtil.pow2(radius) - MathUtil.pow2(radius - thickness));
191         }
192         
193         @Override
194         public Collection<Coordinate> getComponentBounds() {
195                 ArrayList<Coordinate> set = new ArrayList<Coordinate>();
196                 addBound(set, 0, radius);
197                 addBound(set, length, radius);
198                 return set;
199         }
200         
201         @Override
202         public Coordinate getComponentCG() {
203                 return new Coordinate(length / 2, 0, 0, getComponentMass());
204         }
205         
206         @Override
207         public String getComponentName() {
208                 //// Launch lug
209                 return trans.get("LaunchLug.Launchlug");
210         }
211         
212         @Override
213         public double getLongitudinalUnitInertia() {
214                 // 1/12 * (3 * (r1^2 + r2^2) + h^2)
215                 return (3 * (MathUtil.pow2(getInnerRadius())) + MathUtil.pow2(getOuterRadius()) + MathUtil.pow2(getLength())) / 12;
216         }
217         
218         @Override
219         public double getRotationalUnitInertia() {
220                 // 1/2 * (r1^2 + r2^2)
221                 return (MathUtil.pow2(getInnerRadius()) + MathUtil.pow2(getOuterRadius())) / 2;
222         }
223         
224         @Override
225         public boolean allowsChildren() {
226                 return false;
227         }
228         
229         @Override
230         public boolean isCompatible(Class<? extends RocketComponent> type) {
231                 // Allow nothing to be attached to a LaunchLug
232                 return false;
233         }
234         
235 }