Initial commit
[debian/openrocket] / src / net / sf / openrocket / rocketcomponent / MassObject.java
1 package net.sf.openrocket.rocketcomponent;
2
3 import static net.sf.openrocket.util.MathUtil.pow2;
4
5 import java.util.ArrayList;
6 import java.util.Collection;
7
8 import net.sf.openrocket.util.Coordinate;
9 import net.sf.openrocket.util.MathUtil;
10
11
12
13 /**
14  * A MassObject is an internal component that can a specific weight, but not
15  * necessarily a strictly bound shape.  It is represented as a homogeneous
16  * cylinder and drawn in the rocket figure with rounded corners.
17  * <p>
18  * Subclasses of this class need only implement the {@link #getComponentMass()},
19  * {@link #getComponentName()} and {@link #isCompatible(RocketComponent)}
20  * methods. 
21  * 
22  * @author Sampo Niskanen <sampo.niskanen@iki.fi>
23  */
24 public abstract class MassObject extends InternalComponent {
25
26         private double radius;
27         
28         private double radialPosition;
29         private double radialDirection;
30         
31         private double shiftY = 0;
32         private double shiftZ = 0;
33         
34         
35         public MassObject() {
36                 this(0.03, 0.015);
37         }
38         
39         public MassObject(double length, double radius) {
40                 super();
41
42                 this.length = length;
43                 this.radius = radius;
44                 
45                 this.setRelativePosition(Position.TOP);
46                 this.setPositionValue(0.0);
47         }
48
49         
50
51
52         public void setLength(double length) {
53                 length = Math.max(length, 0);
54                 if (MathUtil.equals(this.length, length))
55                         return;
56                 this.length = length;
57                 fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
58         }
59
60         
61
62         public final double getRadius() {
63                 return radius;
64         }
65
66
67         public final void setRadius(double radius) {
68                 radius = Math.max(radius, 0);
69                 if (MathUtil.equals(this.radius, radius))
70                         return;
71                 this.radius = radius;
72                 fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
73         }
74
75         
76         
77         public final double getRadialPosition() {
78                 return radialPosition;
79         }
80
81         public final void setRadialPosition(double radialPosition) {
82                 radialPosition = Math.max(radialPosition, 0);
83                 if (MathUtil.equals(this.radialPosition, radialPosition))
84                         return;
85                 this.radialPosition = radialPosition;
86                 shiftY = radialPosition * Math.cos(radialDirection);
87                 shiftZ = radialPosition * Math.sin(radialDirection);
88                 fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
89         }
90
91         public final double getRadialDirection() {
92                 return radialDirection;
93         }
94
95         public final void setRadialDirection(double radialDirection) {
96                 radialDirection = MathUtil.reduce180(radialDirection);
97                 if (MathUtil.equals(this.radialDirection, radialDirection))
98                         return;
99                 this.radialDirection = radialDirection;
100                 shiftY = radialPosition * Math.cos(radialDirection);
101                 shiftZ = radialPosition * Math.sin(radialDirection);
102                 fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
103         }
104
105         
106
107         
108         /**
109          * Shift the coordinates according to the radial position and direction.
110          */
111         @Override
112         public final Coordinate[] shiftCoordinates(Coordinate[] array) {
113                 for (int i=0; i < array.length; i++) {
114                         array[i] = array[i].add(0, shiftY, shiftZ);
115                 }
116                 return array;
117         }
118         
119         @Override
120         public final Coordinate getComponentCG() {
121                 return new Coordinate(length/2, shiftY, shiftZ, getComponentMass());
122         }
123         
124         @Override
125         public final double getLongitudalUnitInertia() {
126                 return (3*pow2(radius) + pow2(length)) / 12;
127         }
128
129         @Override
130         public final double getRotationalUnitInertia() {
131                 return pow2(radius) / 2;
132         }
133         
134         @Override
135         public final Collection<Coordinate> getComponentBounds() {
136                 Collection<Coordinate> c = new ArrayList<Coordinate>();
137                 addBound(c, 0, radius);
138                 addBound(c, length, radius);
139                 return c;
140         }
141 }