1 package net.sf.openrocket.rocketcomponent;
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.preset.ExternalComponentPreset;
9 import net.sf.openrocket.preset.RocketComponentPreset;
10 import net.sf.openrocket.startup.Application;
11 import net.sf.openrocket.unit.UnitGroup;
12 import net.sf.openrocket.util.Prefs;
15 * Class of components with well-defined physical appearance and which have an effect on
16 * aerodynamic simulation. They have material defined for them, and the mass of the component
17 * is calculated using the component's volume.
19 * @author Sampo Niskanen <sampo.niskanen@iki.fi>
22 public abstract class ExternalComponent extends RocketComponent {
26 ROUGH("ExternalComponent.Rough", 500e-6),
28 UNFINISHED("ExternalComponent.Unfinished", 150e-6),
30 NORMAL("ExternalComponent.Regularpaint", 60e-6),
32 SMOOTH("ExternalComponent.Smoothpaint", 20e-6),
34 POLISHED("ExternalComponent.Polished", 2e-6);
36 private static final Translator trans = Application.getTranslator();
37 private final String name;
38 private final double roughnessSize;
40 Finish(String name, double roughness) {
42 this.roughnessSize = roughness;
45 public double getRoughnessSize() {
50 public String toString() {
51 return trans.get(name) + " (" + UnitGroup.UNITS_ROUGHNESS.toStringUnit(roughnessSize) + ")";
57 * The material of the component.
59 protected Material material = null;
61 protected Finish finish = Finish.NORMAL;
66 * Constructor that sets the relative position of the component.
68 public ExternalComponent(RocketComponent.Position relativePosition) {
69 super(relativePosition);
70 this.material = Prefs.getDefaultComponentMaterial(this.getClass(), Material.Type.BULK);
74 * Returns the volume of the component. This value is used in calculating the mass
77 public abstract double getComponentVolume();
80 * Calculates the mass of the component as the product of the volume and interior density.
83 public double getComponentMass() {
84 return material.getDensity() * getComponentVolume();
88 * ExternalComponent has aerodynamic effect, so return true.
91 public boolean isAerodynamic() {
96 * ExternalComponent has effect on the mass, so return true.
99 public boolean isMassive() {
104 public Material getMaterial() {
108 public void setMaterial(Material mat) {
109 if (mat.getType() != Material.Type.BULK) {
110 throw new IllegalArgumentException("ExternalComponent requires a bulk material" +
111 " type=" + mat.getType());
114 if (material.equals(mat))
118 fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
121 public Finish getFinish() {
125 public void setFinish(Finish finish) {
126 if (this.finish == finish)
128 this.finish = finish;
129 fireComponentChangeEvent(ComponentChangeEvent.AERODYNAMIC_CHANGE);
134 protected void loadFromPreset(RocketComponentPreset preset) {
135 super.loadFromPreset(preset);
137 ExternalComponentPreset p = (ExternalComponentPreset) preset;
138 String materialName = p.getMaterialName();
139 double mass = p.getMass();
141 double volume = getComponentVolume();
143 if (volume > 0.00001) {
144 density = mass / volume;
149 Material mat = Material.newMaterial(Type.BULK, materialName, density, true);
155 protected List<RocketComponent> copyFrom(RocketComponent c) {
156 ExternalComponent src = (ExternalComponent) c;
157 this.finish = src.finish;
158 this.material = src.material;
159 return super.copyFrom(c);