1 package net.sf.openrocket.rocketcomponent;
3 import java.util.ArrayList;
4 import java.util.Collection;
7 import net.sf.openrocket.util.Coordinate;
8 import net.sf.openrocket.util.MathUtil;
12 * An inner component that consists of a hollow cylindrical component. This can be
13 * an inner tube, tube coupler, centering ring, bulkhead etc.
15 * The properties include the inner and outer radii, length and radial position.
17 * @author Sampo Niskanen <sampo.niskanen@iki.fi>
19 public abstract class RingComponent extends StructuralComponent {
21 protected boolean outerRadiusAutomatic = false;
22 protected boolean innerRadiusAutomatic = false;
25 private double radialDirection = 0;
26 private double radialPosition = 0;
28 private double shiftY = 0;
29 private double shiftZ = 0;
34 public abstract double getOuterRadius();
35 public abstract void setOuterRadius(double r);
37 public abstract double getInnerRadius();
38 public abstract void setInnerRadius(double r);
40 public abstract double getThickness();
41 public abstract void setThickness(double thickness);
44 public final boolean isOuterRadiusAutomatic() {
45 return outerRadiusAutomatic;
48 protected void setOuterRadiusAutomatic(boolean auto) {
49 if (auto == outerRadiusAutomatic)
51 outerRadiusAutomatic = auto;
52 fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
56 public final boolean isInnerRadiusAutomatic() {
57 return innerRadiusAutomatic;
60 protected void setInnerRadiusAutomatic(boolean auto) {
61 if (auto == innerRadiusAutomatic)
63 innerRadiusAutomatic = auto;
64 fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
70 public final void setLength(double length) {
71 double l = Math.max(length,0);
76 fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
81 * Return the radial direction of displacement of the component. Direction 0
82 * is equivalent to the Y-direction.
84 * @return the radial direction.
86 public double getRadialDirection() {
87 return radialDirection;
91 * Set the radial direction of displacement of the component. Direction 0
92 * is equivalent to the Y-direction.
94 * @param dir the radial direction.
96 public void setRadialDirection(double dir) {
97 dir = MathUtil.reduce180(dir);
98 if (radialDirection == dir)
100 radialDirection = dir;
101 shiftY = radialPosition * Math.cos(radialDirection);
102 shiftZ = radialPosition * Math.sin(radialDirection);
103 fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
110 * Return the radial position of the component. The position is the distance
111 * of the center of the component from the center of the parent component.
113 * @return the radial position.
115 public double getRadialPosition() {
116 return radialPosition;
120 * Set the radial position of the component. The position is the distance
121 * of the center of the component from the center of the parent component.
123 * @param pos the radial position.
125 public void setRadialPosition(double pos) {
126 pos = Math.max(pos, 0);
127 if (radialPosition == pos)
129 radialPosition = pos;
130 shiftY = radialPosition * Math.cos(radialDirection);
131 shiftZ = radialPosition * Math.sin(radialDirection);
132 fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
138 * Return the number of times the component is multiplied.
140 public int getClusterCount() {
141 if (this instanceof Clusterable)
142 return ((Clusterable)this).getClusterConfiguration().getClusterCount();
148 * Shift the coordinates according to the radial position and direction.
151 public Coordinate[] shiftCoordinates(Coordinate[] array) {
152 for (int i=0; i < array.length; i++) {
153 array[i] = array[i].add(0, shiftY, shiftZ);
160 public Collection<Coordinate> getComponentBounds() {
161 List<Coordinate> bounds = new ArrayList<Coordinate>();
162 addBound(bounds,0,getOuterRadius());
163 addBound(bounds,length,getOuterRadius());
170 public Coordinate getComponentCG() {
171 return new Coordinate(length/2, 0, 0, getComponentMass());
175 public double getComponentMass() {
176 return ringMass(getOuterRadius(), getInnerRadius(), getLength(),
177 getMaterial().getDensity()) * getClusterCount();
182 public double getLongitudalUnitInertia() {
183 return ringLongitudalUnitInertia(getOuterRadius(), getInnerRadius(), getLength());
187 public double getRotationalUnitInertia() {
188 return ringRotationalUnitInertia(getOuterRadius(), getInnerRadius());