6fa4a4c2df903893b898e4b4fc5b26090924be31
[debian/openrocket] / src / net / sf / openrocket / rocketcomponent / ExternalComponent.java
1 package net.sf.openrocket.rocketcomponent;
2
3 import java.util.List;
4
5 import net.sf.openrocket.material.Material;
6 import net.sf.openrocket.unit.UnitGroup;
7 import net.sf.openrocket.util.Prefs;
8
9 /**
10  * Class of components with well-defined physical appearance and which have an effect on
11  * aerodynamic simulation.  They have material defined for them, and the mass of the component 
12  * is calculated using the component's volume.
13  * 
14  * @author Sampo Niskanen <sampo.niskanen@iki.fi>
15  */
16
17 public abstract class ExternalComponent extends RocketComponent {
18         
19         public enum Finish {
20                 ROUGH("Rough", 500e-6),
21                 UNFINISHED("Unfinished", 150e-6),
22                 NORMAL("Regular paint", 60e-6),
23                 SMOOTH("Smooth paint", 20e-6),
24                 POLISHED("Polished", 2e-6);
25                 
26                 private final String name;
27                 private final double roughnessSize;
28                 
29                 Finish(String name, double roughness) {
30                         this.name = name;
31                         this.roughnessSize = roughness;
32                 }
33                 
34                 public double getRoughnessSize() {
35                         return roughnessSize;
36                 }
37                 
38                 @Override
39                 public String toString() {
40                         return name + " (" + UnitGroup.UNITS_ROUGHNESS.toStringUnit(roughnessSize) + ")";
41                 }
42         }
43         
44         
45         /**
46          * The material of the component.
47          */
48         protected Material material = null;
49         
50         protected Finish finish = Finish.NORMAL;
51         
52         
53
54         /**
55          * Constructor that sets the relative position of the component.
56          */
57         public ExternalComponent(RocketComponent.Position relativePosition) {
58                 super(relativePosition);
59                 this.material = Prefs.getDefaultComponentMaterial(this.getClass(), Material.Type.BULK);
60         }
61         
62         /**
63          * Returns the volume of the component.  This value is used in calculating the mass
64          * of the object.
65          */
66         public abstract double getComponentVolume();
67         
68         /**
69          * Calculates the mass of the component as the product of the volume and interior density.
70          */
71         @Override
72         public double getComponentMass() {
73                 return material.getDensity() * getComponentVolume();
74         }
75         
76         /**
77          * ExternalComponent has aerodynamic effect, so return true.
78          */
79         @Override
80         public boolean isAerodynamic() {
81                 return true;
82         }
83         
84         /**
85          * ExternalComponent has effect on the mass, so return true.
86          */
87         @Override
88         public boolean isMassive() {
89                 return true;
90         }
91         
92         
93         public Material getMaterial() {
94                 return material;
95         }
96         
97         public void setMaterial(Material mat) {
98                 if (mat.getType() != Material.Type.BULK) {
99                         throw new IllegalArgumentException("ExternalComponent requires a bulk material" +
100                                         " type=" + mat.getType());
101                 }
102                 
103                 if (material.equals(mat))
104                         return;
105                 material = mat;
106                 fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
107         }
108         
109         public Finish getFinish() {
110                 return finish;
111         }
112         
113         public void setFinish(Finish finish) {
114                 if (this.finish == finish)
115                         return;
116                 this.finish = finish;
117                 fireComponentChangeEvent(ComponentChangeEvent.AERODYNAMIC_CHANGE);
118         }
119         
120         
121
122         @Override
123         protected List<RocketComponent> copyFrom(RocketComponent c) {
124                 ExternalComponent src = (ExternalComponent) c;
125                 this.finish = src.finish;
126                 this.material = src.material;
127                 return super.copyFrom(c);
128         }
129         
130     /**
131      * Accept a visitor to this ExternalComponent in the component hierarchy.
132      * 
133      * @param theVisitor  the visitor that will be called back with a reference to this ExternalComponent
134      */
135     @Override 
136     public void accept (final ComponentVisitor theVisitor) {
137         theVisitor.visit(this);
138     }
139     
140 }