1 package net.sf.openrocket.rocketcomponent;
3 import net.sf.openrocket.l10n.Translator;
4 import net.sf.openrocket.material.Material;
5 import net.sf.openrocket.preset.ComponentPreset;
6 import net.sf.openrocket.preset.ComponentPreset.Type;
7 import net.sf.openrocket.startup.Application;
8 import net.sf.openrocket.util.MathUtil;
10 public class Parachute extends RecoveryDevice {
11 private static final Translator trans = Application.getTranslator();
13 public static final double DEFAULT_CD = 0.8;
15 private double diameter;
17 private Material lineMaterial;
18 private int lineCount = 6;
19 private double lineLength = 0.3;
24 this.lineMaterial = Application.getPreferences().getDefaultComponentMaterial(Parachute.class, Material.Type.LINE);
25 this.lineLength = 0.3;
29 public double getDiameter() {
33 public void setDiameter(double d) {
34 if (MathUtil.equals(this.diameter, d))
38 fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
42 public final Material getLineMaterial() {
46 public final void setLineMaterial(Material mat) {
47 if (mat.getType() != Material.Type.LINE) {
48 throw new IllegalArgumentException("Attempted to set non-line material " + mat);
50 if (mat.equals(lineMaterial))
52 this.lineMaterial = mat;
53 if (getLineCount() != 0)
54 fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
56 fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE);
60 public final int getLineCount() {
64 public final void setLineCount(int n) {
65 if (this.lineCount == n)
69 fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
72 public final double getLineLength() {
76 public final void setLineLength(double length) {
77 if (MathUtil.equals(this.lineLength, length))
79 this.lineLength = length;
80 if (getLineCount() != 0)
81 fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
83 fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE);
88 public double getComponentCD(double mach) {
89 return DEFAULT_CD; // TODO: HIGH: Better parachute CD estimate?
93 public double getArea() {
94 return Math.PI * MathUtil.pow2(diameter / 2);
97 public void setArea(double area) {
98 if (MathUtil.equals(getArea(), area))
100 diameter = MathUtil.safeSqrt(area / Math.PI) * 2;
102 fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
106 public double getComponentMass() {
107 return super.getComponentMass() +
108 getLineCount() * getLineLength() * getLineMaterial().getDensity();
112 public String getComponentName() {
114 return trans.get("Parachute.Parachute");
118 public boolean allowsChildren() {
123 public boolean isCompatible(Class<? extends RocketComponent> type) {
129 protected void loadFromPreset(ComponentPreset preset) {
130 if( preset.has( ComponentPreset.DIAMETER )) {
131 this.diameter = preset.get( ComponentPreset.DIAMETER );
133 if( preset.has( ComponentPreset.LINE_COUNT )) {
134 this.lineCount = preset.get( ComponentPreset.LINE_COUNT );
136 if( preset.has( ComponentPreset.LINE_LENGTH )) {
137 this.lineLength = preset.get( ComponentPreset.LINE_LENGTH );
139 if( preset.has( ComponentPreset.LINE_MATERIAL )) {
140 this.lineMaterial = preset.get( ComponentPreset.LINE_MATERIAL );
142 super.loadFromPreset(preset);
147 public Type getPresetType() {
148 return ComponentPreset.Type.PARACHUTE;