1 package net.sf.openrocket.rocketcomponent;
3 import net.sf.openrocket.util.Coordinate;
4 import net.sf.openrocket.util.MathUtil;
6 import java.util.ArrayList;
7 import java.util.Collection;
11 public class LaunchLug extends ExternalComponent implements Coaxial {
13 private double radius;
14 private double thickness;
16 private double radialDirection = 0;
18 /* These are calculated when the component is first attached to any Rocket */
19 private double shiftY, shiftZ;
24 super(Position.MIDDLE);
31 public double getOuterRadius () {
35 public void setOuterRadius (double radius) {
36 if (MathUtil.equals(this.radius, radius))
39 this.thickness = Math.min(this.thickness, this.radius);
40 fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
43 public double getInnerRadius() {
44 return radius - thickness;
47 public void setInnerRadius(double innerRadius) {
48 setOuterRadius(innerRadius + thickness);
51 public double getThickness() {
55 public void setThickness(double thickness) {
56 if (MathUtil.equals(this.thickness, thickness))
58 this.thickness = MathUtil.clamp(thickness, 0, radius);
59 fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
63 public double getRadialDirection() {
64 return radialDirection;
67 public void setRadialDirection(double direction) {
68 direction = MathUtil.reduce180(direction);
69 if (MathUtil.equals(this.radialDirection, direction))
71 this.radialDirection = direction;
72 fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
77 public void setLength(double length) {
78 if (MathUtil.equals(this.length, length))
81 fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
89 public void setRelativePosition(RocketComponent.Position position) {
90 super.setRelativePosition(position);
91 fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
96 public void setPositionValue(double value) {
97 super.setPositionValue(value);
98 fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
104 public Coordinate[] shiftCoordinates(Coordinate[] array) {
105 array = super.shiftCoordinates(array);
107 for (int i = 0; i < array.length; i++) {
108 array[i] = array[i].add(0, shiftY, shiftZ);
116 public void componentChanged(ComponentChangeEvent e) {
117 super.componentChanged(e);
120 * shiftY and shiftZ must be computed here since calculating them
121 * in shiftCoordinates() would cause an infinite loop due to .toRelative
123 RocketComponent body;
126 for (body = this.getParent(); body != null; body = body.getParent()) {
127 if (body instanceof SymmetricComponent)
134 SymmetricComponent s = (SymmetricComponent) body;
136 x1 = this.toRelative(Coordinate.NUL, body)[0].x;
137 x2 = this.toRelative(new Coordinate(length, 0, 0), body)[0].x;
138 x1 = MathUtil.clamp(x1, 0, body.getLength());
139 x2 = MathUtil.clamp(x2, 0, body.getLength());
140 parentRadius = Math.max(s.getRadius(x1), s.getRadius(x2));
143 shiftY = Math.cos(radialDirection) * (parentRadius + radius);
144 shiftZ = Math.sin(radialDirection) * (parentRadius + radius);
146 // System.out.println("Computed shift: y="+shiftY+" z="+shiftZ);
153 public double getComponentVolume() {
154 return length * Math.PI * (MathUtil.pow2(radius) - MathUtil.pow2(radius - thickness));
158 public Collection<Coordinate> getComponentBounds() {
159 ArrayList<Coordinate> set = new ArrayList<Coordinate>();
160 addBound(set, 0, radius);
161 addBound(set, length, radius);
166 public Coordinate getComponentCG() {
167 return new Coordinate(length / 2, 0, 0, getComponentMass());
171 public String getComponentName() {
176 public double getLongitudinalUnitInertia() {
177 // 1/12 * (3 * (r1^2 + r2^2) + h^2)
178 return (3 * (MathUtil.pow2(getInnerRadius())) + MathUtil.pow2(getOuterRadius()) +
179 MathUtil.pow2(getLength())) / 12;
183 public double getRotationalUnitInertia() {
184 // 1/2 * (r1^2 + r2^2)
185 return (MathUtil.pow2(getInnerRadius()) + MathUtil.pow2(getOuterRadius()))/2;
189 public boolean allowsChildren() {
194 public boolean isCompatible(Class<? extends RocketComponent> type) {
195 // Allow nothing to be attached to a LaunchLug
200 * Accept a visitor to this LaunchLug in the component hierarchy.
202 * @param theVisitor the visitor that will be called back with a reference to this LaunchLug
205 public void accept (final ComponentVisitor theVisitor) {
206 theVisitor.visit(this);