[Major Refactor] Parallel stages are children of centerline stages
This commit is contained in:
parent
2f42594acb
commit
5f42a10c20
@ -62,26 +62,12 @@ public class StageSaver extends ComponentAssemblySaver {
|
||||
|
||||
private Collection<? extends String> addStageReplicationParams(final Stage currentStage) {
|
||||
List<String> elementsToReturn = new ArrayList<String>();
|
||||
final String relTo_tag = "relativeto";
|
||||
final String outside_tag = "outside";
|
||||
final String instCt_tag = "instancecount";
|
||||
final String radoffs_tag = "radialoffset";
|
||||
final String startangle_tag = "angleoffset";
|
||||
|
||||
|
||||
if (null != currentStage) {
|
||||
// Save position unless "AFTER"
|
||||
if (currentStage.getRelativePosition() != RocketComponent.Position.AFTER) {
|
||||
// position type and offset are saved in superclass
|
||||
// String type = currentStage.getRelativePositionMethod().name().toLowerCase(Locale.ENGLISH);
|
||||
// double axialOffset = currentStage.getAxialPosition();
|
||||
// elementsToReturn.add("<position type=\"" + type + "\">" + axialOffset + "</position>");
|
||||
int relativeTo = currentStage.getRelativeToStage();
|
||||
elementsToReturn.add("<" + relTo_tag + ">" + relativeTo + "</" + relTo_tag + ">");
|
||||
}
|
||||
|
||||
boolean outsideFlag = currentStage.getOutside();
|
||||
elementsToReturn.add("<" + outside_tag + ">" + outsideFlag + "</" + outside_tag + ">");
|
||||
int instanceCount = currentStage.getInstanceCount();
|
||||
elementsToReturn.add("<" + instCt_tag + ">" + instanceCount + "</" + instCt_tag + ">");
|
||||
double radialOffset = currentStage.getRadialOffset();
|
||||
|
@ -664,6 +664,7 @@ public abstract class FinSet extends ExternalComponent {
|
||||
finArea = -1;
|
||||
cantRotation = null;
|
||||
}
|
||||
super.componentChanged(e);
|
||||
}
|
||||
|
||||
|
||||
|
@ -77,7 +77,6 @@ public class Rocket extends RocketComponent {
|
||||
flightConfigurationIDs.add(null);
|
||||
}
|
||||
|
||||
|
||||
// Does the rocket have a perfect finish (a notable amount of laminar flow)
|
||||
private boolean perfectFinish = false;
|
||||
|
||||
@ -93,6 +92,8 @@ public class Rocket extends RocketComponent {
|
||||
treeModID = modID;
|
||||
functionalModID = modID;
|
||||
defaultConfiguration = new Configuration(this);
|
||||
|
||||
Stage.resetStageCount();
|
||||
}
|
||||
|
||||
|
||||
|
@ -79,12 +79,17 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
||||
/**
|
||||
* Parent component of the current component, or null if none exists.
|
||||
*/
|
||||
private RocketComponent parent = null;
|
||||
protected RocketComponent parent = null;
|
||||
|
||||
/**
|
||||
* previous child in parent's child list
|
||||
*/
|
||||
protected RocketComponent previousComponent = null;
|
||||
|
||||
/**
|
||||
* List of child components of this component.
|
||||
*/
|
||||
private ArrayList<RocketComponent> children = new ArrayList<RocketComponent>();
|
||||
protected ArrayList<RocketComponent> children = new ArrayList<RocketComponent>();
|
||||
|
||||
|
||||
//////// Parameters common to all components:
|
||||
@ -106,7 +111,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
||||
* Offset of the position of this component relative to the normal position given by
|
||||
* relativePosition. By default zero, i.e. no position change.
|
||||
*/
|
||||
// protected double position = 0;
|
||||
protected double offset = 0;
|
||||
|
||||
/**
|
||||
* Position of this component relative to it's parent.
|
||||
@ -298,11 +303,11 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
||||
protected void componentChanged(ComponentChangeEvent e) {
|
||||
// No-op
|
||||
checkState();
|
||||
this.update();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return the user-provided name of the component, or the component base
|
||||
* name if the user-provided name is empty. This can be used in the UI.
|
||||
@ -883,7 +888,6 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
||||
* @param position the relative positioning.
|
||||
*/
|
||||
protected void setRelativePosition(RocketComponent.Position position) {
|
||||
|
||||
// this variable does not change the internal representation
|
||||
// the relativePosition (method) is just the lens through which external code may view this component's position.
|
||||
this.relativePosition = position;
|
||||
@ -898,40 +902,41 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
||||
*
|
||||
* @return double position of the component relative to the parent, with respect to <code>position</code>
|
||||
*/
|
||||
public double asPositionValue(Position thePosition, RocketComponent relativeTo) {
|
||||
double result = this.position.x; // relative
|
||||
// this should be the usual case.... only 'Stage' classes should call this with anything else....
|
||||
double relativeAxialPosition = this.position.x;
|
||||
if (relativeTo != this.parent) {
|
||||
Coordinate refAbsPos = relativeTo.getAbsolutePositionVector();
|
||||
Coordinate curAbsPos = this.getAbsolutePositionVector();
|
||||
relativeAxialPosition = (curAbsPos.x - refAbsPos.x);
|
||||
public double asPositionValue(Position thePosition) {
|
||||
if (null == this.parent) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
if (relativeTo != null) {
|
||||
double relLength = relativeTo.getLength();
|
||||
double thisCenterX = this.position.x;
|
||||
double relativeLength = this.parent.length;
|
||||
double result = Double.NaN;
|
||||
|
||||
switch (thePosition) {
|
||||
case AFTER:
|
||||
result = relativeAxialPosition + (-relLength - this.getLength()) / 2;
|
||||
if (null == this.previousComponent) {
|
||||
result = thisCenterX + (relativeLength - this.getLength()) / 2;
|
||||
} else {
|
||||
double relativeAxialOffset = this.previousComponent.getRelativePositionVector().x;
|
||||
relativeLength = this.previousComponent.getLength();
|
||||
result = (thisCenterX - relativeAxialOffset) - (relativeLength + this.getLength()) / 2;
|
||||
}
|
||||
break;
|
||||
case ABSOLUTE:
|
||||
Coordinate curAbsPos = this.getAbsolutePositionVector();
|
||||
result = curAbsPos.x;
|
||||
result = this.getAbsolutePositionVector().x;
|
||||
break;
|
||||
case TOP:
|
||||
result = relativeAxialPosition + (relLength - this.getLength()) / 2;
|
||||
result = thisCenterX + (relativeLength - this.getLength()) / 2;
|
||||
break;
|
||||
case MIDDLE:
|
||||
result = relativeAxialPosition;
|
||||
result = thisCenterX;
|
||||
break;
|
||||
case BOTTOM:
|
||||
result = relativeAxialPosition + (this.length - relLength) / 2;
|
||||
result = thisCenterX + (this.length - relativeLength) / 2;
|
||||
break;
|
||||
default:
|
||||
throw new BugException("Unknown position type: " + thePosition);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -948,7 +953,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
||||
|
||||
public double getAxialOffset() {
|
||||
mutex.verify();
|
||||
return this.asPositionValue(this.relativePosition, this.parent);
|
||||
return this.asPositionValue(this.relativePosition);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -990,72 +995,88 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
||||
setAxialOffset(value);
|
||||
}
|
||||
|
||||
public void setAxialOffset(double value) {
|
||||
this.setAxialOffset(this.relativePosition, value, this.getParent());
|
||||
public void setAxialOffset(double _value) {
|
||||
this.setAxialOffset(this.relativePosition, _value);
|
||||
this.fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
|
||||
}
|
||||
|
||||
protected void setAxialOffset(Position positionMethod, double newOffset, RocketComponent referenceComponent) {
|
||||
// if this is the root of a hierarchy, constrain the position to zeros.
|
||||
// if referenceComponent is null, the function call is simply in error
|
||||
protected void setAfter(RocketComponent referenceComponent) {
|
||||
checkState();
|
||||
|
||||
if ((null == this.parent) || (referenceComponent == null)) {
|
||||
double newAxialPosition;
|
||||
double refLength;
|
||||
|
||||
if (null == referenceComponent) {
|
||||
// if this is the first component in the stage, position from the top of the parent
|
||||
if (null == this.parent) {
|
||||
// Probably initialization order issue. Ignore a.t.t.
|
||||
return;
|
||||
} else {
|
||||
refLength = this.parent.getLength();
|
||||
newAxialPosition = (-refLength + this.length) / 2;
|
||||
}
|
||||
} else {
|
||||
refLength = referenceComponent.getLength();
|
||||
double refRelX = referenceComponent.getRelativePositionVector().x;
|
||||
|
||||
newAxialPosition = refRelX + (refLength + this.length) / 2;
|
||||
}
|
||||
|
||||
//this.relativePosition = Position.AFTER;
|
||||
this.position = new Coordinate(newAxialPosition, this.position.y, this.position.z);
|
||||
}
|
||||
|
||||
protected void setAxialOffset(Position positionMethod, double newOffset) {
|
||||
// if this is the root of a hierarchy, constrain the position to zero.
|
||||
if (null == this.parent) {
|
||||
return;
|
||||
}
|
||||
if (referenceComponent == this) {
|
||||
throw new BugException("cannot move a component relative to itself!");
|
||||
}
|
||||
checkState();
|
||||
// if (this instanceof Stage) {
|
||||
// System.err.println(String.format(" Setting Stage X offs: type: %s pos: %f <== (%s,%f,%s)", this.relativePosition.name(), this.position.x,
|
||||
// positionMethod.name(), newOffset, referenceComponent.getName()));
|
||||
// }
|
||||
|
||||
this.relativePosition = positionMethod;
|
||||
this.offset = newOffset;
|
||||
|
||||
double newAxialPosition = Double.NaN;
|
||||
double refRelX = referenceComponent.position.x;
|
||||
double refLength = referenceComponent.getLength();
|
||||
|
||||
if (referenceComponent.isAncestor(this)) {
|
||||
referenceComponent = this.parent;
|
||||
refRelX = 0;
|
||||
}
|
||||
double refLength = this.parent.getLength();
|
||||
|
||||
switch (positionMethod) {
|
||||
case ABSOLUTE:
|
||||
newAxialPosition = newOffset - this.parent.position.x;
|
||||
break;
|
||||
case AFTER:
|
||||
newAxialPosition = refRelX + (refLength + this.length) / 2;
|
||||
break;
|
||||
this.setAfter(this.previousComponent);
|
||||
return;
|
||||
case TOP:
|
||||
newAxialPosition = refRelX + (-refLength + this.length) / 2 + newOffset;
|
||||
newAxialPosition = (-refLength + this.length) / 2 + newOffset;
|
||||
break;
|
||||
case MIDDLE:
|
||||
newAxialPosition = refRelX + newOffset;
|
||||
newAxialPosition = newOffset;
|
||||
break;
|
||||
case BOTTOM:
|
||||
newAxialPosition = refRelX + (+refLength - this.length) / 2 + newOffset;
|
||||
newAxialPosition = (+refLength - this.length) / 2 + newOffset;
|
||||
break;
|
||||
default:
|
||||
throw new BugException("Unknown position type: " + positionMethod);
|
||||
}
|
||||
|
||||
if (Double.NaN == newAxialPosition) {
|
||||
throw new BugException("setAxialOffset is broken -- attempted to update as NaN: " + this.toDebugDetail());
|
||||
}
|
||||
this.position = new Coordinate(newAxialPosition, this.position.y, this.position.z);
|
||||
}
|
||||
|
||||
// if ((this instanceof Stage) && (2 == this.getStageNumber())) {
|
||||
// System.err.println(String.format(" Set Stage X offs: type: %s pos: %f", this.relativePosition.name(), this.position.x));
|
||||
// }
|
||||
protected void update() {
|
||||
if (null == this.parent) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setAxialOffset(this.relativePosition, this.offset);
|
||||
}
|
||||
|
||||
public Coordinate getRelativePositionVector() {
|
||||
return this.position;
|
||||
}
|
||||
|
||||
// disabled
|
||||
// public void setRelativePositionVector(final Coordinate _newPos) {
|
||||
// // this.setPosition( this.relativePosition, _newPos );
|
||||
// }
|
||||
|
||||
public Coordinate getAbsolutePositionVector() {
|
||||
if (null == this.parent) { // i.e. root / Rocket instance OR improperly initialized components
|
||||
return new Coordinate();
|
||||
@ -1364,6 +1385,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
||||
throw new IllegalStateException("Component " + component.getComponentName() +
|
||||
" not currently compatible with component " + getComponentName());
|
||||
}
|
||||
|
||||
children.add(index, component);
|
||||
component.parent = this;
|
||||
|
||||
@ -1556,23 +1578,24 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
||||
*
|
||||
* @return the stage number this component belongs to.
|
||||
*/
|
||||
public final int getStageNumber() {
|
||||
public int getStageNumber() {
|
||||
checkState();
|
||||
if (parent == null) {
|
||||
throw new IllegalArgumentException("getStageNumber() called for root component");
|
||||
}
|
||||
|
||||
RocketComponent stage = this;
|
||||
while (!(stage instanceof Stage)) {
|
||||
stage = stage.parent;
|
||||
if (stage == null || stage.parent == null) {
|
||||
RocketComponent curComponent = this;
|
||||
while (!(curComponent instanceof Stage)) {
|
||||
curComponent = curComponent.parent;
|
||||
if (curComponent == null || curComponent.parent == null) {
|
||||
throw new IllegalStateException("getStageNumber() could not find parent " +
|
||||
"stage.");
|
||||
}
|
||||
}
|
||||
return stage.parent.getChildPosition(stage);
|
||||
}
|
||||
Stage stage = (Stage) curComponent;
|
||||
|
||||
return stage.getStageNumber();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a component with the given ID. The component tree is searched from this component
|
||||
@ -2077,16 +2100,46 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
||||
}
|
||||
}
|
||||
|
||||
// Primarily for debug use
|
||||
public void dumpTree(final boolean includeHeader, final String prefix) {
|
||||
if (includeHeader) {
|
||||
System.err.println(" [Name] [Length] [Rel Pos] [Abs Pos] ");
|
||||
// multi-line output
|
||||
protected StringBuilder toDebugDetail() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
StackTraceElement[] stackTrace = (new Exception()).getStackTrace();
|
||||
buf.append(" >> Dumping Detailed Information from: " + stackTrace[1].getMethodName() + "\n");
|
||||
buf.append(" current Component: " + this.getName() + " ofClass: " + this.getClass().getSimpleName() + "\n");
|
||||
buf.append(" offset: " + this.offset + " via: " + this.relativePosition.name() + " => " + this.getAxialOffset() + "\n");
|
||||
buf.append(" thisCenterX: " + this.position.x + "\n");
|
||||
buf.append(" this length: " + this.length + "\n");
|
||||
if (null == this.previousComponent) {
|
||||
buf.append(" ..prevComponent: " + null + "\n");
|
||||
} else {
|
||||
RocketComponent refComp = this.previousComponent;
|
||||
buf.append(" >>prevCompName: " + refComp.getName() + "\n");
|
||||
buf.append(" ..prevCenterX: " + refComp.position.x + "\n");
|
||||
buf.append(" ..prevLength: " + refComp.getLength() + "\n");
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
System.err.println(String.format("%s >> %-24s %5.3f %24s %24s", prefix, this.getName(), this.getLength(), this.getRelativePositionVector(), this.getAbsolutePositionVector()));
|
||||
// Primarily for debug use
|
||||
public String toDebugTree() {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append("\n ====== ====== ====== ====== ====== ====== ====== ====== ====== ====== ====== ======\n");
|
||||
buffer.append(" [Name] [Length] [Rel Pos] [Abs Pos] \n");
|
||||
this.dumpTreeHelper(buffer, "");
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public void toDebugTreeNode(final StringBuilder buffer, final String prefix) {
|
||||
buffer.append(String.format("%s %-24s %5.3f %24s %24s\n", prefix, this.getName(), this.getLength(),
|
||||
this.getRelativePositionVector(), this.getAbsolutePositionVector()));
|
||||
}
|
||||
|
||||
public void dumpTreeHelper(StringBuilder buffer, final String prefix) {
|
||||
this.toDebugTreeNode(buffer, prefix);
|
||||
|
||||
Iterator<RocketComponent> iterator = this.children.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
iterator.next().dumpTree(false, prefix + " ");
|
||||
iterator.next().dumpTreeHelper(buffer, prefix + " ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,76 +17,27 @@ public class Stage extends ComponentAssembly implements FlightConfigurableCompon
|
||||
|
||||
private FlightConfigurationImpl<StageSeparationConfiguration> separationConfigurations;
|
||||
|
||||
private boolean outside = false;
|
||||
private boolean centerline = true;
|
||||
private double angularPosition_rad = 0;
|
||||
private double radialPosition_m = 0;
|
||||
private Stage stageRelativeTo = null;
|
||||
|
||||
private int count = 1;
|
||||
private double angularSeparation = Math.PI;
|
||||
|
||||
private int stageNumber;
|
||||
private static int stageCount;
|
||||
|
||||
public Stage() {
|
||||
this.separationConfigurations = new FlightConfigurationImpl<StageSeparationConfiguration>(this, ComponentChangeEvent.EVENT_CHANGE, new StageSeparationConfiguration());
|
||||
this.relativePosition = Position.AFTER;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void componentChanged(ComponentChangeEvent e) {
|
||||
checkState();
|
||||
|
||||
if (e.isAerodynamicChange() || e.isMassChange()) {
|
||||
// System.err.println(">> in (" + this.getStageNumber() + ")" + this.getName());
|
||||
// update this component
|
||||
this.updateBounds();
|
||||
this.updateCenter();
|
||||
|
||||
// now update children relative to this
|
||||
int childIndex = 0;
|
||||
int childCount = this.getChildCount();
|
||||
RocketComponent prevComp = null;
|
||||
while (childIndex < childCount) {
|
||||
RocketComponent curComp = this.getChild(childIndex);
|
||||
// System.err.println(" updating position of " + curComp + " via (AFTER, O, " + prevComp + ")");
|
||||
if (0 == childIndex) {
|
||||
curComp.setAxialOffset(Position.TOP, 0, this);
|
||||
} else {
|
||||
if (Position.AFTER != curComp.getRelativePositionMethod()) {
|
||||
throw new IllegalStateException(" direct children of a Stage are expected to be positioned via AFTER.");
|
||||
}
|
||||
curComp.setAxialOffset(Position.AFTER, 0, prevComp);
|
||||
}
|
||||
// System.err.println(" position updated to: " + curComp.getAxialOffset());
|
||||
|
||||
prevComp = curComp;
|
||||
childIndex++;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
stageNumber = Stage.stageCount;
|
||||
Stage.stageCount++;
|
||||
}
|
||||
|
||||
protected String toPositionString() {
|
||||
return ">> " + this.getName() + " rel: " + this.getRelativePositionVector().x + " abs: " + this.getAbsolutePositionVector().x;
|
||||
}
|
||||
|
||||
protected void dumpDetail() {
|
||||
StackTraceElement[] stackTrace = (new Exception()).getStackTrace();
|
||||
System.err.println(" >> Dumping Stage Detailed Information from: " + stackTrace[1].getMethodName());
|
||||
System.err.println(" curStageName: " + this.getName());
|
||||
System.err.println(" method: " + this.relativePosition.name());
|
||||
System.err.println(" thisCenterX: " + this.position.x);
|
||||
System.err.println(" this length: " + this.length);
|
||||
if (-1 == this.getRelativeToStage()) {
|
||||
System.err.println(" ..refStageName: " + null);
|
||||
} else {
|
||||
Stage refStage = this.stageRelativeTo;
|
||||
System.err.println(" ..refStageName: " + refStage.getName());
|
||||
System.err.println(" ..refCenterX: " + refStage.position.x);
|
||||
System.err.println(" ..refLength: " + refStage.getLength());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getComponentName() {
|
||||
@ -103,6 +54,30 @@ public class Stage extends ComponentAssembly implements FlightConfigurableCompon
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toDebugTreeNode(final StringBuilder buffer, final String prefix) {
|
||||
|
||||
String thisLabel = this.getName() + " (" + this.getStageNumber() + ")";
|
||||
|
||||
buffer.append(String.format("%s %-24s %5.3f %24s %24s", prefix, thisLabel, this.getLength(),
|
||||
this.getRelativePositionVector(), this.getAbsolutePositionVector()));
|
||||
|
||||
if (this.isCenterline()) {
|
||||
buffer.append("\n");
|
||||
} else {
|
||||
buffer.append(String.format(" %4.1f//%s \n", this.getAxialOffset(), this.relativePosition.name()));
|
||||
Coordinate componentAbsolutePosition = this.getAbsolutePositionVector();
|
||||
Coordinate[] instanceCoords = new Coordinate[] { componentAbsolutePosition };
|
||||
instanceCoords = this.shiftCoordinates(instanceCoords);
|
||||
|
||||
for (int instance = 0; instance < this.count; instance++) {
|
||||
Coordinate instanceAbsolutePosition = instanceCoords[instance];
|
||||
buffer.append(String.format("%s [instance %2d of %2d] %s\n", prefix, instance, count, instanceAbsolutePosition));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given type can be added to this component. A Stage allows
|
||||
* only BodyComponents to be added.
|
||||
@ -113,8 +88,12 @@ public class Stage extends ComponentAssembly implements FlightConfigurableCompon
|
||||
*/
|
||||
@Override
|
||||
public boolean isCompatible(Class<? extends RocketComponent> type) {
|
||||
if (type.equals(Stage.class)) {
|
||||
return true;
|
||||
} else {
|
||||
return BodyComponent.class.isAssignableFrom(type);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cloneFlightConfiguration(String oldConfigId, String newConfigId) {
|
||||
@ -129,35 +108,34 @@ public class Stage extends ComponentAssembly implements FlightConfigurableCompon
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean getOutside() {
|
||||
return this.outside;
|
||||
return !isCenterline();
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects if this Stage is attached directly to the Rocket (and is thus centerline)
|
||||
* Or if this stage is a parallel (external) stage.
|
||||
*
|
||||
* @return whether this Stage is along the center line of the Rocket.
|
||||
*/
|
||||
@Override
|
||||
public boolean isCenterline() {
|
||||
return !this.outside;
|
||||
if (this.parent instanceof Rocket) {
|
||||
this.centerline = true;
|
||||
} else {
|
||||
this.centerline = false;
|
||||
}
|
||||
return this.centerline;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stub.
|
||||
* The actual value is set via 'isCenterline()'
|
||||
*/
|
||||
@Override
|
||||
public void setOutside(final boolean _outside) {
|
||||
if (this.outside == _outside) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.outside = _outside;
|
||||
if (this.outside) {
|
||||
this.relativePosition = Position.BOTTOM;
|
||||
if (null == this.stageRelativeTo) {
|
||||
this.stageRelativeTo = this.updatePrevAxialStage();
|
||||
}
|
||||
} else {
|
||||
this.relativePosition = Position.AFTER;
|
||||
this.stageRelativeTo = this.updatePrevAxialStage();
|
||||
this.count = 1;
|
||||
}
|
||||
|
||||
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -172,67 +150,81 @@ public class Stage extends ComponentAssembly implements FlightConfigurableCompon
|
||||
@Override
|
||||
public void setInstanceCount(final int _count) {
|
||||
mutex.verify();
|
||||
if (this.centerline) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.count = _count;
|
||||
this.angularSeparation = Math.PI * 2 / this.count;
|
||||
|
||||
if (this.outside) {
|
||||
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getAngularOffset() {
|
||||
if (this.outside) {
|
||||
return this.angularPosition_rad;
|
||||
} else {
|
||||
if (this.centerline) {
|
||||
return 0.;
|
||||
} else {
|
||||
return this.angularPosition_rad;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAngularOffset(final double angle_rad) {
|
||||
this.angularPosition_rad = angle_rad;
|
||||
if (this.outside) {
|
||||
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
|
||||
if (this.centerline) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.angularPosition_rad = angle_rad;
|
||||
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getRadialOffset() {
|
||||
if (this.outside) {
|
||||
return this.radialPosition_m;
|
||||
} else {
|
||||
if (this.centerline) {
|
||||
return 0.;
|
||||
} else {
|
||||
return this.radialPosition_m;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRadialOffset(final double radius) {
|
||||
this.radialPosition_m = radius;
|
||||
// log.error(" set radial position for: " + this.getName() + " to: " + this.radialPosition_m + " ... in meters?");
|
||||
if (this.outside) {
|
||||
if (false == this.centerline) {
|
||||
this.radialPosition_m = radius;
|
||||
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
|
||||
}
|
||||
}
|
||||
|
||||
public void setRelativePositionMethod(final Position _newPosition) {
|
||||
if (Position.AFTER != _newPosition) {
|
||||
this.outside = true;
|
||||
if (null == this.parent) {
|
||||
throw new NullPointerException(" a Stage requires a parent before any positioning! ");
|
||||
}
|
||||
|
||||
if (this.isCenterline()) {
|
||||
// Centerline stages must be set via AFTER-- regardless of what was requested:
|
||||
super.setRelativePosition(Position.AFTER);
|
||||
} else if (this.parent instanceof Stage) {
|
||||
if (Position.AFTER == _newPosition) {
|
||||
log.warn("Stages cannot be relative to other stages via AFTER! Ignoring.");
|
||||
super.setRelativePosition(Position.TOP);
|
||||
} else {
|
||||
super.setRelativePosition(_newPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getPositionValue() {
|
||||
mutex.verify();
|
||||
|
||||
if (null == this.stageRelativeTo) {
|
||||
return super.asPositionValue(this.relativePosition, this.getParent());
|
||||
} else {
|
||||
return getAxialOffset();
|
||||
}
|
||||
|
||||
/*
|
||||
* @deprecated remove when the file is fixed....
|
||||
*/
|
||||
public void setRelativeToStage(final int _relToStage) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
/**
|
||||
@ -242,46 +234,43 @@ public class Stage extends ComponentAssembly implements FlightConfigurableCompon
|
||||
* @return the stage number which this stage is positioned relative to
|
||||
*/
|
||||
public int getRelativeToStage() {
|
||||
if (null == this.stageRelativeTo) {
|
||||
if (null == this.parent) {
|
||||
return -1;
|
||||
} else if (this.parent instanceof Stage) {
|
||||
return this.parent.parent.getChildPosition(this.parent);
|
||||
} else if (this.isCenterline()) {
|
||||
if (0 < this.stageNumber) {
|
||||
return --this.stageNumber;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return this.getRocket().getChildPosition(this.stageRelativeTo);
|
||||
public static void resetStageCount() {
|
||||
Stage.stageCount = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* @param _relTo the stage number which this stage is positioned relative to
|
||||
*/
|
||||
public Stage setRelativeToStage(final int _relTo) {
|
||||
mutex.verify();
|
||||
if ((_relTo < 0) || (_relTo >= this.getRocket().getStageCount())) {
|
||||
log.error("attempt to position this stage relative to a non-existent stage number. Ignoring.");
|
||||
this.stageRelativeTo = null;
|
||||
} else if (_relTo == this.getRocket().getChildPosition(this)) {
|
||||
// self-referential: also an error
|
||||
this.stageRelativeTo = null;
|
||||
} else if (this.isCenterline()) {
|
||||
this.relativePosition = Position.AFTER;
|
||||
updatePrevAxialStage();
|
||||
} else {
|
||||
this.stageRelativeTo = (Stage) this.getRocket().getChild(_relTo);
|
||||
@Override
|
||||
public int getStageNumber() {
|
||||
return this.stageNumber;
|
||||
}
|
||||
|
||||
return this.stageRelativeTo;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public double getAxialOffset() {
|
||||
double returnValue;
|
||||
if (null == this.stageRelativeTo) {
|
||||
returnValue = super.asPositionValue(Position.TOP, this.getParent());
|
||||
} else if (this.isCenterline()) {
|
||||
returnValue = super.asPositionValue(Position.AFTER, this.stageRelativeTo);
|
||||
|
||||
if (this.isCenterline()) {
|
||||
if (Position.AFTER == this.relativePosition) {
|
||||
returnValue = super.getAxialOffset();
|
||||
} else if (Position.TOP == this.relativePosition) {
|
||||
this.relativePosition = Position.AFTER;
|
||||
returnValue = super.getAxialOffset();
|
||||
} else {
|
||||
returnValue = super.asPositionValue(this.relativePosition, this.stageRelativeTo);
|
||||
throw new BugException("found a Stage on centerline, but not positioned as AFTER. Please fix this! " + this.getName() + " is " + this.getRelativePosition().name());
|
||||
}
|
||||
} else {
|
||||
returnValue = super.asPositionValue(this.relativePosition);
|
||||
}
|
||||
|
||||
if (0.000001 > Math.abs(returnValue)) {
|
||||
@ -294,12 +283,10 @@ public class Stage extends ComponentAssembly implements FlightConfigurableCompon
|
||||
@Override
|
||||
public void setAxialOffset(final double _pos) {
|
||||
this.updateBounds();
|
||||
super.setAxialOffset(this.relativePosition, _pos, this.stageRelativeTo);
|
||||
super.setAxialOffset(this.relativePosition, _pos);
|
||||
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
|
||||
}
|
||||
|
||||
// TOOD: unify with 'generate instanceOffsets()'
|
||||
// what is the use of this again?
|
||||
@Override
|
||||
public Coordinate[] shiftCoordinates(Coordinate[] c) {
|
||||
checkState();
|
||||
@ -328,56 +315,74 @@ public class Stage extends ComponentAssembly implements FlightConfigurableCompon
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StringBuilder toDebugDetail() {
|
||||
StringBuilder buf = super.toDebugDetail();
|
||||
// if (-1 == this.getRelativeToStage()) {
|
||||
// System.err.println(" >>refStageName: " + null + "\n");
|
||||
// } else {
|
||||
// Stage refStage = (Stage) this.parent;
|
||||
// System.err.println(" >>refStageName: " + refStage.getName() + "\n");
|
||||
// System.err.println(" ..refCenterX: " + refStage.position.x + "\n");
|
||||
// System.err.println(" ..refLength: " + refStage.getLength() + "\n");
|
||||
// }
|
||||
return buf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBounds() {
|
||||
|
||||
// currently only updates the length
|
||||
this.length = 0;
|
||||
Iterator<RocketComponent> childIterator = this.getChildren().iterator();
|
||||
while (childIterator.hasNext()) {
|
||||
RocketComponent curChild = childIterator.next();
|
||||
if (curChild.isCenterline()) {
|
||||
this.length += curChild.getLength();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @Warning this will return the previous axial stage REGARDLESS of whether 'this' is in the centerline stack or not.
|
||||
* @return previous axial stage (defined as above, in the direction of launch)
|
||||
*/
|
||||
protected Stage updatePrevAxialStage() {
|
||||
if (null != this.getParent()) {
|
||||
Rocket rocket = this.getRocket();
|
||||
int thisStageNumber = rocket.getChildPosition(this);
|
||||
int curStageIndex = thisStageNumber - 1;
|
||||
while (curStageIndex >= 0) {
|
||||
Stage curStage = (Stage) rocket.getChild(curStageIndex);
|
||||
if (curStage.isCenterline()) {
|
||||
this.stageRelativeTo = curStage;
|
||||
return this.stageRelativeTo;
|
||||
}
|
||||
curStageIndex--;
|
||||
}
|
||||
}
|
||||
|
||||
this.stageRelativeTo = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void updateCenter() {
|
||||
if (null == this.stageRelativeTo) {
|
||||
this.updatePrevAxialStage();
|
||||
if (null == this.stageRelativeTo) {
|
||||
// this stage is actually the topmost Stage, instead of just out-of-date
|
||||
this.setAxialOffset(Position.ABSOLUTE, this.getLength() / 2, this.getRocket());
|
||||
@Override
|
||||
protected void update() {
|
||||
if (null == this.parent) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.updateBounds();
|
||||
if (this.parent instanceof Rocket) {
|
||||
int childNumber = this.parent.getChildPosition(this);
|
||||
if (0 == childNumber) {
|
||||
this.setAfter(null);
|
||||
} else {
|
||||
RocketComponent prevStage = this.parent.getChild(childNumber - 1);
|
||||
this.setAfter(prevStage);
|
||||
}
|
||||
} else if (this.parent instanceof Stage) {
|
||||
this.updateBounds();
|
||||
super.update();
|
||||
}
|
||||
|
||||
// general case:
|
||||
double offset = super.asPositionValue(this.relativePosition, this.stageRelativeTo);
|
||||
this.setAxialOffset(this.relativePosition, offset, this.stageRelativeTo);
|
||||
|
||||
this.updateChildSequence();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
protected void updateChildSequence() {
|
||||
Iterator<RocketComponent> childIterator = this.getChildren().iterator();
|
||||
RocketComponent prevComp = null;
|
||||
while (childIterator.hasNext()) {
|
||||
RocketComponent curChild = childIterator.next();
|
||||
if (curChild.isCenterline()) {
|
||||
curChild.previousComponent = prevComp;
|
||||
prevComp = curChild;
|
||||
} else {
|
||||
curChild.previousComponent = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package net.sf.openrocket.rocketcomponent;
|
||||
|
||||
//import junit.framework.TestCase;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent.Position;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
@ -12,7 +13,7 @@ import org.junit.Test;
|
||||
public class StageTest extends BaseTestCase {
|
||||
|
||||
// tolerance for compared double test results
|
||||
protected final double EPSILON = 0.001;
|
||||
protected final double EPSILON = 0.00001;
|
||||
|
||||
protected final Coordinate ZERO = new Coordinate(0., 0., 0.);
|
||||
|
||||
@ -23,8 +24,8 @@ public class StageTest extends BaseTestCase {
|
||||
public Rocket createTestRocket() {
|
||||
double tubeRadius = 1;
|
||||
// setup
|
||||
Rocket root = new Rocket();
|
||||
root.setName("Rocket");
|
||||
Rocket rocket = new Rocket();
|
||||
rocket.setName("Rocket");
|
||||
|
||||
Stage sustainer = new Stage();
|
||||
sustainer.setName("Sustainer stage");
|
||||
@ -34,76 +35,48 @@ public class StageTest extends BaseTestCase {
|
||||
RocketComponent sustainerBody = new BodyTube(3.0, tubeRadius, 0.01);
|
||||
sustainerBody.setName("Sustainer Body ");
|
||||
sustainer.addChild(sustainerBody);
|
||||
root.addChild(sustainer);
|
||||
rocket.addChild(sustainer);
|
||||
|
||||
Stage core = new Stage();
|
||||
core.setName("Core stage");
|
||||
BodyTube coreBody = new BodyTube(6.0, tubeRadius, 0.01);
|
||||
coreBody.setName("Core Body ");
|
||||
core.addChild(coreBody);
|
||||
root.addChild(core);
|
||||
|
||||
return root;
|
||||
rocket.addChild(core);
|
||||
BodyTube coreUpperBody = new BodyTube(1.8, tubeRadius, 0.01);
|
||||
coreUpperBody.setName("Core UpBody ");
|
||||
core.addChild(coreUpperBody);
|
||||
BodyTube coreLowerBody = new BodyTube(4.2, tubeRadius, 0.01);
|
||||
coreLowerBody.setName("Core LoBody ");
|
||||
core.addChild(coreLowerBody);
|
||||
FinSet coreFins = new TrapezoidFinSet(4, 4, 2, 2, 4);
|
||||
coreFins.setName("Core Fins");
|
||||
coreLowerBody.addChild(coreFins);
|
||||
return rocket;
|
||||
}
|
||||
|
||||
public Stage createBooster() {
|
||||
double tubeRadius = 0.8;
|
||||
|
||||
Stage booster = new Stage();
|
||||
booster.setName("Booster Stage A");
|
||||
booster.setName("Booster Stage");
|
||||
booster.setOutside(true);
|
||||
RocketComponent boosterNose = new NoseCone(Transition.Shape.CONICAL, 2.0, tubeRadius);
|
||||
boosterNose.setName("Booster A Nosecone");
|
||||
boosterNose.setName("Booster Nosecone");
|
||||
booster.addChild(boosterNose);
|
||||
RocketComponent boosterBody = new BodyTube(2.0, tubeRadius, 0.01);
|
||||
boosterBody.setName("Booster A Body ");
|
||||
boosterBody.setName("Booster Body ");
|
||||
booster.addChild(boosterBody);
|
||||
Transition boosterTail = new Transition();
|
||||
boosterTail.setName("Booster A Tail");
|
||||
boosterTail.setName("Booster Tail");
|
||||
boosterTail.setForeRadius(1.0);
|
||||
boosterTail.setAftRadius(0.5);
|
||||
boosterTail.setLength(1.0);
|
||||
booster.addChild(boosterTail);
|
||||
|
||||
booster.setInstanceCount(3);
|
||||
booster.setRadialOffset(1.8);
|
||||
|
||||
return booster;
|
||||
}
|
||||
|
||||
// // instantiate a rocket with realistic numbers, matching a file that exhibited errors
|
||||
// public Rocket createDeltaIIRocket() {
|
||||
//
|
||||
// // setup
|
||||
// Rocket root = new Rocket();
|
||||
// root.setName("Rocket");
|
||||
//
|
||||
// Stage payloadFairing = new Stage();
|
||||
// root.addChild(payloadFairing);
|
||||
// payloadFairing.setName("Payload Fairing");
|
||||
// NoseCone payloadNose = new NoseCone(Transition.Shape.POWER, 0.0535, 0.03);
|
||||
// payloadNose.setShapeParameter(0.55);
|
||||
// payloadNose.setName("Payload Nosecone");
|
||||
// payloadNose.setAftRadius(0.3);
|
||||
// payloadNose.setThickness(0.001);
|
||||
// payloadFairing.addChild(payloadNose);
|
||||
// BodyTube payloadBody = new BodyTube(0.0833, 0.03, 0.001);
|
||||
// payloadBody.setName("Payload Body ");
|
||||
// payloadFairing.addChild(payloadBody);
|
||||
// Transition payloadTransition = new Transition();
|
||||
// payloadTransition.setName("Payload Aft Transition");
|
||||
// payloadTransition.setForeRadius(0.03);
|
||||
// payloadTransition.setAftRadius(0.024);
|
||||
// payloadTransition.setLength(0.04);
|
||||
// payloadFairing.addChild(payloadTransition);
|
||||
//
|
||||
// Stage core = new Stage();
|
||||
// core.setName("Delta Core stage");
|
||||
// BodyTube coreBody = new BodyTube(0.0833, 0.3, 0.001);
|
||||
// coreBody.setName("Delta Core Body ");
|
||||
// core.addChild(coreBody);
|
||||
// root.addChild(core);
|
||||
//
|
||||
// return root;
|
||||
// }
|
||||
|
||||
/* From OpenRocket Technical Documentation
|
||||
*
|
||||
* 3.1.4 Coordinate systems
|
||||
@ -116,41 +89,45 @@ public class StageTest extends BaseTestCase {
|
||||
|
||||
@Test
|
||||
public void testSetRocketPositionFail() {
|
||||
RocketComponent root = createTestRocket();
|
||||
RocketComponent rocket = createTestRocket();
|
||||
Coordinate expectedPosition;
|
||||
Coordinate targetPosition;
|
||||
Coordinate resultPosition;
|
||||
|
||||
// case 1: the Root Rocket should be stationary
|
||||
// case 1: the rocket Rocket should be stationary
|
||||
expectedPosition = ZERO;
|
||||
targetPosition = new Coordinate(+4.0, 0.0, 0.0);
|
||||
root.setAxialOffset(targetPosition.x);
|
||||
resultPosition = root.getRelativePositionVector();
|
||||
assertThat(" Moved the rocket root itself-- this should not be enabled.", expectedPosition.x, equalTo(resultPosition.x));
|
||||
rocket.setAxialOffset(targetPosition.x);
|
||||
resultPosition = rocket.getRelativePositionVector();
|
||||
assertThat(" Moved the rocket rocket itself-- this should not be enabled.", expectedPosition.x, equalTo(resultPosition.x));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddTopStage() {
|
||||
RocketComponent root = createTestRocket();
|
||||
public void testAddSustainerStage() {
|
||||
RocketComponent rocket = createTestRocket();
|
||||
|
||||
// Sustainer Stage
|
||||
Stage sustainer = (Stage) root.getChild(0);
|
||||
Stage sustainer = (Stage) rocket.getChild(0);
|
||||
RocketComponent sustainerNose = sustainer.getChild(0);
|
||||
RocketComponent sustainerBody = sustainer.getChild(1);
|
||||
assertThat(" createTestRocket failed: is sustainer stage an ancestor of the sustainer stage? ", sustainer.isAncestor(sustainer), equalTo(false));
|
||||
assertThat(" createTestRocket failed: is sustainer stage an ancestor of the sustainer nose? ", sustainer.isAncestor(sustainerNose), equalTo(true));
|
||||
assertThat(" createTestRocket failed: is the root rocket an ancestor of the sustainer Nose? ", root.isAncestor(sustainerNose), equalTo(true));
|
||||
assertThat(" createTestRocket failed: is the rocket rocket an ancestor of the sustainer Nose? ", rocket.isAncestor(sustainerNose), equalTo(true));
|
||||
assertThat(" createTestRocket failed: is sustainer Body an ancestor of the sustainer Nose? ", sustainerBody.isAncestor(sustainerNose), equalTo(false));
|
||||
|
||||
int relToExpected = -1;
|
||||
int relToStage = sustainer.getRelativeToStage();
|
||||
assertThat(" createTestRocket failed: sustainer relative position: ", relToStage, equalTo(relToExpected));
|
||||
|
||||
double expectedSustainerLength = 5.0;
|
||||
assertThat(" createTestRocket failed: Sustainer size: ", sustainer.getLength(), equalTo(expectedSustainerLength));
|
||||
double expectedSustainerX = +2.5;
|
||||
double sustainerX;
|
||||
sustainerX = sustainer.getRelativePositionVector().x;
|
||||
assertThat(" createTestRocket failed: Relative position: ", sustainerX, equalTo(expectedSustainerX));
|
||||
assertThat(" createTestRocket failed: sustainer Relative position: ", sustainerX, equalTo(expectedSustainerX));
|
||||
sustainerX = sustainer.getRelativePositionVector().x;
|
||||
assertThat(" createTestRocket failed: Absolute position: ", sustainerX, equalTo(expectedSustainerX));
|
||||
assertThat(" createTestRocket failed: sustainer Absolute position: ", sustainerX, equalTo(expectedSustainerX));
|
||||
|
||||
double expectedSustainerNoseX = -1.5;
|
||||
double sustainerNosePosition = sustainerNose.getRelativePositionVector().x;
|
||||
@ -170,44 +147,67 @@ public class StageTest extends BaseTestCase {
|
||||
|
||||
// WARNING: this test will not pass unless 'testAddTopStage' is passing as well -- that function tests the dependencies...
|
||||
@Test
|
||||
public void testAddMiddleStage() {
|
||||
RocketComponent root = createTestRocket();
|
||||
public void testAddCoreStage() {
|
||||
// vvvv function under test vvvv ( which indirectly tests initialization code, and that the test setup creates the preconditions that we expect
|
||||
RocketComponent rocket = createTestRocket();
|
||||
// ^^^^ function under test ^^^^
|
||||
|
||||
// Core Stage
|
||||
Stage core = (Stage) root.getChild(1);
|
||||
Stage core = (Stage) rocket.getChild(1);
|
||||
double expectedCoreLength = 6.0;
|
||||
assertThat(" createTestRocket failed: Core size: ", core.getLength(), equalTo(expectedCoreLength));
|
||||
double expectedCoreX = +8.0;
|
||||
double coreX;
|
||||
core.setRelativePosition(Position.AFTER);
|
||||
|
||||
int relToExpected = 0;
|
||||
int relToStage = core.getRelativeToStage();
|
||||
assertThat(" createTestRocket failed: corerelative position: ", relToStage, equalTo(relToExpected));
|
||||
|
||||
coreX = core.getRelativePositionVector().x;
|
||||
assertThat(" createTestRocket failed: Relative position: ", coreX, equalTo(expectedCoreX));
|
||||
assertThat(" createTestRocket failed: core Relative position: ", coreX, equalTo(expectedCoreX));
|
||||
coreX = core.getAbsolutePositionVector().x;
|
||||
assertThat(" createTestRocket failed: Absolute position: ", coreX, equalTo(expectedCoreX));
|
||||
assertThat(" createTestRocket failed: core Absolute position: ", coreX, equalTo(expectedCoreX));
|
||||
|
||||
RocketComponent coreBody = core.getChild(0);
|
||||
double expectedCoreBodyX = 0.0;
|
||||
double coreBodyX = coreBody.getRelativePositionVector().x;
|
||||
assertThat(" createTestRocket failed: core body rel X: ", coreBodyX, equalTo(expectedCoreBodyX));
|
||||
expectedCoreBodyX = expectedCoreX;
|
||||
coreBodyX = coreBody.getAbsolutePositionVector().x;
|
||||
assertThat(" createTestRocket failed: core body abs X: ", coreBodyX, equalTo(expectedCoreBodyX));
|
||||
RocketComponent coreUpBody = core.getChild(0);
|
||||
double expectedX = -2.1;
|
||||
double resultantX = coreUpBody.getRelativePositionVector().x;
|
||||
|
||||
assertThat(" createTestRocket failed: core body rel X: ", resultantX, equalTo(expectedX));
|
||||
expectedX = 5.9;
|
||||
resultantX = coreUpBody.getAbsolutePositionVector().x;
|
||||
assertThat(" createTestRocket failed: core body abs X: ", resultantX, equalTo(expectedX));
|
||||
|
||||
RocketComponent coreLoBody = core.getChild(1);
|
||||
expectedX = 0.9;
|
||||
resultantX = coreLoBody.getRelativePositionVector().x;
|
||||
assertEquals(" createTestRocket failed: core body rel X: ", expectedX, resultantX, EPSILON);
|
||||
expectedX = 8.9;
|
||||
resultantX = coreLoBody.getAbsolutePositionVector().x;
|
||||
assertEquals(" createTestRocket failed: core body abs X: ", expectedX, resultantX, EPSILON);
|
||||
|
||||
RocketComponent coreFins = coreLoBody.getChild(0);
|
||||
expectedX = 0.1;
|
||||
resultantX = coreFins.getRelativePositionVector().x;
|
||||
assertEquals(" createTestRocket failed: core Fins rel X: ", expectedX, resultantX, EPSILON);
|
||||
expectedX = 9.0;
|
||||
resultantX = coreFins.getAbsolutePositionVector().x;
|
||||
assertEquals(" createTestRocket failed: core Fins abs X: ", expectedX, resultantX, EPSILON);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetStagePosition_topOfStack() {
|
||||
// setup
|
||||
RocketComponent root = createTestRocket();
|
||||
Stage sustainer = (Stage) root.getChild(0);
|
||||
RocketComponent rocket = createTestRocket();
|
||||
Stage sustainer = (Stage) rocket.getChild(0);
|
||||
Coordinate expectedPosition = new Coordinate(+2.5, 0., 0.); // i.e. half the tube length
|
||||
Coordinate targetPosition = new Coordinate(+4.0, 0., 0.);
|
||||
|
||||
|
||||
// without making the rocket 'external' and the Stage should be restricted to AFTER positioning.
|
||||
sustainer.setOutside(false);
|
||||
sustainer.setRelativePositionMethod(Position.ABSOLUTE);
|
||||
assertThat("Setting a stage's position method to anything other than AFTER flags it off-center", sustainer.getOutside(), equalTo(true));
|
||||
assertThat("Setting a centerline stage to anything other than AFTER is ignored.", sustainer.getOutside(), equalTo(false));
|
||||
assertThat("Setting a centerline stage to anything other than AFTER is ignored.", sustainer.getRelativePosition(), equalTo(Position.AFTER));
|
||||
|
||||
// vv function under test
|
||||
sustainer.setAxialOffset(targetPosition.x);
|
||||
@ -215,69 +215,89 @@ public class StageTest extends BaseTestCase {
|
||||
|
||||
Coordinate resultantRelativePosition = sustainer.getRelativePositionVector();
|
||||
assertThat(" 'setAxialPosition(double)' failed. Relative position: ", resultantRelativePosition.x, equalTo(expectedPosition.x));
|
||||
// for all stages, the absolute position should equal the relative, because the direct parent is the root component (i.e. the Rocket)
|
||||
// for all stages, the absolute position should equal the relative, because the direct parent is the rocket component (i.e. the Rocket)
|
||||
Coordinate resultantAbsolutePosition = sustainer.getAbsolutePositionVector();
|
||||
assertThat(" 'setAxialPosition(double)' failed. Absolute position: ", resultantAbsolutePosition.x, equalTo(expectedPosition.x));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindPrevAxialStage() {
|
||||
RocketComponent root = createTestRocket();
|
||||
Stage core = (Stage) root.getChild(1);
|
||||
Stage booster = createBooster();
|
||||
root.addChild(booster);
|
||||
public void testBoosterInitialization() {
|
||||
// setup
|
||||
RocketComponent rocket = createTestRocket();
|
||||
Stage core = (Stage) rocket.getChild(1);
|
||||
Stage boosterSet = createBooster();
|
||||
core.addChild(boosterSet);
|
||||
|
||||
Stage booster2 = new Stage();
|
||||
booster2.setOutside(true);
|
||||
booster2.setName("Booster Set 2");
|
||||
RocketComponent booster2Body = new BodyTube(2.0, 1.0, 0.01);
|
||||
booster2Body.setName("Booster Body 2");
|
||||
booster2.addChild(booster2Body);
|
||||
root.addChild(booster2);
|
||||
double targetOffset = 0;
|
||||
boosterSet.setAxialOffset(Position.BOTTOM, targetOffset);
|
||||
// vv function under test
|
||||
boosterSet.setInstanceCount(2);
|
||||
boosterSet.setRadialOffset(4.0);
|
||||
boosterSet.setAngularOffset(Math.PI / 2);
|
||||
// ^^ function under test
|
||||
String treeDump = rocket.toDebugTree();
|
||||
|
||||
Stage booster3 = new Stage();
|
||||
booster3.setOutside(true);
|
||||
booster3.setName("Booster Set 3");
|
||||
RocketComponent booster3Body = new BodyTube(4.0, 1.0, 0.01);
|
||||
booster3Body.setName("Booster Body 3");
|
||||
booster3.addChild(booster3Body);
|
||||
root.addChild(booster3);
|
||||
int expectedInstanceCount = 2;
|
||||
int instanceCount = boosterSet.getInstanceCount();
|
||||
assertThat(" 'setInstancecount(int)' failed: ", instanceCount, equalTo(expectedInstanceCount));
|
||||
|
||||
Stage tail = new Stage();
|
||||
tail.setName("Tail");
|
||||
RocketComponent tailBody = new BodyTube(4.0, 1.0, 0.01);
|
||||
tailBody.setName("TailBody");
|
||||
root.addChild(tail);
|
||||
tail.addChild(tailBody);
|
||||
double expectedAbsX = 8.5;
|
||||
Coordinate resultantCenter = boosterSet.getAbsolutePositionVector();
|
||||
assertEquals(treeDump + "\n>>'setAxialOffset()' failed: ", expectedAbsX, resultantCenter.x, EPSILON);
|
||||
|
||||
Stage prevAxialStage;
|
||||
prevAxialStage = booster3.updatePrevAxialStage();
|
||||
assertThat(" 'setAxialPosition(double)' failed. Absolute position: ", prevAxialStage, equalTo(core));
|
||||
|
||||
prevAxialStage = tail.updatePrevAxialStage();
|
||||
assertThat(" 'setAxialPosition(double)' failed. Absolute position: ", prevAxialStage, equalTo(core));
|
||||
double expectedRadialOffset = 4.0;
|
||||
double radialOffset = boosterSet.getRadialOffset();
|
||||
assertEquals(" 'setRadialOffset(double)' failed. offset: ", expectedRadialOffset, radialOffset, EPSILON);
|
||||
|
||||
double expectedAngularOffset = Math.PI / 2;
|
||||
double angularOffset = boosterSet.getAngularOffset();
|
||||
assertEquals(" 'setAngularOffset(double)' failed. offset: ", expectedAngularOffset, angularOffset, EPSILON);
|
||||
}
|
||||
|
||||
|
||||
// because even though this is an "outside" stage, it's relative to itself -- i.e. an error.
|
||||
// also an error with a well-defined failure result (i.e. just failover to AFTER placement as the first stage of a rocket.
|
||||
@Test
|
||||
public void testSetStagePosition_inStack() {
|
||||
public void testBoosterInstanceLocation_BOTTOM() {
|
||||
// setup
|
||||
RocketComponent root = createTestRocket();
|
||||
Stage sustainer = (Stage) root.getChild(0);
|
||||
Stage core = (Stage) root.getChild(1);
|
||||
Coordinate expectedSustainerPosition = new Coordinate(+2.5, 0., 0.); // i.e. half the tube length
|
||||
Coordinate expectedCorePosition = new Coordinate(+8.0, 0., 0.);
|
||||
Coordinate targetPosition = new Coordinate(+17.0, 0., 0.);
|
||||
RocketComponent rocket = createTestRocket();
|
||||
Stage core = (Stage) rocket.getChild(1);
|
||||
Stage boosterSet = createBooster();
|
||||
core.addChild(boosterSet);
|
||||
|
||||
sustainer.setAxialOffset(targetPosition.x);
|
||||
Coordinate sustainerPosition = sustainer.getRelativePositionVector();
|
||||
assertThat(" 'setAxialPosition(double)' failed. Relative position: ", sustainerPosition.x, equalTo(expectedSustainerPosition.x));
|
||||
double targetOffset = 0;
|
||||
boosterSet.setAxialOffset(Position.BOTTOM, targetOffset);
|
||||
int targetInstanceCount = 3;
|
||||
double targetRadialOffset = 1.8;
|
||||
// vv function under test
|
||||
boosterSet.setInstanceCount(targetInstanceCount);
|
||||
boosterSet.setRadialOffset(targetRadialOffset);
|
||||
// ^^ function under test
|
||||
String treeDump = rocket.toDebugTree();
|
||||
|
||||
core.setAxialOffset(targetPosition.x);
|
||||
Coordinate resultantCorePosition = core.getRelativePositionVector();
|
||||
assertThat(" 'setAxialPosition(double)' failed. Absolute position: ", resultantCorePosition.x, equalTo(expectedCorePosition.x));
|
||||
double expectedX = 8.5;
|
||||
double angle = Math.PI * 2 / targetInstanceCount;
|
||||
double radius = targetRadialOffset;
|
||||
|
||||
Coordinate componentAbsolutePosition = boosterSet.getAbsolutePositionVector();
|
||||
Coordinate[] instanceCoords = new Coordinate[] { componentAbsolutePosition };
|
||||
instanceCoords = boosterSet.shiftCoordinates(instanceCoords);
|
||||
|
||||
int inst = 0;
|
||||
Coordinate expectedPosition0 = new Coordinate(expectedX, radius * Math.cos(angle * inst), radius * Math.sin(angle * inst));
|
||||
Coordinate resultantPosition0 = instanceCoords[0];
|
||||
assertEquals(treeDump + "\n>> Failed to generate Parallel Stage instances correctly: ", expectedPosition0, resultantPosition0);
|
||||
|
||||
inst = 1;
|
||||
Coordinate expectedPosition1 = new Coordinate(expectedX, radius * Math.cos(angle * inst), radius * Math.sin(angle * inst));
|
||||
Coordinate resultantPosition1 = instanceCoords[1];
|
||||
assertEquals(treeDump + "\n>> Failed to generate Parallel Stage instances correctly: ", expectedPosition1, resultantPosition1);
|
||||
|
||||
inst = 2;
|
||||
Coordinate expectedPosition2 = new Coordinate(expectedX, radius * Math.cos(angle * inst), radius * Math.sin(angle * inst));
|
||||
Coordinate resultantPosition2 = instanceCoords[2];
|
||||
assertEquals(treeDump + "\n>> Failed to generate Parallel Stage instances correctly: ", expectedPosition2, resultantPosition2);
|
||||
|
||||
}
|
||||
|
||||
@ -286,31 +306,28 @@ public class StageTest extends BaseTestCase {
|
||||
@Test
|
||||
public void testSetStagePosition_outsideABSOLUTE() {
|
||||
// setup
|
||||
RocketComponent root = createTestRocket();
|
||||
Stage core = (Stage) root.getChild(1);
|
||||
RocketComponent rocket = createTestRocket();
|
||||
Stage core = (Stage) rocket.getChild(1);
|
||||
Stage booster = createBooster();
|
||||
root.addChild(booster);
|
||||
core.addChild(booster);
|
||||
|
||||
Coordinate targetPosition = new Coordinate(+17.0, 0., 0.);
|
||||
double expectedX = targetPosition.x;
|
||||
double targetX = +17.0;
|
||||
double expectedX = targetX - core.getAbsolutePositionVector().x;
|
||||
|
||||
// when 'external' the stage should be freely movable
|
||||
booster.setOutside(true);
|
||||
booster.setRelativePositionMethod(Position.ABSOLUTE);
|
||||
booster.setRelativeToStage(1);
|
||||
// when subStages should be freely movable
|
||||
// vv function under test
|
||||
booster.setAxialOffset(targetPosition.x);
|
||||
booster.setAxialOffset(Position.ABSOLUTE, targetX);
|
||||
// ^^ function under test
|
||||
|
||||
Coordinate resultantRelativePosition = booster.getRelativePositionVector();
|
||||
assertThat(" 'setAxialPosition(double)' failed. Relative position: ", resultantRelativePosition.x, equalTo(expectedX));
|
||||
double resultantPositionValue = booster.getPositionValue();
|
||||
assertThat(" 'setAxialPosition(double)' failed. PositionValue: ", resultantPositionValue, equalTo(expectedX));
|
||||
assertThat(" 'setAxialPosition(double)' failed. PositionValue: ", resultantPositionValue, equalTo(targetX));
|
||||
double resultantAxialPosition = booster.getAxialOffset();
|
||||
assertThat(" 'setAxialPosition(double)' failed. Relative position: ", resultantAxialPosition, equalTo(expectedX));
|
||||
// for all stages, the absolute position should equal the relative, because the direct parent is the root component (i.e. the Rocket)
|
||||
assertThat(" 'setAxialPosition(double)' failed. Relative position: ", resultantAxialPosition, equalTo(targetX));
|
||||
// for all stages, the absolute position should equal the relative, because the direct parent is the rocket component (i.e. the Rocket)
|
||||
Coordinate resultantAbsolutePosition = booster.getAbsolutePositionVector();
|
||||
assertThat(" 'setAxialPosition(double)' failed. Absolute position: ", resultantAbsolutePosition.x, equalTo(expectedX));
|
||||
assertThat(" 'setAxialPosition(double)' failed. Absolute position: ", resultantAbsolutePosition.x, equalTo(targetX));
|
||||
}
|
||||
|
||||
// WARNING:
|
||||
@ -319,17 +336,17 @@ public class StageTest extends BaseTestCase {
|
||||
@Test
|
||||
public void testSetStagePosition_outsideTopOfStack() {
|
||||
// setup
|
||||
RocketComponent root = createTestRocket();
|
||||
Stage sustainer = (Stage) root.getChild(0);
|
||||
RocketComponent rocket = createTestRocket();
|
||||
Stage sustainer = (Stage) rocket.getChild(0);
|
||||
Coordinate expectedPosition = new Coordinate(+2.5, 0., 0.);
|
||||
Coordinate targetPosition = new Coordinate(+4.0, 0., 0.);
|
||||
|
||||
// when 'external' the stage should be freely movable
|
||||
sustainer.setOutside(true);
|
||||
sustainer.setRelativePositionMethod(Position.TOP);
|
||||
sustainer.setRelativeToStage(0);
|
||||
|
||||
int expectedRelativeIndex = -1;
|
||||
assertThat(" 'setRelativeToStage(int)' failed. Relative stage index:", sustainer.getRelativeToStage(), equalTo(expectedRelativeIndex));
|
||||
int resultantRelativeIndex = sustainer.getRelativeToStage();
|
||||
assertThat(" 'setRelativeToStage(int)' failed. Relative stage index:", expectedRelativeIndex, equalTo(resultantRelativeIndex));
|
||||
|
||||
// vv function under test
|
||||
sustainer.setAxialOffset(targetPosition.x);
|
||||
@ -344,31 +361,31 @@ public class StageTest extends BaseTestCase {
|
||||
double expectedAxialPosition = 0;
|
||||
double resultantAxialPosition = sustainer.getAxialOffset();
|
||||
assertThat(" 'getAxialPosition()' failed. Relative position: ", resultantAxialPosition, equalTo(expectedAxialPosition));
|
||||
// for all stages, the absolute position should equal the relative, because the direct parent is the root component (i.e. the Rocket)
|
||||
// for all stages, the absolute position should equal the relative, because the direct parent is the rocket component (i.e. the Rocket)
|
||||
Coordinate resultantAbsolutePosition = sustainer.getAbsolutePositionVector();
|
||||
assertThat(" 'setAbsolutePositionVector()' failed. Absolute position: ", resultantAbsolutePosition.x, equalTo(expectedPosition.x));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetStagePosition_outsideTOP() {
|
||||
Rocket root = this.createTestRocket();
|
||||
Rocket rocket = this.createTestRocket();
|
||||
Stage core = (Stage) rocket.getChild(1);
|
||||
Stage booster = createBooster();
|
||||
root.addChild(booster);
|
||||
core.addChild(booster);
|
||||
|
||||
booster.setOutside(true);
|
||||
booster.setRelativePositionMethod(Position.TOP);
|
||||
booster.setRelativeToStage(1);
|
||||
// vv function under test
|
||||
double targetOffset = +2.0;
|
||||
booster.setAxialOffset(targetOffset);
|
||||
|
||||
// vv function under test
|
||||
booster.setAxialOffset(Position.TOP, targetOffset);
|
||||
// ^^ function under test
|
||||
|
||||
double expectedX = +9.5;
|
||||
double expectedAbsoluteX = +9.5;
|
||||
double expectedRelativeX = 1.5;
|
||||
Coordinate resultantRelativePosition = booster.getRelativePositionVector();
|
||||
assertThat(" 'setAxialPosition(double)' failed. Relative position: ", resultantRelativePosition.x, equalTo(expectedX));
|
||||
// for all stages, the absolute position should equal the relative, because the direct parent is the root component (i.e. the Rocket)
|
||||
assertThat(" 'setAxialPosition(double)' failed. Relative position: ", resultantRelativePosition.x, equalTo(expectedRelativeX));
|
||||
// for all stages, the absolute position should equal the relative, because the direct parent is the rocket component (i.e. the Rocket)
|
||||
Coordinate resultantAbsolutePosition = booster.getAbsolutePositionVector();
|
||||
assertThat(" 'setAxialPosition(double)' failed. Absolute position: ", resultantAbsolutePosition.x, equalTo(expectedX));
|
||||
assertThat(" 'setAxialPosition(double)' failed. Absolute position: ", resultantAbsolutePosition.x, equalTo(expectedAbsoluteX));
|
||||
|
||||
double resultantAxialOffset = booster.getAxialOffset();
|
||||
assertThat(" 'getAxialPosition()' failed. Relative position: ", resultantAxialOffset, equalTo(targetOffset));
|
||||
@ -380,25 +397,24 @@ public class StageTest extends BaseTestCase {
|
||||
@Test
|
||||
public void testSetStagePosition_outsideMIDDLE() {
|
||||
// setup
|
||||
RocketComponent root = createTestRocket();
|
||||
RocketComponent rocket = createTestRocket();
|
||||
Stage core = (Stage) rocket.getChild(1);
|
||||
Stage booster = createBooster();
|
||||
root.addChild(booster);
|
||||
core.addChild(booster);
|
||||
|
||||
// when 'external' the stage should be freely movable
|
||||
booster.setOutside(true);
|
||||
booster.setRelativePositionMethod(Position.MIDDLE);
|
||||
booster.setRelativeToStage(1);
|
||||
// vv function under test
|
||||
double targetOffset = +2.0;
|
||||
booster.setAxialOffset(targetOffset);
|
||||
booster.setAxialOffset(Position.MIDDLE, targetOffset);
|
||||
// ^^ function under test
|
||||
|
||||
double expectedX = +10.0;
|
||||
double expectedRelativeX = +2.0;
|
||||
double expectedAbsoluteX = +10.0;
|
||||
Coordinate resultantRelativePosition = booster.getRelativePositionVector();
|
||||
assertThat(" 'setAxialPosition(double)' failed. Relative position: ", resultantRelativePosition.x, equalTo(expectedX));
|
||||
// for all stages, the absolute position should equal the relative, because the direct parent is the root component (i.e. the Rocket)
|
||||
assertThat(" 'setAxialPosition(double)' failed. Relative position: ", resultantRelativePosition.x, equalTo(expectedRelativeX));
|
||||
// for all stages, the absolute position should equal the relative, because the direct parent is the rocket component (i.e. the Rocket)
|
||||
Coordinate resultantAbsolutePosition = booster.getAbsolutePositionVector();
|
||||
assertThat(" 'setAxialPosition(double)' failed. Absolute position: ", resultantAbsolutePosition.x, equalTo(expectedX));
|
||||
assertThat(" 'setAxialPosition(double)' failed. Absolute position: ", resultantAbsolutePosition.x, equalTo(expectedAbsoluteX));
|
||||
|
||||
|
||||
double resultantPositionValue = booster.getPositionValue();
|
||||
@ -411,26 +427,23 @@ public class StageTest extends BaseTestCase {
|
||||
@Test
|
||||
public void testSetStagePosition_outsideBOTTOM() {
|
||||
// setup
|
||||
RocketComponent root = createTestRocket();
|
||||
RocketComponent rocket = createTestRocket();
|
||||
Stage core = (Stage) rocket.getChild(1);
|
||||
Stage booster = createBooster();
|
||||
root.addChild(booster);
|
||||
core.addChild(booster);
|
||||
|
||||
|
||||
// when 'external' the stage should be freely movable
|
||||
booster.setOutside(true);
|
||||
booster.setRelativePositionMethod(Position.BOTTOM);
|
||||
booster.setRelativeToStage(1);
|
||||
// vv function under test
|
||||
double targetOffset = +4.0;
|
||||
booster.setAxialOffset(targetOffset);
|
||||
booster.setAxialOffset(Position.BOTTOM, targetOffset);
|
||||
// ^^ function under test
|
||||
|
||||
double expectedX = +12.5;
|
||||
double expectedRelativeX = +4.5;
|
||||
double expectedAbsoluteX = +12.5;
|
||||
Coordinate resultantRelativePosition = booster.getRelativePositionVector();
|
||||
assertThat(" 'setAxialPosition(double)' failed. Relative position: ", resultantRelativePosition.x, equalTo(expectedX));
|
||||
// for all stages, the absolute position should equal the relative, because the direct parent is the root component (i.e. the Rocket)
|
||||
assertThat(" 'setAxialPosition(double)' failed. Relative position: ", resultantRelativePosition.x, equalTo(expectedRelativeX));
|
||||
// for all stages, the absolute position should equal the relative, because the direct parent is the rocket component (i.e. the Rocket)
|
||||
Coordinate resultantAbsolutePosition = booster.getAbsolutePositionVector();
|
||||
assertThat(" 'setAxialPosition(double)' failed. Absolute position: ", resultantAbsolutePosition.x, equalTo(expectedX));
|
||||
assertThat(" 'setAxialPosition(double)' failed. Absolute position: ", resultantAbsolutePosition.x, equalTo(expectedAbsoluteX));
|
||||
|
||||
double resultantPositionValue = booster.getPositionValue();
|
||||
assertThat(" 'setPositionValue()' failed. Relative position: ", resultantPositionValue, equalTo(targetOffset));
|
||||
@ -442,186 +455,260 @@ public class StageTest extends BaseTestCase {
|
||||
@Test
|
||||
public void testAxial_setTOP_getABSOLUTE() {
|
||||
// setup
|
||||
RocketComponent root = createTestRocket();
|
||||
Stage core = (Stage) root.getChild(1);
|
||||
RocketComponent rocket = createTestRocket();
|
||||
Stage core = (Stage) rocket.getChild(1);
|
||||
Stage booster = createBooster();
|
||||
root.addChild(booster);
|
||||
core.addChild(booster);
|
||||
|
||||
double targetOffset = +4.50;
|
||||
booster.setOutside(true);
|
||||
booster.setRelativePositionMethod(Position.TOP);
|
||||
booster.setRelativeToStage(1);
|
||||
booster.setAxialOffset(targetOffset);
|
||||
booster.setAxialOffset(Position.TOP, targetOffset);
|
||||
|
||||
double expectedAxialOffset = +12.0;
|
||||
double expectedAxialOffset = +4.0;
|
||||
Coordinate resultantRelativePosition = booster.getRelativePositionVector();
|
||||
assertThat(" 'setAxialPosition(double)' failed. Relative position: ", resultantRelativePosition.x, equalTo(expectedAxialOffset));
|
||||
|
||||
Stage refStage = core;
|
||||
// vv function under test
|
||||
double resultantAxialPosition = booster.asPositionValue(Position.ABSOLUTE, refStage);
|
||||
double resultantAxialPosition = booster.asPositionValue(Position.ABSOLUTE);
|
||||
// ^^ function under test
|
||||
|
||||
assertThat(" 'setPositionValue()' failed. Relative position: ", resultantAxialPosition, equalTo(expectedAxialOffset));
|
||||
double expectedAbsoluteX = +12.0;
|
||||
assertThat(" 'setPositionValue()' failed. Relative position: ", resultantAxialPosition, equalTo(expectedAbsoluteX));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAxial_setTOP_getAFTER() {
|
||||
// setup
|
||||
RocketComponent root = createTestRocket();
|
||||
Stage core = (Stage) root.getChild(1);
|
||||
RocketComponent rocket = createTestRocket();
|
||||
Stage core = (Stage) rocket.getChild(1);
|
||||
Stage booster = createBooster();
|
||||
root.addChild(booster);
|
||||
core.addChild(booster);
|
||||
|
||||
double targetOffset = +4.50;
|
||||
booster.setOutside(true);
|
||||
booster.setRelativePositionMethod(Position.TOP);
|
||||
booster.setRelativeToStage(1);
|
||||
booster.setAxialOffset(targetOffset);
|
||||
booster.setAxialOffset(Position.TOP, targetOffset);
|
||||
|
||||
Coordinate expectedPosition = new Coordinate(+12.0, 0., 0.);
|
||||
Coordinate resultantRelativePosition = booster.getRelativePositionVector();
|
||||
assertThat(" 'setAxialPosition(double)' failed. Relative position: ", resultantRelativePosition.x, equalTo(expectedPosition.x));
|
||||
double expectedRelativeX = +4.0;
|
||||
double resultantX = booster.getRelativePositionVector().x;
|
||||
|
||||
assertThat(" 'setAxialPosition(double)' failed. Relative position: ", resultantX, equalTo(expectedRelativeX));
|
||||
|
||||
Stage refStage = core;
|
||||
double resultantAxialPosition;
|
||||
double expectedAxialPosition;
|
||||
// vv function under test
|
||||
resultantAxialPosition = booster.asPositionValue(Position.AFTER, refStage);
|
||||
// because this component is not initalized to
|
||||
resultantX = booster.asPositionValue(Position.AFTER);
|
||||
// ^^ function under test
|
||||
expectedAxialPosition = -1.5;
|
||||
assertThat(" 'setPositionValue()' failed. Relative position: ", resultantAxialPosition, equalTo(expectedAxialPosition));
|
||||
|
||||
double expectedAfterX = 4.5;
|
||||
assertEquals(" 'setPositionValue()' failed. Relative position: ", expectedAfterX, resultantX, EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAxial_setTOP_getMIDDLE() {
|
||||
// setup
|
||||
RocketComponent root = createTestRocket();
|
||||
Stage core = (Stage) root.getChild(1);
|
||||
RocketComponent rocket = createTestRocket();
|
||||
Stage core = (Stage) rocket.getChild(1);
|
||||
Stage booster = createBooster();
|
||||
root.addChild(booster);
|
||||
|
||||
core.addChild(booster);
|
||||
|
||||
double targetOffset = +4.50;
|
||||
booster.setOutside(true);
|
||||
booster.setRelativePositionMethod(Position.TOP);
|
||||
booster.setRelativeToStage(1);
|
||||
booster.setAxialOffset(targetOffset);
|
||||
booster.setAxialOffset(Position.TOP, targetOffset);
|
||||
|
||||
Coordinate expectedPosition = new Coordinate(+12.0, 0., 0.);
|
||||
Coordinate resultantRelativePosition = booster.getRelativePositionVector();
|
||||
assertThat(" 'setAxialPosition(double)' failed. Relative position: ", resultantRelativePosition.x, equalTo(expectedPosition.x));
|
||||
double expectedRelativeX = +4.0;
|
||||
double resultantX = booster.getRelativePositionVector().x;
|
||||
assertThat(" 'setAxialPosition(double)' failed. Relative position: ", resultantX, equalTo(expectedRelativeX));
|
||||
|
||||
Stage refStage = core;
|
||||
double resultantAxialPosition;
|
||||
double expectedAxialPosition = +4.0;
|
||||
|
||||
// vv function under test
|
||||
resultantAxialPosition = booster.asPositionValue(Position.MIDDLE, refStage);
|
||||
resultantAxialPosition = booster.asPositionValue(Position.MIDDLE);
|
||||
// ^^ function under test
|
||||
assertThat(" 'setPositionValue()' failed. Relative position: ", resultantAxialPosition, equalTo(expectedAxialPosition));
|
||||
|
||||
assertEquals(" 'setPositionValue()' failed. Relative position: ", expectedAxialPosition, resultantAxialPosition, EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAxial_setTOP_getBOTTOM() {
|
||||
// setup
|
||||
RocketComponent root = createTestRocket();
|
||||
Stage core = (Stage) root.getChild(1);
|
||||
RocketComponent rocket = createTestRocket();
|
||||
Stage core = (Stage) rocket.getChild(1);
|
||||
Stage booster = createBooster();
|
||||
root.addChild(booster);
|
||||
core.addChild(booster);
|
||||
|
||||
|
||||
double targetOffset = +4.50;
|
||||
booster.setOutside(true);
|
||||
booster.setRelativePositionMethod(Position.TOP);
|
||||
booster.setRelativeToStage(1);
|
||||
booster.setAxialOffset(targetOffset);
|
||||
booster.setAxialOffset(Position.TOP, targetOffset);
|
||||
|
||||
Coordinate expectedPosition = new Coordinate(+12.0, 0., 0.);
|
||||
Coordinate resultantRelativePosition = booster.getRelativePositionVector();
|
||||
assertThat(" 'setAxialPosition(double)' failed. Relative position: ", resultantRelativePosition.x, equalTo(expectedPosition.x));
|
||||
double expectedRelativeX = +4.0;
|
||||
double resultantX = booster.getRelativePositionVector().x;
|
||||
assertEquals(" 'setAxialPosition(double)' failed. Relative position: ", expectedRelativeX, resultantX, EPSILON);
|
||||
|
||||
Stage refStage = core;
|
||||
double resultantAxialPosition;
|
||||
double expectedAxialPosition;
|
||||
// vv function under test
|
||||
resultantAxialPosition = booster.asPositionValue(Position.BOTTOM, refStage);
|
||||
double resultantAxialOffset = booster.asPositionValue(Position.BOTTOM);
|
||||
// ^^ function under test
|
||||
expectedAxialPosition = +3.5;
|
||||
assertThat(" 'setPositionValue()' failed. Relative position: ", resultantAxialPosition, equalTo(expectedAxialPosition));
|
||||
double expectedAxialOffset = +3.5;
|
||||
assertEquals(" 'setPositionValue()' failed. Relative position: ", expectedAxialOffset, resultantAxialOffset, EPSILON);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testAxial_setBOTTOM_getTOP() {
|
||||
// setup
|
||||
RocketComponent root = createTestRocket();
|
||||
Stage core = (Stage) root.getChild(1);
|
||||
RocketComponent rocket = createTestRocket();
|
||||
Stage core = (Stage) rocket.getChild(1);
|
||||
Stage booster = createBooster();
|
||||
root.addChild(booster);
|
||||
|
||||
core.addChild(booster);
|
||||
|
||||
double targetOffset = +4.50;
|
||||
booster.setOutside(true);
|
||||
booster.setRelativePositionMethod(Position.BOTTOM);
|
||||
booster.setRelativeToStage(1);
|
||||
booster.setAxialOffset(targetOffset);
|
||||
booster.setAxialOffset(Position.BOTTOM, targetOffset);
|
||||
|
||||
Coordinate expectedPosition = new Coordinate(+13.0, 0., 0.);
|
||||
Coordinate resultantRelativePosition = booster.getRelativePositionVector();
|
||||
assertThat(" 'setAxialPosition(double)' failed. Relative position: ", resultantRelativePosition.x, equalTo(expectedPosition.x));
|
||||
|
||||
Stage refStage = core;
|
||||
double resultantAxialPosition;
|
||||
double expectedAxialPosition;
|
||||
double expectedRelativeX = +5.0;
|
||||
double resultantX = booster.getRelativePositionVector().x;
|
||||
assertEquals(" 'setAxialPosition(double)' failed. Relative position: ", expectedRelativeX, resultantX, EPSILON);
|
||||
|
||||
// vv function under test
|
||||
resultantAxialPosition = booster.asPositionValue(Position.TOP, refStage);
|
||||
double resultantAxialOffset = booster.asPositionValue(Position.TOP);
|
||||
// ^^ function under test
|
||||
expectedAxialPosition = 5.5;
|
||||
assertThat(" 'setPositionValue()' failed. Relative position: ", resultantAxialPosition, equalTo(expectedAxialPosition));
|
||||
double expectedAxialOffset = 5.5;
|
||||
assertEquals(" 'setPositionValue()' failed. Relative position: ", expectedAxialOffset, resultantAxialOffset, EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitializationOrder() {
|
||||
Rocket root = createTestRocket();
|
||||
Stage boosterA = createBooster();
|
||||
root.addChild(boosterA);
|
||||
Stage boosterB = createBooster();
|
||||
root.addChild(boosterB);
|
||||
public void testOutsideStageRepositionTOPAfterAdd() {
|
||||
final double boosterRadius = 0.8;
|
||||
final double targetOffset = +2.50;
|
||||
final Position targetMethod = Position.TOP;
|
||||
Rocket rocket = createTestRocket();
|
||||
Stage core = (Stage) rocket.getChild(1);
|
||||
|
||||
double targetOffset = +4.50;
|
||||
Stage booster = new Stage();
|
||||
booster.setName("Booster Stage");
|
||||
core.addChild(booster);
|
||||
booster.setAxialOffset(targetMethod, targetOffset);
|
||||
|
||||
// requirement: regardless of initialization order (which we cannot control)
|
||||
// two boosters with identical initialization commands should end up at the same place.
|
||||
// a booster should retain it's positioning method and offset while adding on children
|
||||
double expectedRelativeX = -0.5;
|
||||
double resultantOffset = booster.getRelativePositionVector().x;
|
||||
assertEquals(" init order error: Booster: initial relative X: ", expectedRelativeX, resultantOffset, EPSILON);
|
||||
double expectedAxialOffset = targetOffset;
|
||||
resultantOffset = booster.getAxialOffset();
|
||||
assertEquals(" init order error: Booster: initial axial offset: ", expectedAxialOffset, resultantOffset, EPSILON);
|
||||
|
||||
boosterA.setOutside(true);
|
||||
boosterA.setRelativePositionMethod(Position.BOTTOM);
|
||||
boosterA.setRelativeToStage(1);
|
||||
boosterA.setAxialOffset(targetOffset);
|
||||
// Body Component 2
|
||||
RocketComponent boosterBody = new BodyTube(4.0, boosterRadius, 0.01);
|
||||
boosterBody.setName("Booster Body ");
|
||||
booster.addChild(boosterBody);
|
||||
|
||||
boosterB.dumpDetail();
|
||||
boosterB.setRelativePositionMethod(Position.TOP);
|
||||
System.err.println(" B: setMeth: " + boosterB.getRelativePositionVector().x);
|
||||
boosterB.setRelativeToStage(1);
|
||||
System.err.println(" B: setRelTo: " + boosterB.getRelativePositionVector().x);
|
||||
boosterB.setAxialOffset(targetOffset);
|
||||
System.err.println(" B: setOffs: " + boosterB.getRelativePositionVector().x);
|
||||
boosterB.setRelativePositionMethod(Position.BOTTOM);
|
||||
System.err.println(" B: setMeth: " + boosterB.getRelativePositionVector().x);
|
||||
boosterB.setOutside(true);
|
||||
System.err.println(" B: setOutside:" + boosterB.getRelativePositionVector().x);
|
||||
expectedAxialOffset = targetOffset;
|
||||
resultantOffset = booster.getAxialOffset();
|
||||
assertEquals(" init order error: Booster: populated axial offset: ", expectedAxialOffset, resultantOffset, EPSILON);
|
||||
expectedRelativeX = 1.5;
|
||||
resultantOffset = booster.getRelativePositionVector().x;
|
||||
assertEquals(" init order error: Booster: populated relative X: ", expectedRelativeX, resultantOffset, EPSILON);
|
||||
expectedAxialOffset = targetOffset;
|
||||
|
||||
root.dumpTree(true, "");
|
||||
}
|
||||
|
||||
double offsetA = boosterA.getAxialOffset();
|
||||
double offsetB = boosterB.getAxialOffset();
|
||||
@Test
|
||||
public void testOutsideStageRepositionBOTTOMAfterAdd() {
|
||||
final double boosterRadius = 0.8;
|
||||
final double targetOffset = +2.50;
|
||||
final Position targetMethod = Position.BOTTOM;
|
||||
Rocket rocket = createTestRocket();
|
||||
Stage core = (Stage) rocket.getChild(1);
|
||||
|
||||
assertThat(" init order error: Booster A: resultant positions: ", offsetA, equalTo(targetOffset));
|
||||
assertThat(" init order error: Booster B: resultant positions: ", offsetB, equalTo(targetOffset));
|
||||
Stage booster = new Stage();
|
||||
booster.setName("Booster Stage");
|
||||
core.addChild(booster);
|
||||
booster.setAxialOffset(targetMethod, targetOffset);
|
||||
|
||||
// requirement: regardless of initialization order (which we cannot control)
|
||||
// a booster should retain it's positioning method and offset while adding on children
|
||||
double expectedRelativeX = 5.5;
|
||||
double resultantOffset = booster.getRelativePositionVector().x;
|
||||
assertEquals(" init order error: Booster: initial relative X: ", expectedRelativeX, resultantOffset, EPSILON);
|
||||
double expectedAxialOffset = targetOffset;
|
||||
resultantOffset = booster.getAxialOffset();
|
||||
assertEquals(" init order error: Booster: initial axial offset: ", expectedAxialOffset, resultantOffset, EPSILON);
|
||||
|
||||
// Body Component 2
|
||||
RocketComponent boosterBody = new BodyTube(4.0, boosterRadius, 0.01);
|
||||
boosterBody.setName("Booster Body ");
|
||||
booster.addChild(boosterBody);
|
||||
|
||||
expectedAxialOffset = targetOffset;
|
||||
resultantOffset = booster.getAxialOffset();
|
||||
assertEquals(" init order error: Booster: populated axial offset: ", expectedAxialOffset, resultantOffset, EPSILON);
|
||||
expectedRelativeX = 3.5;
|
||||
resultantOffset = booster.getRelativePositionVector().x;
|
||||
assertEquals(" init order error: Booster: populated relative X: ", expectedRelativeX, resultantOffset, EPSILON);
|
||||
expectedAxialOffset = targetOffset;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testStageInitializationMethodValueOrder() {
|
||||
Rocket rocket = createTestRocket();
|
||||
Stage core = (Stage) rocket.getChild(1);
|
||||
Stage boosterA = createBooster();
|
||||
boosterA.setName("Booster A Stage");
|
||||
core.addChild(boosterA);
|
||||
Stage boosterB = createBooster();
|
||||
boosterB.setName("Booster B Stage");
|
||||
core.addChild(boosterB);
|
||||
|
||||
double targetOffset = +4.50;
|
||||
double expectedOffset = +4.0;
|
||||
// requirement: regardless of initialization order (which we cannot control)
|
||||
// two boosters with identical initialization commands should end up at the same place.
|
||||
|
||||
boosterA.setAxialOffset(Position.TOP, targetOffset);
|
||||
|
||||
boosterB.setRelativePositionMethod(Position.TOP);
|
||||
boosterB.setAxialOffset(targetOffset);
|
||||
|
||||
double resultantOffsetA = boosterA.getRelativePositionVector().x;
|
||||
double resultantOffsetB = boosterB.getRelativePositionVector().x;
|
||||
|
||||
assertEquals(" init order error: Booster A: resultant positions: ", expectedOffset, resultantOffsetA, EPSILON);
|
||||
assertEquals(" init order error: Booster B: resultant positions: ", expectedOffset, resultantOffsetB, EPSILON);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testStageNumbering() {
|
||||
Rocket rocket = createTestRocket();
|
||||
Stage sustainer = (Stage) rocket.getChild(0);
|
||||
Stage core = (Stage) rocket.getChild(1);
|
||||
Stage boosterA = createBooster();
|
||||
boosterA.setName("Booster A Stage");
|
||||
core.addChild(boosterA);
|
||||
boosterA.setAxialOffset(Position.BOTTOM, 0.0);
|
||||
Stage boosterB = createBooster();
|
||||
boosterB.setName("Booster B Stage");
|
||||
core.addChild(boosterB);
|
||||
boosterB.setAxialOffset(Position.BOTTOM, 0);
|
||||
|
||||
|
||||
int expectedStageNumber = 0;
|
||||
int actualStageNumber = sustainer.getStageNumber();
|
||||
assertEquals(" init order error: sustainer: resultant positions: ", expectedStageNumber, actualStageNumber);
|
||||
|
||||
expectedStageNumber = 1;
|
||||
actualStageNumber = core.getStageNumber();
|
||||
assertEquals(" init order error: core: resultant positions: ", expectedStageNumber, actualStageNumber);
|
||||
|
||||
expectedStageNumber = 2;
|
||||
actualStageNumber = boosterA.getStageNumber();
|
||||
assertEquals(" init order error: Booster A: resultant positions: ", expectedStageNumber, actualStageNumber);
|
||||
|
||||
expectedStageNumber = 3;
|
||||
actualStageNumber = boosterB.getStageNumber();
|
||||
assertEquals(" init order error: Booster B: resultant positions: ", expectedStageNumber, actualStageNumber);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,130 +0,0 @@
|
||||
package net.sf.openrocket.gui.adaptors;
|
||||
|
||||
import java.util.EventObject;
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.swing.AbstractListModel;
|
||||
import javax.swing.ComboBoxModel;
|
||||
import javax.swing.event.ListDataListener;
|
||||
|
||||
import org.jfree.util.Log;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.rocketcomponent.Stage;
|
||||
import net.sf.openrocket.util.ArrayList;
|
||||
import net.sf.openrocket.util.ChangeSource;
|
||||
import net.sf.openrocket.util.Reflection;
|
||||
import net.sf.openrocket.util.StateChangeListener;
|
||||
|
||||
public class StageSelectModel extends AbstractListModel<Stage> implements ComboBoxModel<Stage>, StateChangeListener {
|
||||
private static final long serialVersionUID = 1311302134934033684L;
|
||||
private static final Logger log = LoggerFactory.getLogger(StageSelectModel.class);
|
||||
|
||||
// protected final String nullText;
|
||||
|
||||
protected Stage sourceStage = null;
|
||||
protected ArrayList<Stage> displayValues = new ArrayList<Stage>();
|
||||
protected Stage selectedStage = null;
|
||||
|
||||
//@SuppressWarnings("unchecked")
|
||||
public StageSelectModel( final Stage _stage) {
|
||||
this.sourceStage = _stage;
|
||||
// this.nullText = nullText;
|
||||
|
||||
populateDisplayValues();
|
||||
|
||||
stateChanged(null); // Update current value
|
||||
this.sourceStage.addChangeListener(this);
|
||||
}
|
||||
|
||||
private void populateDisplayValues(){
|
||||
Rocket rocket = this.sourceStage.getRocket();
|
||||
|
||||
this.displayValues.clear();
|
||||
Iterator<RocketComponent> stageIter = rocket.getChildren().iterator();
|
||||
while( stageIter.hasNext() ){
|
||||
RocketComponent curComp = stageIter.next();
|
||||
if( curComp instanceof Stage ){
|
||||
Stage curStage = (Stage)curComp;
|
||||
if( curStage.equals( this.sourceStage )){
|
||||
continue;
|
||||
}else{
|
||||
displayValues.add( curStage );
|
||||
}
|
||||
}else{
|
||||
throw new IllegalStateException("Rocket has a child which is something other than a Stage: "+curComp.getClass().getCanonicalName()+"(called: "+curComp.getName()+")");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
return this.displayValues.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stage getElementAt(int index) {
|
||||
return this.displayValues.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelectedItem(Object newItem) {
|
||||
if (newItem == null) {
|
||||
// Clear selection - huh?
|
||||
return;
|
||||
}
|
||||
|
||||
if (newItem instanceof String) {
|
||||
log.error("setStage to string? huh? (unexpected value type");
|
||||
return;
|
||||
}
|
||||
|
||||
if( newItem instanceof Stage ){
|
||||
Stage nextStage = (Stage) newItem;
|
||||
|
||||
if (nextStage.equals(this.selectedStage)){
|
||||
return; // i.e. no change
|
||||
}
|
||||
|
||||
this.selectedStage = nextStage;
|
||||
this.sourceStage.setRelativeToStage(nextStage.getStageNumber());
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stage getSelectedItem() {
|
||||
return this.selectedStage;
|
||||
//return "StageSelectModel["+this.selectedIndex+": "+this.displayValues.get(this.selectedIndex).getName()+"]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stateChanged(EventObject eo) {
|
||||
if( null == this.sourceStage){
|
||||
return;
|
||||
}
|
||||
Rocket rkt = sourceStage.getRocket();
|
||||
int sourceRelToIndex = this.sourceStage.getRelativeToStage();
|
||||
int selectedStageIndex = -1;
|
||||
if( null != this.selectedStage ){
|
||||
selectedStageIndex = this.selectedStage.getStageNumber();
|
||||
}
|
||||
if ( selectedStageIndex != sourceRelToIndex){
|
||||
this.selectedStage = (Stage)rkt.getChild(sourceRelToIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "StageSelectModel["+this.selectedStage.getName()+" ("+this.selectedStage.getStageNumber()+")]";
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -256,7 +256,7 @@ public abstract class FinSetConfig extends RocketComponentConfig {
|
||||
if (!rings.isEmpty()) {
|
||||
FinSet.TabRelativePosition temp = (FinSet.TabRelativePosition) em.getSelectedItem();
|
||||
em.setSelectedItem(FinSet.TabRelativePosition.FRONT);
|
||||
double len = computeFinTabLength(rings, component.asPositionValue(RocketComponent.Position.TOP, parent),
|
||||
double len = computeFinTabLength(rings, component.asPositionValue(RocketComponent.Position.TOP),
|
||||
component.getLength(), mts, parent);
|
||||
mtl.setValue(len);
|
||||
//Be nice to the user and set the tab relative position enum back the way they had it.
|
||||
@ -305,8 +305,8 @@ public abstract class FinSetConfig extends RocketComponentConfig {
|
||||
Collections.sort(rings, new Comparator<CenteringRing>() {
|
||||
@Override
|
||||
public int compare(CenteringRing centeringRing, CenteringRing centeringRing1) {
|
||||
return (int) (1000d * (centeringRing.asPositionValue(RocketComponent.Position.TOP, relativeTo) -
|
||||
centeringRing1.asPositionValue(RocketComponent.Position.TOP, relativeTo)));
|
||||
return (int) (1000d * (centeringRing.asPositionValue(RocketComponent.Position.TOP) -
|
||||
centeringRing1.asPositionValue(RocketComponent.Position.TOP)));
|
||||
}
|
||||
});
|
||||
|
||||
@ -315,7 +315,7 @@ public abstract class FinSetConfig extends RocketComponentConfig {
|
||||
//Handle centering rings that overlap or are adjacent by synthetically merging them into one virtual ring.
|
||||
if (!positionsFromTop.isEmpty() &&
|
||||
positionsFromTop.get(positionsFromTop.size() - 1).bottomSidePositionFromTop() >=
|
||||
centeringRing.asPositionValue(RocketComponent.Position.TOP, relativeTo)) {
|
||||
centeringRing.asPositionValue(RocketComponent.Position.TOP)) {
|
||||
SortableRing adjacent = positionsFromTop.get(positionsFromTop.size() - 1);
|
||||
adjacent.merge(centeringRing, relativeTo);
|
||||
} else {
|
||||
@ -440,7 +440,7 @@ public abstract class FinSetConfig extends RocketComponentConfig {
|
||||
*/
|
||||
SortableRing(CenteringRing r, RocketComponent relativeTo) {
|
||||
thickness = r.getLength();
|
||||
positionFromTop = r.asPositionValue(RocketComponent.Position.TOP, relativeTo);
|
||||
positionFromTop = r.asPositionValue(RocketComponent.Position.TOP);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -449,7 +449,7 @@ public abstract class FinSetConfig extends RocketComponentConfig {
|
||||
* @param adjacent the adjacent ring
|
||||
*/
|
||||
public void merge(CenteringRing adjacent, RocketComponent relativeTo) {
|
||||
double v = adjacent.asPositionValue(RocketComponent.Position.TOP, relativeTo);
|
||||
double v = adjacent.asPositionValue(RocketComponent.Position.TOP);
|
||||
if (positionFromTop < v) {
|
||||
thickness = (v + adjacent.getLength()) - positionFromTop;
|
||||
} else {
|
||||
|
@ -1,11 +1,6 @@
|
||||
package net.sf.openrocket.gui.configdialog;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.ComboBoxModel;
|
||||
import javax.swing.DefaultComboBoxModel;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JLabel;
|
||||
@ -13,9 +8,6 @@ import javax.swing.JPanel;
|
||||
import javax.swing.JSeparator;
|
||||
import javax.swing.JSpinner;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.document.OpenRocketDocument;
|
||||
import net.sf.openrocket.gui.SpinnerEditor;
|
||||
@ -23,8 +15,6 @@ import net.sf.openrocket.gui.adaptors.BooleanModel;
|
||||
import net.sf.openrocket.gui.adaptors.DoubleModel;
|
||||
import net.sf.openrocket.gui.adaptors.EnumModel;
|
||||
import net.sf.openrocket.gui.adaptors.IntegerModel;
|
||||
import net.sf.openrocket.gui.adaptors.StageSelectModel;
|
||||
import net.sf.openrocket.gui.components.BasicSlider;
|
||||
import net.sf.openrocket.gui.components.StyledLabel;
|
||||
import net.sf.openrocket.gui.components.UnitSelector;
|
||||
import net.sf.openrocket.gui.components.StyledLabel.Style;
|
||||
@ -35,7 +25,6 @@ import net.sf.openrocket.rocketcomponent.Stage;
|
||||
import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.unit.UnitGroup;
|
||||
import net.sf.openrocket.util.ChangeSource;
|
||||
|
||||
public class StageConfig extends RocketComponentConfig {
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
@ -60,13 +49,6 @@ public class StageConfig extends RocketComponentConfig {
|
||||
private JPanel parallelTab( final Stage stage ){
|
||||
JPanel motherPanel = new JPanel( new MigLayout("fill"));
|
||||
|
||||
// this stage is positioned relative to what stage?
|
||||
JLabel relativeStageLabel = new JLabel(trans.get("Stage.parallel.componentname"));
|
||||
motherPanel.add( relativeStageLabel);
|
||||
ComboBoxModel<Stage> relativeStageModel = new StageSelectModel( stage );
|
||||
JComboBox<Stage> relToCombo = new JComboBox<Stage>( relativeStageModel );
|
||||
motherPanel.add( relToCombo , "growx, wrap");
|
||||
|
||||
// enable parallel staging
|
||||
motherPanel.add(new JSeparator(SwingConstants.HORIZONTAL), "spanx 3, growx, wrap");
|
||||
BooleanModel parallelEnabledModel = new BooleanModel( component, "Outside");
|
||||
@ -146,6 +128,8 @@ public class StageConfig extends RocketComponentConfig {
|
||||
motherPanel.add(axialOffsetUnitSelector, "growx 1, wrap");
|
||||
parallelEnabledModel.addEnableComponent( axialOffsetUnitSelector , true);
|
||||
|
||||
System.err.println(stage.getRocket().toDebugTree());
|
||||
|
||||
return motherPanel;
|
||||
}
|
||||
|
||||
|
@ -86,8 +86,8 @@ public class CenteringRingStrategy extends AbstractPrintStrategy<Void> {
|
||||
* @return true if the two physically intersect, from which we infer that the centering ring supports the tube
|
||||
*/
|
||||
private boolean overlaps(CenteringRing one, InnerTube two) {
|
||||
final double crTopPosition = one.asPositionValue(RocketComponent.Position.ABSOLUTE, one.getParent());
|
||||
final double mmTopPosition = two.asPositionValue(RocketComponent.Position.ABSOLUTE, two.getParent());
|
||||
final double crTopPosition = one.asPositionValue(RocketComponent.Position.ABSOLUTE);
|
||||
final double mmTopPosition = two.asPositionValue(RocketComponent.Position.ABSOLUTE);
|
||||
final double crBottomPosition = one.getLength() + crTopPosition;
|
||||
final double mmBottomPosition = two.getLength() + mmTopPosition;
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.sf.openrocket.gui.rocketfigure;
|
||||
|
||||
import net.sf.openrocket.rocketcomponent.Stage;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
import net.sf.openrocket.util.Transformation;
|
||||
|
||||
@ -21,7 +22,6 @@ public class BodyTubeShapes extends RocketComponentShape {
|
||||
Coordinate[] instanceOffsets = new Coordinate[]{ transformation.transform( componentAbsoluteLocation )};
|
||||
instanceOffsets = component.shiftCoordinates(instanceOffsets);
|
||||
|
||||
// System.err.println(">> Starting component "+component.getName()+" at: "+(instanceOffsets[0].x - length/2));
|
||||
Shape[] s = new Shape[instanceOffsets.length];
|
||||
for (int i=0; i < instanceOffsets.length; i++) {
|
||||
s[i] = new Rectangle2D.Double((instanceOffsets[i].x-length/2)*S, //x - the X coordinate of the upper-left corner of the newly constructed Rectangle2D
|
||||
|
@ -22,7 +22,7 @@ public class ShockCordShapes extends RocketComponentShape {
|
||||
double radius = massObj.getRadius();
|
||||
double arc = Math.min(length, 2*radius) * 0.7;
|
||||
|
||||
Shape[] s = new Shape[0];
|
||||
Shape[] s = new Shape[1];
|
||||
Coordinate start = componentAbsoluteLocation;
|
||||
s[0] = new RoundRectangle2D.Double((start.x-radius)*S,(start.y-radius)*S,
|
||||
length*S,2*radius*S,arc*S,arc*S);
|
||||
@ -47,7 +47,7 @@ public class ShockCordShapes extends RocketComponentShape {
|
||||
|
||||
double or = tube.getRadius();
|
||||
|
||||
Shape[] s = new Shape[0];
|
||||
Shape[] s = new Shape[1];
|
||||
Coordinate start = componentAbsoluteLocation;
|
||||
s[0] = new Ellipse2D.Double((start.z-or)*S,(start.y-or)*S,2*or*S,2*or*S);
|
||||
|
||||
|
@ -22,7 +22,7 @@ public class StreamerShapes extends RocketComponentShape {
|
||||
double radius = massObj.getRadius();
|
||||
double arc = Math.min(length, 2*radius) * 0.7;
|
||||
|
||||
Shape[] s = new Shape[0];
|
||||
Shape[] s = new Shape[1];
|
||||
Coordinate center = componentAbsoluteLocation;
|
||||
s[0] = new RoundRectangle2D.Double((center.x-radius)*S,(center.y-radius)*S,
|
||||
length*S,2*radius*S,arc*S,arc*S);
|
||||
@ -45,7 +45,7 @@ public class StreamerShapes extends RocketComponentShape {
|
||||
net.sf.openrocket.rocketcomponent.MassObject tube = (net.sf.openrocket.rocketcomponent.MassObject)component;
|
||||
|
||||
double or = tube.getRadius();
|
||||
Shape[] s = new Shape[0];
|
||||
Shape[] s = new Shape[1];
|
||||
Coordinate center = componentAbsoluteLocation;
|
||||
s[0] = new Ellipse2D.Double((center.z-or)*S,(center.y-or)*S,2*or*S,2*or*S);
|
||||
|
||||
|
@ -23,9 +23,11 @@ import net.sf.openrocket.gui.figureelements.FigureElement;
|
||||
import net.sf.openrocket.gui.util.ColorConversion;
|
||||
import net.sf.openrocket.gui.util.SwingPreferences;
|
||||
import net.sf.openrocket.motor.Motor;
|
||||
import net.sf.openrocket.rocketcomponent.BodyTube;
|
||||
import net.sf.openrocket.rocketcomponent.Configuration;
|
||||
import net.sf.openrocket.rocketcomponent.FinSet;
|
||||
import net.sf.openrocket.rocketcomponent.MotorMount;
|
||||
import net.sf.openrocket.rocketcomponent.OutsideComponent;
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.rocketcomponent.Stage;
|
||||
@ -442,27 +444,50 @@ public class RocketFigure extends AbstractScaleFigure {
|
||||
// Coordinate componentRelativeLocation = comp.getRelativePositionVector();
|
||||
Coordinate componentAbsoluteLocation = parentOffset.add(comp.getRelativePositionVector());
|
||||
|
||||
//System.err.println(">> Drawing component "+comp.getName()+" at relloc: "+componentAbsoluteLocation);
|
||||
if( ( comp instanceof Rocket)||( comp instanceof Stage )){
|
||||
// these components don't have any shapes to generate / get
|
||||
// No-Op
|
||||
// generate shapes:
|
||||
if( comp instanceof Rocket){
|
||||
// no-op. no shapes
|
||||
}else if( comp instanceof Stage ){
|
||||
// no-op; no shapes here, either.
|
||||
}else{
|
||||
// if( comp instanceof FinSet ){
|
||||
// System.err.println(">> Drawing component "+comp.getName()+" at absloc: "+componentAbsoluteLocation);
|
||||
// System.err.println(" (parent was at: "+parentOffset);
|
||||
// }
|
||||
// get all shapes for this component, add to return list.
|
||||
RocketComponentShape[] childShapes = getThisShape( viewType, comp, componentAbsoluteLocation, viewTransform);
|
||||
|
||||
for ( RocketComponentShape curShape : childShapes ){
|
||||
allShapes.add( curShape );
|
||||
}
|
||||
}
|
||||
|
||||
// recurse to each child
|
||||
// recurse differently, depending on if this node has instances or not....
|
||||
if( comp.isCenterline() ){
|
||||
// recurse to each child with just the center
|
||||
for( RocketComponent child: comp.getChildren() ){
|
||||
getShapeTree( allShapes, child, componentAbsoluteLocation);
|
||||
}
|
||||
|
||||
}else{
|
||||
|
||||
// DEBUG -- for external stages....
|
||||
System.err.println(">> Drawing pStage: "+comp.getName()+" at absloc: "+componentAbsoluteLocation);
|
||||
Stage testStage = (Stage)comp;
|
||||
// System.err.println(">> Starting component "+component.getName()+" at: "+(instanceOffsets[0]));
|
||||
|
||||
// recurse to each child with each instance of this component
|
||||
OutsideComponent outer = (OutsideComponent)comp;
|
||||
// int instanceCount = outer.getInstanceCount();
|
||||
|
||||
// get the offsets for m instances
|
||||
Coordinate[] instanceOffsets = new Coordinate[]{ componentAbsoluteLocation };
|
||||
instanceOffsets = comp.shiftCoordinates( instanceOffsets);
|
||||
|
||||
// recurse to each child with each offset
|
||||
for( RocketComponent child: comp.getChildren() ){
|
||||
for( Coordinate curInstanceCoordinate : instanceOffsets){
|
||||
getShapeTree( allShapes, child, curInstanceCoordinate);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user