Initial commit
[debian/openrocket] / src / net / sf / openrocket / rocketcomponent / RingComponent.java
1 package net.sf.openrocket.rocketcomponent;
2
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.List;
6
7 import net.sf.openrocket.util.Coordinate;
8 import net.sf.openrocket.util.MathUtil;
9
10
11 /**
12  * An inner component that consists of a hollow cylindrical component.  This can be
13  * an inner tube, tube coupler, centering ring, bulkhead etc.
14  * 
15  * The properties include the inner and outer radii, length and radial position.
16  * 
17  * @author Sampo Niskanen <sampo.niskanen@iki.fi>
18  */
19 public abstract class RingComponent extends StructuralComponent {
20
21         protected boolean outerRadiusAutomatic = false;
22         protected boolean innerRadiusAutomatic = false;
23         
24         
25         private double radialDirection = 0;
26         private double radialPosition = 0;
27         
28         private double shiftY = 0;
29         private double shiftZ = 0;
30         
31
32         
33
34         public abstract double getOuterRadius();
35         public abstract void setOuterRadius(double r);
36         
37         public abstract double getInnerRadius();        
38         public abstract void setInnerRadius(double r);
39         
40         public abstract double getThickness();
41         public abstract void setThickness(double thickness);
42         
43         
44         public final boolean isOuterRadiusAutomatic() {
45                 return outerRadiusAutomatic;
46         }
47         
48         protected void setOuterRadiusAutomatic(boolean auto) {
49                 if (auto == outerRadiusAutomatic)
50                         return;
51                 outerRadiusAutomatic = auto;
52                 fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
53         }
54         
55         
56         public final boolean isInnerRadiusAutomatic() {
57                 return innerRadiusAutomatic;
58         }
59         
60         protected void setInnerRadiusAutomatic(boolean auto) {
61                 if (auto == innerRadiusAutomatic)
62                         return;
63                 innerRadiusAutomatic = auto;
64                 fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
65         }
66         
67         
68         
69         
70         public final void setLength(double length) {
71                 double l = Math.max(length,0);
72                 if (this.length == l)
73                         return;
74                 
75                 this.length = l;
76                 fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
77         }
78
79         
80         /**
81          * Return the radial direction of displacement of the component.  Direction 0
82          * is equivalent to the Y-direction.
83          * 
84          * @return  the radial direction.
85          */
86         public double getRadialDirection() {
87                 return radialDirection;
88         }
89         
90         /**
91          * Set the radial direction of displacement of the component.  Direction 0
92          * is equivalent to the Y-direction.
93          * 
94          * @param dir  the radial direction.
95          */
96         public void setRadialDirection(double dir) {
97                 dir = MathUtil.reduce180(dir);
98                 if (radialDirection == dir)
99                         return;
100                 radialDirection = dir;
101                 shiftY = radialPosition * Math.cos(radialDirection);
102                 shiftZ = radialPosition * Math.sin(radialDirection);
103                 fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
104         }
105
106         
107         
108         
109         /**
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.
112          * 
113          * @return  the radial position.
114          */
115         public double getRadialPosition() {
116                 return radialPosition;
117         }
118         
119         /**
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.
122          * 
123          * @param pos  the radial position.
124          */
125         public void setRadialPosition(double pos) {
126                 pos = Math.max(pos, 0);
127                 if (radialPosition == pos)
128                         return;
129                 radialPosition = pos;
130                 shiftY = radialPosition * Math.cos(radialDirection);
131                 shiftZ = radialPosition * Math.sin(radialDirection);
132                 fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
133         }
134
135
136
137         /**
138          * Return the number of times the component is multiplied.
139          */
140         public int getClusterCount() {
141                 if (this instanceof Clusterable)
142                         return ((Clusterable)this).getClusterConfiguration().getClusterCount();
143                 return 1;
144         }
145         
146         
147         /**
148          * Shift the coordinates according to the radial position and direction.
149          */
150         @Override
151         public Coordinate[] shiftCoordinates(Coordinate[] array) {
152                 for (int i=0; i < array.length; i++) {
153                         array[i] = array[i].add(0, shiftY, shiftZ);
154                 }
155                 return array;
156         }
157         
158         
159         @Override
160         public Collection<Coordinate> getComponentBounds() {
161                 List<Coordinate> bounds = new ArrayList<Coordinate>();
162                 addBound(bounds,0,getOuterRadius());
163                 addBound(bounds,length,getOuterRadius());
164                 return bounds;
165         }
166         
167
168         
169         @Override
170         public Coordinate getComponentCG() {
171                 return new Coordinate(length/2, 0, 0, getComponentMass());
172         }
173
174         @Override
175         public double getComponentMass() {
176                 return ringMass(getOuterRadius(), getInnerRadius(), getLength(),
177                                 getMaterial().getDensity()) * getClusterCount();
178         }
179         
180
181         @Override
182         public double getLongitudalUnitInertia() {
183                 return ringLongitudalUnitInertia(getOuterRadius(), getInnerRadius(), getLength());
184         }
185
186         @Override
187         public double getRotationalUnitInertia() {
188                 return ringRotationalUnitInertia(getOuterRadius(), getInnerRadius());
189         }
190
191 }