package com.billkuker.rocketry.motorsim;\r
\r
+import java.util.List;\r
+\r
import javax.measure.quantity.Area;\r
import javax.measure.quantity.Length;\r
import javax.measure.quantity.Volume;\r
\r
import org.jscience.physics.amount.Amount;\r
\r
-public interface Grain {\r
+public interface Grain {\r
\r
\r
public java.awt.geom.Area getCrossSection(Amount<Length> regression);\r
public interface DiscreteRegression{\r
public Amount<Length> optimalRegressionStep();\r
}\r
+ \r
+ public interface Composite {\r
+ public List<Grain> getGrains();\r
+ }\r
\r
public Amount<Area> surfaceArea(Amount<Length> regression);\r
\r
--- /dev/null
+package com.billkuker.rocketry.motorsim.grain;\r
+\r
+import java.awt.geom.AffineTransform;\r
+import java.awt.geom.Rectangle2D;\r
+import java.util.Collections;\r
+import java.util.List;\r
+import java.util.Vector;\r
+\r
+import javax.measure.quantity.Area;\r
+import javax.measure.quantity.Length;\r
+import javax.measure.quantity.Volume;\r
+import javax.measure.unit.SI;\r
+\r
+import org.jscience.physics.amount.Amount;\r
+\r
+import com.billkuker.rocketry.motorsim.Grain;\r
+\r
+public class GrainSet implements Grain, Grain.Composite {\r
+ \r
+ private Vector<Grain> grains = new Vector<Grain>();\r
+ \r
+ private double flush = 1;\r
+ private Amount<Length> delay = Amount.valueOf(0, SI.MILLIMETER);\r
+ \r
+ public GrainSet( Grain... gs ){\r
+ for ( Grain g : gs )\r
+ grains.add(g);\r
+ }\r
+ \r
+ private Amount<Length> getAdjustedRegression(Amount<Length> regression, int grain){\r
+ return regression.minus(delay.times(grain)).times(Math.pow(flush,grain));\r
+ }\r
+\r
+ public Amount<Area> surfaceArea(Amount<Length> regression) {\r
+ Amount<Area> ret = Amount.valueOf(0, SI.SQUARE_METRE);\r
+ for ( int i = 0; i < grains.size(); i++ ){\r
+ ret = ret.plus(grains.elementAt(i).surfaceArea(getAdjustedRegression(regression, i)));\r
+ }\r
+ return ret;\r
+ }\r
+\r
+ public Amount<Volume> volume(Amount<Length> regression) {\r
+ Amount<Volume> ret = Amount.valueOf(0, SI.CUBIC_METRE);\r
+ for ( int i = 0; i < grains.size(); i++ ){\r
+ ret = ret.plus(grains.elementAt(i).volume(getAdjustedRegression(regression, i)));\r
+ }\r
+ return ret;\r
+ }\r
+\r
+ public Amount<Length> webThickness() {\r
+ Amount<Length> max = Amount.valueOf(0, SI.MILLIMETER);;\r
+ for ( int i = 0; i < grains.size(); i++ ){\r
+ Grain g = grains.elementAt(i);\r
+ Amount<Length> t = g.webThickness().plus(delay.times(i));\r
+ if ( t.isGreaterThan(max))\r
+ max = t;\r
+ }\r
+ return max;\r
+ }\r
+\r
+ public java.awt.geom.Area getCrossSection(Amount<Length> regression) {\r
+ java.awt.geom.Area a = new java.awt.geom.Area();\r
+ for ( int i = 0; i < grains.size(); i++ ){\r
+ Rectangle2D unburntBounds = grains.elementAt(i).getSideView(Amount.valueOf(0, SI.MILLIMETER)).getBounds2D();\r
+ a.add(grains.elementAt(i).getCrossSection(getAdjustedRegression(regression, i)));\r
+ a.transform(AffineTransform.getTranslateInstance(0, -(unburntBounds.getHeight() + 5)));\r
+ }\r
+ return a;\r
+ }\r
+\r
+ public java.awt.geom.Area getSideView(Amount<Length> regression) {\r
+ \r
+ \r
+ java.awt.geom.Area ret = new java.awt.geom.Area();\r
+\r
+ for ( int i = 0 ; i < grains.size() ; i++ ){\r
+ Rectangle2D unburntBounds = grains.elementAt(i).getSideView(Amount.valueOf(0, SI.MILLIMETER)).getBounds2D();\r
+ java.awt.geom.Area g = grains.elementAt(i).getSideView(getAdjustedRegression(regression, i));\r
+ ret.add(g); \r
+ ret.transform(AffineTransform.getTranslateInstance(0, -(unburntBounds.getHeight() + 10)));\r
+ }\r
+ return ret;\r
+ }\r
+\r
+ public List<Grain> getGrains() {\r
+ return Collections.unmodifiableList(grains);\r
+ }\r
+\r
+}\r
\r
import java.awt.geom.AffineTransform;\r
import java.awt.geom.Rectangle2D;\r
+import java.beans.PropertyChangeEvent;\r
+import java.beans.PropertyChangeListener;\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.List;\r
\r
import javax.measure.quantity.Area;\r
import javax.measure.quantity.Length;\r
import org.jscience.physics.amount.Amount;\r
\r
import com.billkuker.rocketry.motorsim.Grain;\r
+import com.billkuker.rocketry.motorsim.MotorPart;\r
\r
-public class MultiGrain implements Grain {\r
+public class MultiGrain extends MotorPart implements Grain, Grain.Composite, PropertyChangeListener {\r
\r
- private Grain grain;\r
- private int count;\r
+ private Grain grain = null;\r
+ private int count = 1;\r
\r
+ public int getCount() {\r
+ return count;\r
+ }\r
+\r
+ public void setCount(int count) {\r
+ int old = this.count;\r
+ this.count = count;\r
+ firePropertyChange("Count", old, count );\r
+ }\r
+ \r
+ public void setGrain(Grain g){\r
+ Grain old = grain;\r
+ grain = g;\r
+ if ( g instanceof MotorPart ){\r
+ ((MotorPart)g).addPropertyChangeListener(this);\r
+ }\r
+ firePropertyChange("Grain", old, grain);\r
+ }\r
+ \r
+ public Grain getGrain(){\r
+ return grain;\r
+ }\r
+\r
private double flush = 1;\r
private Amount<Length> delay = Amount.valueOf(0, SI.MILLIMETER);\r
\r
+ public MultiGrain(){\r
+ }\r
+ \r
public MultiGrain( Grain g, int c ){\r
- grain = g;\r
count = c;\r
+ setGrain(g);\r
}\r
\r
private Amount<Length> getAdjustedRegression(Amount<Length> regression, int grain){\r
return ret;\r
}\r
\r
+ public List<Grain> getGrains() {\r
+ ArrayList<Grain> ret = new ArrayList<Grain>();\r
+ ret.add(grain);\r
+ return Collections.unmodifiableList(ret);\r
+ }\r
+\r
+ public void propertyChange(PropertyChangeEvent evt) {\r
+ firePropertyChange(evt);\r
+ }\r
+\r
}\r