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