Merge branch 'upstream' into debian
[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.l10n.Translator;
6 import net.sf.openrocket.material.Material;
7 import net.sf.openrocket.material.Material.Type;
8 import net.sf.openrocket.startup.Application;
9 import net.sf.openrocket.unit.UnitGroup;
10 import net.sf.openrocket.util.Prefs;
11
12 /**
13  * Class of components with well-defined physical appearance and which have an effect on
14  * aerodynamic simulation.  They have material defined for them, and the mass of the component
15  * is calculated using the component's volume.
16  *
17  * @author Sampo Niskanen <sampo.niskanen@iki.fi>
18  */
19
20 public abstract class ExternalComponent extends RocketComponent {
21         
22         public enum Finish {
23                 //// Rough
24                 ROUGH("ExternalComponent.Rough", 500e-6),
25                 //// Unfinished
26                 UNFINISHED("ExternalComponent.Unfinished", 150e-6),
27                 //// Regular paint
28                 NORMAL("ExternalComponent.Regularpaint", 60e-6),
29                 //// Smooth paint
30                 SMOOTH("ExternalComponent.Smoothpaint", 20e-6),
31                 //// Polished
32                 POLISHED("ExternalComponent.Polished", 2e-6);
33                 
34                 private static final Translator trans = Application.getTranslator();
35                 private final String name;
36                 private final double roughnessSize;
37                 
38                 Finish(String name, double roughness) {
39                         this.name = name;
40                         this.roughnessSize = roughness;
41                 }
42                 
43                 public double getRoughnessSize() {
44                         return roughnessSize;
45                 }
46                 
47                 @Override
48                 public String toString() {
49                         return trans.get(name) + " (" + UnitGroup.UNITS_ROUGHNESS.toStringUnit(roughnessSize) + ")";
50                 }
51         }
52         
53         
54         /**
55          * The material of the component.
56          */
57         protected Material material = null;
58         
59         protected Finish finish = Finish.NORMAL;
60         
61         
62
63         /**
64          * Constructor that sets the relative position of the component.
65          */
66         public ExternalComponent(RocketComponent.Position relativePosition) {
67                 super(relativePosition);
68                 this.material = Prefs.getDefaultComponentMaterial(this.getClass(), Material.Type.BULK);
69         }
70         
71         /**
72          * Returns the volume of the component.  This value is used in calculating the mass
73          * of the object.
74          */
75         public abstract double getComponentVolume();
76         
77         /**
78          * Calculates the mass of the component as the product of the volume and interior density.
79          */
80         @Override
81         public double getComponentMass() {
82                 return material.getDensity() * getComponentVolume();
83         }
84         
85         /**
86          * ExternalComponent has aerodynamic effect, so return true.
87          */
88         @Override
89         public boolean isAerodynamic() {
90                 return true;
91         }
92         
93         /**
94          * ExternalComponent has effect on the mass, so return true.
95          */
96         @Override
97         public boolean isMassive() {
98                 return true;
99         }
100         
101         
102         public Material getMaterial() {
103                 return material;
104         }
105         
106         public void setMaterial(Material mat) {
107                 if (mat.getType() != Material.Type.BULK) {
108                         throw new IllegalArgumentException("ExternalComponent requires a bulk material" +
109                                         " type=" + mat.getType());
110                 }
111                 
112                 if (material.equals(mat))
113                         return;
114                 material = mat;
115                 clearPreset();
116                 fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
117                 clearPreset();
118         }
119         
120         public Finish getFinish() {
121                 return finish;
122         }
123         
124         public void setFinish(Finish finish) {
125                 if (this.finish == finish)
126                         return;
127                 this.finish = finish;
128                 fireComponentChangeEvent(ComponentChangeEvent.AERODYNAMIC_CHANGE);
129         }
130         
131         
132         @Override
133         protected void loadFromPreset(RocketComponent preset) {
134                 super.loadFromPreset(preset);
135                 
136                 // Surface finish is left unchanged
137                 
138                 ExternalComponent c = (ExternalComponent) preset;
139                 
140                 Material mat = c.getMaterial();
141                 if (c.isMassOverridden()) {
142                         double mass = c.getOverrideMass();
143                         double volume = getComponentVolume();
144                         double density;
145                         if (volume > 0.00001) {
146                                 density = mass / volume;
147                         } else {
148                                 density = 1000;
149                         }
150                         mat = Material.newMaterial(Type.BULK, mat.getName(), density, true);
151                 }
152                 
153                 setMaterial(mat);
154         }
155         
156         
157         @Override
158         protected List<RocketComponent> copyFrom(RocketComponent c) {
159                 ExternalComponent src = (ExternalComponent) c;
160                 this.finish = src.finish;
161                 this.material = src.material;
162                 return super.copyFrom(c);
163         }
164         
165 }