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