changing internal positioning back to top-top

This commit is contained in:
Daniel_M_Williams 2015-08-01 14:57:10 -04:00
parent 2ac17cd0d5
commit 6f039a992b
16 changed files with 242 additions and 265 deletions

View File

@ -200,7 +200,7 @@ public class BasicMassCalculator extends AbstractMassCalculator {
* @return the total mass of all motors * @return the total mass of all motors
*/ */
@Override @Override
public double getPropellantMass(Configuration configuration, MotorInstanceConfiguration motors){ public double getPropellantMass(Configuration configuration, MotorInstanceConfiguration motors) {
double mass = 0; double mass = 0;
// add up the masses of all motors in the rocket // add up the masses of all motors in the rocket
@ -239,7 +239,9 @@ public class BasicMassCalculator extends AbstractMassCalculator {
private void calculateStageCache(Configuration config) { private void calculateStageCache(Configuration config) {
if (cgCache == null) { if (cgCache == null) {
int stages = config.getRocket().getStageCount(); //int stages = config.getRocket().getStageCount();
// temporary fix . this undercounts the stages
int stages = config.getRocket().getChildCount();
cgCache = new Coordinate[stages]; cgCache = new Coordinate[stages];
longitudinalInertiaCache = new double[stages]; longitudinalInertiaCache = new double[stages];

View File

@ -311,9 +311,10 @@ public class BodyTube extends SymmetricComponent implements MotorMount, Coaxial
@Override @Override
public Collection<Coordinate> getComponentBounds() { public Collection<Coordinate> getComponentBounds() {
Collection<Coordinate> bounds = new ArrayList<Coordinate>(8); Collection<Coordinate> bounds = new ArrayList<Coordinate>(8);
Coordinate ref = this.getAbsolutePositionVector();
double r = getOuterRadius(); double r = getOuterRadius();
addBound(bounds, 0, r); addBound(bounds, ref.x, r);
addBound(bounds, length, r); addBound(bounds, ref.x + length, r);
return bounds; return bounds;
} }

View File

@ -128,7 +128,9 @@ public class Configuration implements Cloneable, ChangeSource, ComponentChangeLi
} }
public int[] getActiveStages() { public int[] getActiveStages() {
int stageCount = Stage.getStageCount(); // temporary hack fix
//int stageCount = Stage.getStageCount();
int stageCount = getRocket().getChildCount();
List<Integer> active = new ArrayList<Integer>(); List<Integer> active = new ArrayList<Integer>();
int[] ret; int[] ret;

View File

@ -621,10 +621,11 @@ public abstract class FinSet extends ExternalComponent {
@Override @Override
public Collection<Coordinate> getComponentBounds() { public Collection<Coordinate> getComponentBounds() {
List<Coordinate> bounds = new ArrayList<Coordinate>(); List<Coordinate> bounds = new ArrayList<Coordinate>();
double refx = this.getAbsolutePositionVector().x;
double r = getBodyRadius(); double r = getBodyRadius();
for (Coordinate point : getFinPoints()) { for (Coordinate point : getFinPoints()) {
addFinBound(bounds, point.x, point.y + r); addFinBound(bounds, refx + point.x, point.y + r);
} }
return bounds; return bounds;

View File

@ -81,11 +81,6 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
*/ */
protected 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. * List of child components of this component.
*/ */
@ -909,31 +904,25 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
return 0.0; return 0.0;
} }
double thisCenterX = this.position.x; double thisX = this.position.x;
double relativeLength = this.parent.length; double relativeLength = this.parent.length;
double result = Double.NaN; double result = Double.NaN;
switch (thePosition) { switch (thePosition) {
case AFTER: case AFTER:
if (null == this.previousComponent) { result = thisX - relativeLength;
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; break;
case ABSOLUTE: case ABSOLUTE:
result = this.getAbsolutePositionVector().x; result = this.getAbsolutePositionVector().x;
break; break;
case TOP: case TOP:
result = thisCenterX + (relativeLength - this.getLength()) / 2; result = thisX;
break; break;
case MIDDLE: case MIDDLE:
result = thisCenterX; result = thisX + (-relativeLength + this.getLength()) / 2;
break; break;
case BOTTOM: case BOTTOM:
result = thisCenterX + (this.length - relativeLength) / 2; result = thisX + (-relativeLength + this.getLength());
break; break;
default: default:
throw new BugException("Unknown position type: " + thePosition); throw new BugException("Unknown position type: " + thePosition);
@ -1008,20 +997,20 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
double newAxialPosition; double newAxialPosition;
double refLength; double refLength;
// DEBUG
if (null == referenceComponent) { if (null == referenceComponent) {
// if this is the first component in the stage, position from the top of the parent
if (null == this.parent) { if (null == this.parent) {
// Probably initialization order issue. Ignore a.t.t. // Probably initialization order issue. Ignore a.t.t.
return; return;
} else { } else {
refLength = this.parent.getLength(); // if this is ACTUALLY the first component in the stage, position from the top of the parent
newAxialPosition = (-refLength + this.length) / 2; newAxialPosition = 0;
} }
} else { } else {
refLength = referenceComponent.getLength(); refLength = referenceComponent.getLength();
double refRelX = referenceComponent.getRelativePositionVector().x; double refRelX = referenceComponent.getRelativePositionVector().x;
newAxialPosition = refRelX + (refLength + this.length) / 2; newAxialPosition = refRelX + refLength;
} }
//this.relativePosition = Position.AFTER; //this.relativePosition = Position.AFTER;
@ -1032,12 +1021,16 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
// if this is the root of a hierarchy, constrain the position to zero. // if this is the root of a hierarchy, constrain the position to zero.
if (null == this.parent) { if (null == this.parent) {
return; return;
} else if ((this.isCenterline()) && (this instanceof Stage)) {
// enforce AFTER
positionMethod = Position.AFTER;
} }
checkState(); checkState();
this.relativePosition = positionMethod; this.relativePosition = positionMethod;
this.offset = newOffset; this.offset = newOffset;
double newAxialPosition = Double.NaN; double newAxialPosition = Double.NaN;
double refLength = this.parent.getLength(); double refLength = this.parent.getLength();
@ -1046,16 +1039,17 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
newAxialPosition = newOffset - this.parent.position.x; newAxialPosition = newOffset - this.parent.position.x;
break; break;
case AFTER: case AFTER:
this.setAfter(this.previousComponent); // no-op
// this.setAfter(this.previousComponent);
return; return;
case TOP: case TOP:
newAxialPosition = (-refLength + this.length) / 2 + newOffset;
break;
case MIDDLE:
newAxialPosition = newOffset; newAxialPosition = newOffset;
break; break;
case MIDDLE:
newAxialPosition = (refLength - this.length) / 2 + newOffset;
break;
case BOTTOM: case BOTTOM:
newAxialPosition = (+refLength - this.length) / 2 + newOffset; newAxialPosition = (refLength - this.length) + newOffset;
break; break;
default: default:
throw new BugException("Unknown position type: " + positionMethod); throw new BugException("Unknown position type: " + positionMethod);
@ -2032,14 +2026,14 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
buf.append(" offset: " + this.offset + " via: " + this.relativePosition.name() + " => " + this.getAxialOffset() + "\n"); buf.append(" offset: " + this.offset + " via: " + this.relativePosition.name() + " => " + this.getAxialOffset() + "\n");
buf.append(" thisCenterX: " + this.position.x + "\n"); buf.append(" thisCenterX: " + this.position.x + "\n");
buf.append(" this length: " + this.length + "\n"); buf.append(" this length: " + this.length + "\n");
if (null == this.previousComponent) { // if (null == this.previousComponent) {
buf.append(" ..prevComponent: " + null + "\n"); // buf.append(" ..prevComponent: " + null + "\n");
} else { // } else {
RocketComponent refComp = this.previousComponent; // RocketComponent refComp = this.previousComponent;
buf.append(" >>prevCompName: " + refComp.getName() + "\n"); // buf.append(" >>prevCompName: " + refComp.getName() + "\n");
buf.append(" ..prevCenterX: " + refComp.position.x + "\n"); // buf.append(" ..prevCenterX: " + refComp.position.x + "\n");
buf.append(" ..prevLength: " + refComp.getLength() + "\n"); // buf.append(" ..prevLength: " + refComp.getLength() + "\n");
} // }
return buf; return buf;
} }
@ -2053,8 +2047,10 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
} }
public void toDebugTreeNode(final StringBuilder buffer, final String prefix) { 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(), buffer.append(String.format("%s %-24s %5.3f %24f %24f\n", prefix, this.getName(), this.getLength(),
this.getRelativePositionVector(), this.getAbsolutePositionVector())); this.getRelativePositionVector().x, this.getAbsolutePositionVector().x));
// 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) { public void dumpTreeHelper(StringBuilder buffer, final String prefix) {

View File

@ -256,17 +256,11 @@ public class Stage extends ComponentAssembly implements FlightConfigurableCompon
@Override @Override
public double getAxialOffset() { public double getAxialOffset() {
double returnValue; double returnValue = Double.NaN;
if (this.isCenterline()) { if ((this.isCenterline() && (Position.AFTER != this.relativePosition))) {
if (Position.AFTER == this.relativePosition) { // remember the implicit (this instanceof Stage)
returnValue = super.getAxialOffset(); throw new BugException("found a Stage on centerline, but not positioned as AFTER. Please fix this! " + this.getName() + " is " + this.getRelativePosition().name());
} else if (Position.TOP == this.relativePosition) {
this.relativePosition = Position.AFTER;
returnValue = super.getAxialOffset();
} else {
throw new BugException("found a Stage on centerline, but not positioned as AFTER. Please fix this! " + this.getName() + " is " + this.getRelativePosition().name());
}
} else { } else {
returnValue = super.asPositionValue(this.relativePosition); returnValue = super.asPositionValue(this.relativePosition);
} }
@ -374,19 +368,21 @@ public class Stage extends ComponentAssembly implements FlightConfigurableCompon
this.updateBounds(); this.updateBounds();
if (this.parent instanceof Rocket) { if (this.parent instanceof Rocket) {
// stages which are directly children of the rocket are inline, and positioned
int childNumber = this.parent.getChildPosition(this); int childNumber = this.parent.getChildPosition(this);
if (0 == childNumber) { if (0 == childNumber) {
this.setAfter(null); this.setAfter(this.parent);
} else { } else {
RocketComponent prevStage = this.parent.getChild(childNumber - 1); RocketComponent prevStage = this.parent.getChild(childNumber - 1);
this.setAfter(prevStage); this.setAfter(prevStage);
} }
} else if (this.parent instanceof Stage) { } else if (this.parent instanceof Stage) {
this.updateBounds(); this.updateBounds();
// because if parent is instanceof Stage, that means 'this' is positioned externally
super.update(); super.update();
} }
// updates the internal 'previousComponent' field.
this.updateChildSequence(); this.updateChildSequence();
return; return;
@ -398,10 +394,11 @@ public class Stage extends ComponentAssembly implements FlightConfigurableCompon
while (childIterator.hasNext()) { while (childIterator.hasNext()) {
RocketComponent curChild = childIterator.next(); RocketComponent curChild = childIterator.next();
if (curChild.isCenterline()) { if (curChild.isCenterline()) {
curChild.previousComponent = prevComp; //curChild.previousComponent = prevComp;
curChild.setAfter(prevComp);
prevComp = curChild; prevComp = curChild;
} else { // } else {
curChild.previousComponent = null; // curChild.previousComponent = null;
} }
} }
} }

View File

@ -116,32 +116,34 @@ public class StageTest extends BaseTestCase {
assertThat(" createTestRocket failed: is the rocket rocket an ancestor of the sustainer Nose? ", rocket.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)); assertThat(" createTestRocket failed: is sustainer Body an ancestor of the sustainer Nose? ", sustainerBody.isAncestor(sustainerNose), equalTo(false));
String rocketTree = rocket.toDebugTree();
int relToExpected = -1; int relToExpected = -1;
int relToStage = sustainer.getRelativeToStage(); int relToStage = sustainer.getRelativeToStage();
assertThat(" createTestRocket failed: sustainer relative position: ", relToStage, equalTo(relToExpected)); assertThat(" createTestRocket failed: sustainer relative position: ", relToStage, equalTo(relToExpected));
double expectedSustainerLength = 5.0; double expectedSustainerLength = 5.0;
assertThat(" createTestRocket failed: Sustainer size: ", sustainer.getLength(), equalTo(expectedSustainerLength)); assertThat(" createTestRocket failed: Sustainer size: ", sustainer.getLength(), equalTo(expectedSustainerLength));
double expectedSustainerX = +2.5; double expectedSustainerX = 0;
double sustainerX; double sustainerX;
sustainerX = sustainer.getRelativePositionVector().x; sustainerX = sustainer.getRelativePositionVector().x;
assertThat(" createTestRocket failed: sustainer Relative position: ", sustainerX, equalTo(expectedSustainerX)); assertThat(" createTestRocket failed:\n" + rocketTree + " sustainer Relative position: ", sustainerX, equalTo(expectedSustainerX));
sustainerX = sustainer.getRelativePositionVector().x; sustainerX = sustainer.getAbsolutePositionVector().x;
assertThat(" createTestRocket failed: sustainer Absolute position: ", sustainerX, equalTo(expectedSustainerX)); assertThat(" createTestRocket failed:\n" + rocketTree + " sustainer Absolute position: ", sustainerX, equalTo(expectedSustainerX));
double expectedSustainerNoseX = -1.5; double expectedSustainerNoseX = 0;
double sustainerNosePosition = sustainerNose.getRelativePositionVector().x; double sustainerNosePosition = sustainerNose.getRelativePositionVector().x;
assertThat(" createTestRocket failed: sustainer Nose X position: ", sustainerNosePosition, equalTo(expectedSustainerNoseX)); assertThat(" createTestRocket failed:\n" + rocketTree + " sustainer Nose X position: ", sustainerNosePosition, equalTo(expectedSustainerNoseX));
expectedSustainerNoseX = +1; expectedSustainerNoseX = 0;
sustainerNosePosition = sustainerNose.getAbsolutePositionVector().x; sustainerNosePosition = sustainerNose.getAbsolutePositionVector().x;
assertThat(" createTestRocket failed: sustainer Nose X position: ", sustainerNosePosition, equalTo(expectedSustainerNoseX)); assertThat(" createTestRocket failed:\n" + rocketTree + " sustainer Nose X position: ", sustainerNosePosition, equalTo(expectedSustainerNoseX));
double expectedSustainerBodyX = +1; double expectedSustainerBodyX = 2;
double sustainerBodyX = sustainerBody.getRelativePositionVector().x; double sustainerBodyX = sustainerBody.getRelativePositionVector().x;
assertThat(" createTestRocket failed: sustainer body rel X position: ", sustainerBodyX, equalTo(expectedSustainerBodyX)); assertThat(" createTestRocket failed:\n" + rocketTree + " sustainer body rel X position: ", sustainerBodyX, equalTo(expectedSustainerBodyX));
expectedSustainerBodyX = +3.5; expectedSustainerBodyX = 2;
sustainerBodyX = sustainerBody.getAbsolutePositionVector().x; sustainerBodyX = sustainerBody.getAbsolutePositionVector().x;
assertThat(" createTestRocket failed: sustainer body abs X position: ", sustainerBodyX, equalTo(expectedSustainerBodyX)); assertThat(" createTestRocket failed:\n" + rocketTree + " sustainer body abs X position: ", sustainerBodyX, equalTo(expectedSustainerBodyX));
} }
@ -151,47 +153,51 @@ public class StageTest extends BaseTestCase {
// vvvv function under test vvvv ( which indirectly tests initialization code, and that the test setup creates the preconditions that we expect // vvvv function under test vvvv ( which indirectly tests initialization code, and that the test setup creates the preconditions that we expect
RocketComponent rocket = createTestRocket(); RocketComponent rocket = createTestRocket();
// ^^^^ function under test ^^^^ // ^^^^ function under test ^^^^
String rocketTree = rocket.toDebugTree();
// Core Stage // Core Stage
Stage core = (Stage) rocket.getChild(1); Stage core = (Stage) rocket.getChild(1);
double expectedCoreLength = 6.0; double expectedCoreLength = 6.0;
assertThat(" createTestRocket failed: Core size: ", core.getLength(), equalTo(expectedCoreLength)); assertThat(" createTestRocket failed: Core size: ", core.getLength(), equalTo(expectedCoreLength));
double expectedCoreX = +8.0; double expectedCoreX = 5;
double coreX; double coreX;
int relToExpected = 0; int relToExpected = 0;
int relToStage = core.getRelativeToStage(); int relToStage = core.getRelativeToStage();
assertThat(" createTestRocket failed: corerelative position: ", relToStage, equalTo(relToExpected)); assertThat(" createTestRocket failed:\n" + rocketTree + " core relative position: ", relToStage, equalTo(relToExpected));
coreX = core.getRelativePositionVector().x; coreX = core.getRelativePositionVector().x;
assertThat(" createTestRocket failed: core Relative position: ", coreX, equalTo(expectedCoreX)); assertThat(" createTestRocket failed:\n" + rocketTree + " core Relative position: ", coreX, equalTo(expectedCoreX));
coreX = core.getAbsolutePositionVector().x; coreX = core.getAbsolutePositionVector().x;
assertThat(" createTestRocket failed: core Absolute position: ", coreX, equalTo(expectedCoreX)); assertThat(" createTestRocket failed:\n" + rocketTree + " core Absolute position: ", coreX, equalTo(expectedCoreX));
RocketComponent coreUpBody = core.getChild(0); RocketComponent coreUpperBody = core.getChild(0);
double expectedX = -2.1; double expectedX = 0;
double resultantX = coreUpBody.getRelativePositionVector().x; double resultantX = coreUpperBody.getRelativePositionVector().x;
assertThat(" createTestRocket failed:\n" + rocketTree + " core body rel X: ", resultantX, equalTo(expectedX));
expectedX = expectedCoreX;
resultantX = coreUpperBody.getAbsolutePositionVector().x;
assertThat(" createTestRocket failed:\n" + rocketTree + " core body abs X: ", resultantX, equalTo(expectedX));
assertThat(" createTestRocket failed: core body rel X: ", resultantX, equalTo(expectedX)); RocketComponent coreLowerBody = core.getChild(1);
expectedX = 5.9; expectedX = coreUpperBody.getLength();
resultantX = coreUpBody.getAbsolutePositionVector().x; resultantX = coreLowerBody.getRelativePositionVector().x;
assertThat(" createTestRocket failed: core body abs X: ", resultantX, equalTo(expectedX)); assertEquals(" createTestRocket failed:\n" + rocketTree + " core body rel X: ", expectedX, resultantX, EPSILON);
expectedX = expectedCoreX + coreUpperBody.getLength();
resultantX = coreLowerBody.getAbsolutePositionVector().x;
assertEquals(" createTestRocket failed:\n" + rocketTree + " core body abs X: ", expectedX, resultantX, EPSILON);
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); RocketComponent coreFins = coreLowerBody.getChild(0);
expectedX = 0.1; // default is offset=0, method=0
expectedX = 0.2;
resultantX = coreFins.getRelativePositionVector().x; resultantX = coreFins.getRelativePositionVector().x;
assertEquals(" createTestRocket failed: core Fins rel X: ", expectedX, resultantX, EPSILON); assertEquals(" createTestRocket failed:\n" + rocketTree + " core Fins rel X: ", expectedX, resultantX, EPSILON);
expectedX = 9.0; // 5 + 1.8 + 4.2 = 11
// 11 - 4 = 7;
expectedX = 7.0;
resultantX = coreFins.getAbsolutePositionVector().x; resultantX = coreFins.getAbsolutePositionVector().x;
assertEquals(" createTestRocket failed: core Fins abs X: ", expectedX, resultantX, EPSILON); assertEquals(" createTestRocket failed:\n" + rocketTree + " core Fins abs X: ", expectedX, resultantX, EPSILON);
} }
@ -200,7 +206,7 @@ public class StageTest extends BaseTestCase {
// setup // setup
RocketComponent rocket = createTestRocket(); RocketComponent rocket = createTestRocket();
Stage sustainer = (Stage) rocket.getChild(0); Stage sustainer = (Stage) rocket.getChild(0);
Coordinate expectedPosition = new Coordinate(+2.5, 0., 0.); // i.e. half the tube length Coordinate expectedPosition = new Coordinate(0, 0., 0.); // i.e. half the tube length
Coordinate targetPosition = new Coordinate(+4.0, 0., 0.); Coordinate targetPosition = new Coordinate(+4.0, 0., 0.);
@ -212,12 +218,13 @@ public class StageTest extends BaseTestCase {
// vv function under test // vv function under test
sustainer.setAxialOffset(targetPosition.x); sustainer.setAxialOffset(targetPosition.x);
// ^^ function under test // ^^ function under test
String rocketTree = rocket.toDebugTree();
Coordinate resultantRelativePosition = sustainer.getRelativePositionVector(); Coordinate resultantRelativePosition = sustainer.getRelativePositionVector();
assertThat(" 'setAxialPosition(double)' failed. Relative position: ", resultantRelativePosition.x, equalTo(expectedPosition.x)); assertThat(" 'setAxialPosition(double)' failed:\n" + rocketTree + " Relative position: ", resultantRelativePosition.x, equalTo(expectedPosition.x));
// for all stages, the absolute position should equal the relative, because the direct parent is the rocket 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(); Coordinate resultantAbsolutePosition = sustainer.getAbsolutePositionVector();
assertThat(" 'setAxialPosition(double)' failed. Absolute position: ", resultantAbsolutePosition.x, equalTo(expectedPosition.x)); assertThat(" 'setAxialPosition(double)' failed:\n" + rocketTree + " Absolute position: ", resultantAbsolutePosition.x, equalTo(expectedPosition.x));
} }
@ -242,20 +249,19 @@ public class StageTest extends BaseTestCase {
int instanceCount = boosterSet.getInstanceCount(); int instanceCount = boosterSet.getInstanceCount();
assertThat(" 'setInstancecount(int)' failed: ", instanceCount, equalTo(expectedInstanceCount)); assertThat(" 'setInstancecount(int)' failed: ", instanceCount, equalTo(expectedInstanceCount));
double expectedAbsX = 8.5; double expectedAbsX = 6.0;
Coordinate resultantCenter = boosterSet.getAbsolutePositionVector(); Coordinate resultantCenter = boosterSet.getAbsolutePositionVector();
assertEquals(treeDump + "\n>>'setAxialOffset()' failed: ", expectedAbsX, resultantCenter.x, EPSILON); assertEquals(treeDump + "\n>>'setAxialOffset()' failed:\n" + treeDump + " absolute position", expectedAbsX, resultantCenter.x, EPSILON);
double expectedRadialOffset = 4.0; double expectedRadialOffset = 4.0;
double radialOffset = boosterSet.getRadialOffset(); double radialOffset = boosterSet.getRadialOffset();
assertEquals(" 'setRadialOffset(double)' failed. offset: ", expectedRadialOffset, radialOffset, EPSILON); assertEquals(" 'setRadialOffset(double)' failed: \n" + treeDump + " radial offset: ", expectedRadialOffset, radialOffset, EPSILON);
double expectedAngularOffset = Math.PI / 2; double expectedAngularOffset = Math.PI / 2;
double angularOffset = boosterSet.getAngularOffset(); double angularOffset = boosterSet.getAngularOffset();
assertEquals(" 'setAngularOffset(double)' failed. offset: ", expectedAngularOffset, angularOffset, EPSILON); assertEquals(" 'setAngularOffset(double)' failed:\n" + treeDump + " angular offset: ", expectedAngularOffset, angularOffset, EPSILON);
} }
// because even though this is an "outside" stage, it's relative to itself -- i.e. an error. // 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. // also an error with a well-defined failure result (i.e. just failover to AFTER placement as the first stage of a rocket.
@Test @Test
@ -276,7 +282,7 @@ public class StageTest extends BaseTestCase {
// ^^ function under test // ^^ function under test
String treeDump = rocket.toDebugTree(); String treeDump = rocket.toDebugTree();
double expectedX = 8.5; double expectedX = 6;
double angle = Math.PI * 2 / targetInstanceCount; double angle = Math.PI * 2 / targetInstanceCount;
double radius = targetRadialOffset; double radius = targetRadialOffset;
@ -318,16 +324,17 @@ public class StageTest extends BaseTestCase {
// vv function under test // vv function under test
booster.setAxialOffset(Position.ABSOLUTE, targetX); booster.setAxialOffset(Position.ABSOLUTE, targetX);
// ^^ function under test // ^^ function under test
String treeDump = rocket.toDebugTree();
Coordinate resultantRelativePosition = booster.getRelativePositionVector(); Coordinate resultantRelativePosition = booster.getRelativePositionVector();
assertThat(" 'setAxialPosition(double)' failed. Relative position: ", resultantRelativePosition.x, equalTo(expectedX)); assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Relative position: ", resultantRelativePosition.x, equalTo(expectedX));
double resultantPositionValue = booster.getPositionValue(); double resultantPositionValue = booster.getPositionValue();
assertThat(" 'setAxialPosition(double)' failed. PositionValue: ", resultantPositionValue, equalTo(targetX)); assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " PositionValue: ", resultantPositionValue, equalTo(targetX));
double resultantAxialPosition = booster.getAxialOffset(); double resultantAxialPosition = booster.getAxialOffset();
assertThat(" 'setAxialPosition(double)' failed. Relative position: ", resultantAxialPosition, equalTo(targetX)); assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " 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) // 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(); Coordinate resultantAbsolutePosition = booster.getAbsolutePositionVector();
assertThat(" 'setAxialPosition(double)' failed. Absolute position: ", resultantAbsolutePosition.x, equalTo(targetX)); assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Absolute position: ", resultantAbsolutePosition.x, equalTo(targetX));
} }
// WARNING: // WARNING:
@ -338,32 +345,32 @@ public class StageTest extends BaseTestCase {
// setup // setup
RocketComponent rocket = createTestRocket(); RocketComponent rocket = createTestRocket();
Stage sustainer = (Stage) rocket.getChild(0); Stage sustainer = (Stage) rocket.getChild(0);
Coordinate expectedPosition = new Coordinate(+2.5, 0., 0.);
Coordinate targetPosition = new Coordinate(+4.0, 0., 0.); Coordinate targetPosition = new Coordinate(+4.0, 0., 0.);
Coordinate expectedPosition = targetPosition;
// when 'external' the stage should be freely movable
sustainer.setRelativePositionMethod(Position.TOP);
int expectedRelativeIndex = -1; int expectedRelativeIndex = -1;
int resultantRelativeIndex = sustainer.getRelativeToStage(); int resultantRelativeIndex = sustainer.getRelativeToStage();
assertThat(" 'setRelativeToStage(int)' failed. Relative stage index:", expectedRelativeIndex, equalTo(resultantRelativeIndex)); assertThat(" 'setRelativeToStage(int)' failed. Relative stage index:", expectedRelativeIndex, equalTo(resultantRelativeIndex));
// vv function under test // vv function under test
sustainer.setAxialOffset(targetPosition.x); // when 'external' the stage should be freely movable
sustainer.setAxialOffset(Position.TOP, targetPosition.x);
// ^^ function under test // ^^ function under test
String treeDump = rocket.toDebugTree();
double expectedX = 0;
Coordinate resultantRelativePosition = sustainer.getRelativePositionVector(); Coordinate resultantRelativePosition = sustainer.getRelativePositionVector();
assertThat(" 'setAxialPosition(double)' failed. Relative position: ", resultantRelativePosition.x, equalTo(expectedPosition.x)); assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Sustainer Relative position: ", resultantRelativePosition.x, equalTo(expectedX));
double expectedPositionValue = 0; double expectedPositionValue = 0;
double resultantPositionValue = sustainer.getPositionValue(); double resultantPositionValue = sustainer.getPositionValue();
assertThat(" 'setPositionValue()' failed. Relative position: ", resultantPositionValue, equalTo(expectedPositionValue)); assertThat(" 'setPositionValue()' failed: \n" + treeDump + " Sustainer Position Value: ", resultantPositionValue, equalTo(expectedPositionValue));
double expectedAxialPosition = 0; double expectedAxialOffset = 0;
double resultantAxialPosition = sustainer.getAxialOffset(); double resultantAxialOffset = sustainer.getAxialOffset();
assertThat(" 'getAxialPosition()' failed. Relative position: ", resultantAxialPosition, equalTo(expectedAxialPosition)); assertThat(" 'getAxialPosition()' failed: \n" + treeDump + " Relative position: ", resultantAxialOffset, equalTo(expectedAxialOffset));
// for all stages, the absolute position should equal the relative, because the direct parent is the rocket 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(); Coordinate resultantAbsolutePosition = sustainer.getAbsolutePositionVector();
assertThat(" 'setAbsolutePositionVector()' failed. Absolute position: ", resultantAbsolutePosition.x, equalTo(expectedPosition.x)); assertThat(" 'setAbsolutePositionVector()' failed: \n" + treeDump + " Absolute position: ", resultantAbsolutePosition.x, equalTo(expectedX));
} }
@Test @Test
@ -378,20 +385,21 @@ public class StageTest extends BaseTestCase {
// vv function under test // vv function under test
booster.setAxialOffset(Position.TOP, targetOffset); booster.setAxialOffset(Position.TOP, targetOffset);
// ^^ function under test // ^^ function under test
String treeDump = rocket.toDebugTree();
double expectedAbsoluteX = +9.5; double expectedRelativeX = 2;
double expectedRelativeX = 1.5; double expectedAbsoluteX = 7;
Coordinate resultantRelativePosition = booster.getRelativePositionVector(); Coordinate resultantRelativePosition = booster.getRelativePositionVector();
assertThat(" 'setAxialPosition(double)' failed. Relative position: ", resultantRelativePosition.x, equalTo(expectedRelativeX)); assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " 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) // 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(); Coordinate resultantAbsolutePosition = booster.getAbsolutePositionVector();
assertThat(" 'setAxialPosition(double)' failed. Absolute position: ", resultantAbsolutePosition.x, equalTo(expectedAbsoluteX)); assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Absolute position: ", resultantAbsolutePosition.x, equalTo(expectedAbsoluteX));
double resultantAxialOffset = booster.getAxialOffset(); double resultantAxialOffset = booster.getAxialOffset();
assertThat(" 'getAxialPosition()' failed. Relative position: ", resultantAxialOffset, equalTo(targetOffset)); assertThat(" 'getAxialPosition()' failed: \n" + treeDump + " Axial Offset: ", resultantAxialOffset, equalTo(targetOffset));
double resultantPositionValue = booster.getPositionValue(); double resultantPositionValue = booster.getPositionValue();
assertThat(" 'setPositionValue()' failed. Relative position: ", resultantPositionValue, equalTo(targetOffset)); assertThat(" 'setPositionValue()' failed: \n" + treeDump + " Position Value: ", resultantPositionValue, equalTo(targetOffset));
} }
@Test @Test
@ -407,21 +415,21 @@ public class StageTest extends BaseTestCase {
double targetOffset = +2.0; double targetOffset = +2.0;
booster.setAxialOffset(Position.MIDDLE, targetOffset); booster.setAxialOffset(Position.MIDDLE, targetOffset);
// ^^ function under test // ^^ function under test
String treeDump = rocket.toDebugTree();
double expectedRelativeX = +2.0; double expectedRelativeX = 2.5;
double expectedAbsoluteX = +10.0; double expectedAbsoluteX = 7.5;
Coordinate resultantRelativePosition = booster.getRelativePositionVector(); Coordinate resultantRelativePosition = booster.getRelativePositionVector();
assertThat(" 'setAxialPosition(double)' failed. Relative position: ", resultantRelativePosition.x, equalTo(expectedRelativeX)); assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " 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) // 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(); Coordinate resultantAbsolutePosition = booster.getAbsolutePositionVector();
assertThat(" 'setAxialPosition(double)' failed. Absolute position: ", resultantAbsolutePosition.x, equalTo(expectedAbsoluteX)); assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Absolute position: ", resultantAbsolutePosition.x, equalTo(expectedAbsoluteX));
double resultantPositionValue = booster.getPositionValue(); double resultantPositionValue = booster.getPositionValue();
assertThat(" 'setPositionValue()' failed. Relative position: ", resultantPositionValue, equalTo(targetOffset)); assertThat(" 'setPositionValue()' failed: \n" + treeDump + " Position Value: ", resultantPositionValue, equalTo(targetOffset));
double resultantAxialOffset = booster.getAxialOffset(); double resultantAxialOffset = booster.getAxialOffset();
assertThat(" 'getAxialPosition()' failed. Relative position: ", resultantAxialOffset, equalTo(targetOffset)); assertThat(" 'getAxialPosition()' failed:\n" + treeDump + " Axial Offset: ", resultantAxialOffset, equalTo(targetOffset));
} }
@Test @Test
@ -436,20 +444,21 @@ public class StageTest extends BaseTestCase {
double targetOffset = +4.0; double targetOffset = +4.0;
booster.setAxialOffset(Position.BOTTOM, targetOffset); booster.setAxialOffset(Position.BOTTOM, targetOffset);
// ^^ function under test // ^^ function under test
String treeDump = rocket.toDebugTree();
double expectedRelativeX = +4.5; double expectedRelativeX = 5;
double expectedAbsoluteX = +12.5; double expectedAbsoluteX = +10;
Coordinate resultantRelativePosition = booster.getRelativePositionVector(); Coordinate resultantRelativePosition = booster.getRelativePositionVector();
assertThat(" 'setAxialPosition(double)' failed. Relative position: ", resultantRelativePosition.x, equalTo(expectedRelativeX)); assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " 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) // 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(); Coordinate resultantAbsolutePosition = booster.getAbsolutePositionVector();
assertThat(" 'setAxialPosition(double)' failed. Absolute position: ", resultantAbsolutePosition.x, equalTo(expectedAbsoluteX)); assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Absolute position: ", resultantAbsolutePosition.x, equalTo(expectedAbsoluteX));
double resultantPositionValue = booster.getPositionValue(); double resultantPositionValue = booster.getPositionValue();
assertThat(" 'setPositionValue()' failed. Relative position: ", resultantPositionValue, equalTo(targetOffset)); assertThat(" 'setPositionValue()' failed: \n" + treeDump + " Position Value: ", resultantPositionValue, equalTo(targetOffset));
double resultantAxialOffset = booster.getAxialOffset(); double resultantAxialOffset = booster.getAxialOffset();
assertThat(" 'getAxialPosition()' failed. Relative position: ", resultantAxialOffset, equalTo(targetOffset)); assertThat(" 'getAxialPosition()' failed: \n" + treeDump + " Axial Offset: ", resultantAxialOffset, equalTo(targetOffset));
} }
@Test @Test
@ -462,17 +471,18 @@ public class StageTest extends BaseTestCase {
double targetOffset = +4.50; double targetOffset = +4.50;
booster.setAxialOffset(Position.TOP, targetOffset); booster.setAxialOffset(Position.TOP, targetOffset);
String treeDump = rocket.toDebugTree();
double expectedAxialOffset = +4.0; double expectedRelativePositionX = targetOffset;
Coordinate resultantRelativePosition = booster.getRelativePositionVector(); Coordinate resultantRelativePosition = booster.getRelativePositionVector();
assertThat(" 'setAxialPosition(double)' failed. Relative position: ", resultantRelativePosition.x, equalTo(expectedAxialOffset)); assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Relative position: ", resultantRelativePosition.x, equalTo(expectedRelativePositionX));
// vv function under test // vv function under test
double resultantAxialPosition = booster.asPositionValue(Position.ABSOLUTE); double resultantAxialPosition = booster.asPositionValue(Position.ABSOLUTE);
// ^^ function under test // ^^ function under test
double expectedAbsoluteX = +12.0; double expectedAbsoluteX = 9.5;
assertThat(" 'setPositionValue()' failed. Relative position: ", resultantAxialPosition, equalTo(expectedAbsoluteX)); assertThat(" 'setPositionValue()' failed: \n" + treeDump + " asPositionValue: ", resultantAxialPosition, equalTo(expectedAbsoluteX));
} }
@Test @Test
@ -485,19 +495,18 @@ public class StageTest extends BaseTestCase {
double targetOffset = +4.50; double targetOffset = +4.50;
booster.setAxialOffset(Position.TOP, targetOffset); booster.setAxialOffset(Position.TOP, targetOffset);
String treeDump = rocket.toDebugTree();
double expectedRelativeX = +4.0; double expectedRelativeX = targetOffset;
double resultantX = booster.getRelativePositionVector().x; double resultantX = booster.getRelativePositionVector().x;
assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Relative position: ", resultantX, equalTo(expectedRelativeX));
assertThat(" 'setAxialPosition(double)' failed. Relative position: ", resultantX, equalTo(expectedRelativeX));
// vv function under test // vv function under test
// because this component is not initalized to
resultantX = booster.asPositionValue(Position.AFTER); resultantX = booster.asPositionValue(Position.AFTER);
// ^^ function under test // ^^ function under test
double expectedAfterX = 4.5; double expectedAfterX = -1.5;
assertEquals(" 'setPositionValue()' failed. Relative position: ", expectedAfterX, resultantX, EPSILON); assertEquals(" 'setPositionValue()' failed: \n" + treeDump + " asPosition: ", expectedAfterX, resultantX, EPSILON);
} }
@Test @Test
@ -510,10 +519,11 @@ public class StageTest extends BaseTestCase {
double targetOffset = +4.50; double targetOffset = +4.50;
booster.setAxialOffset(Position.TOP, targetOffset); booster.setAxialOffset(Position.TOP, targetOffset);
String treeDump = rocket.toDebugTree();
double expectedRelativeX = +4.0; double expectedRelativeX = targetOffset;
double resultantX = booster.getRelativePositionVector().x; double resultantX = booster.getRelativePositionVector().x;
assertThat(" 'setAxialPosition(double)' failed. Relative position: ", resultantX, equalTo(expectedRelativeX)); assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Relative position: ", resultantX, equalTo(expectedRelativeX));
double resultantAxialPosition; double resultantAxialPosition;
double expectedAxialPosition = +4.0; double expectedAxialPosition = +4.0;
@ -521,7 +531,7 @@ public class StageTest extends BaseTestCase {
resultantAxialPosition = booster.asPositionValue(Position.MIDDLE); resultantAxialPosition = booster.asPositionValue(Position.MIDDLE);
// ^^ function under test // ^^ function under test
assertEquals(" 'setPositionValue()' failed. Relative position: ", expectedAxialPosition, resultantAxialPosition, EPSILON); assertEquals(" 'setPositionValue()' failed: \n" + treeDump + " Relative position: ", expectedAxialPosition, resultantAxialPosition, EPSILON);
} }
@Test @Test
@ -535,16 +545,17 @@ public class StageTest extends BaseTestCase {
double targetOffset = +4.50; double targetOffset = +4.50;
booster.setAxialOffset(Position.TOP, targetOffset); booster.setAxialOffset(Position.TOP, targetOffset);
String treeDump = rocket.toDebugTree();
double expectedRelativeX = +4.0; double expectedRelativeX = targetOffset;
double resultantX = booster.getRelativePositionVector().x; double resultantX = booster.getRelativePositionVector().x;
assertEquals(" 'setAxialPosition(double)' failed. Relative position: ", expectedRelativeX, resultantX, EPSILON); assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Relative position: ", resultantX, equalTo(expectedRelativeX));
// vv function under test // vv function under test
double resultantAxialOffset = booster.asPositionValue(Position.BOTTOM); double resultantAxialOffset = booster.asPositionValue(Position.BOTTOM);
// ^^ function under test // ^^ function under test
double expectedAxialOffset = +3.5; double expectedAxialOffset = +3.5;
assertEquals(" 'setPositionValue()' failed. Relative position: ", expectedAxialOffset, resultantAxialOffset, EPSILON); assertEquals(" 'setPositionValue()' failed: \n" + treeDump + " Relative position: ", expectedAxialOffset, resultantAxialOffset, EPSILON);
} }
@ -558,93 +569,57 @@ public class StageTest extends BaseTestCase {
double targetOffset = +4.50; double targetOffset = +4.50;
booster.setAxialOffset(Position.BOTTOM, targetOffset); booster.setAxialOffset(Position.BOTTOM, targetOffset);
String treeDump = rocket.toDebugTree();
double expectedRelativeX = +5.0; double expectedRelativeX = +5.5;
double resultantX = booster.getRelativePositionVector().x; double resultantX = booster.getRelativePositionVector().x;
assertEquals(" 'setAxialPosition(double)' failed. Relative position: ", expectedRelativeX, resultantX, EPSILON); assertEquals(" 'setAxialPosition(double)' failed: \n" + treeDump + " Relative position: ", expectedRelativeX, resultantX, EPSILON);
// vv function under test // vv function under test
double resultantAxialOffset = booster.asPositionValue(Position.TOP); double resultantAxialOffset = booster.asPositionValue(Position.TOP);
// ^^ function under test // ^^ function under test
double expectedAxialOffset = 5.5; double expectedAxialOffset = expectedRelativeX;
assertEquals(" 'setPositionValue()' failed. Relative position: ", expectedAxialOffset, resultantAxialOffset, EPSILON); assertEquals(" 'setPositionValue()' failed: \n" + treeDump + " Relative position: ", expectedAxialOffset, resultantAxialOffset, EPSILON);
} }
@Test @Test
public void testOutsideStageRepositionTOPAfterAdd() { public void testOutsideStageRepositionTOPAfterAdd() {
final double boosterRadius = 0.8; final double boosterRadius = 0.8;
Rocket rocket = createTestRocket();
Stage core = (Stage) rocket.getChild(1);
Stage booster = new Stage();
booster.setName("Booster Stage");
core.addChild(booster);
final double targetOffset = +2.50; final double targetOffset = +2.50;
final Position targetMethod = Position.TOP; final Position targetMethod = Position.TOP;
Rocket rocket = createTestRocket();
Stage core = (Stage) rocket.getChild(1);
Stage booster = new Stage();
booster.setName("Booster Stage");
core.addChild(booster);
booster.setAxialOffset(targetMethod, targetOffset); booster.setAxialOffset(targetMethod, targetOffset);
String treeDumpBefore = rocket.toDebugTree();
// requirement: regardless of initialization order (which we cannot control) // requirement: regardless of initialization order (which we cannot control)
// a booster should retain it's positioning method and offset while adding on children // a booster should retain it's positioning method and offset while adding on children
double expectedRelativeX = -0.5; double expectedRelativeX = 2.5;
double resultantOffset = booster.getRelativePositionVector().x; double resultantOffset = booster.getRelativePositionVector().x;
assertEquals(" init order error: Booster: initial relative X: ", expectedRelativeX, resultantOffset, EPSILON); assertEquals(" init order error: Booster: " + treeDumpBefore + " initial relative X: ", expectedRelativeX, resultantOffset, EPSILON);
double expectedAxialOffset = targetOffset; double expectedAxialOffset = targetOffset;
resultantOffset = booster.getAxialOffset(); resultantOffset = booster.getAxialOffset();
assertEquals(" init order error: Booster: initial axial offset: ", expectedAxialOffset, resultantOffset, EPSILON); assertEquals(" init order error: Booster: " + treeDumpBefore + " Initial axial offset: ", expectedAxialOffset, resultantOffset, EPSILON);
// Body Component 2 // Body Component 2
RocketComponent boosterBody = new BodyTube(4.0, boosterRadius, 0.01); RocketComponent boosterBody = new BodyTube(4.0, boosterRadius, 0.01);
boosterBody.setName("Booster Body "); boosterBody.setName("Booster Body ");
booster.addChild(boosterBody); booster.addChild(boosterBody);
expectedAxialOffset = targetOffset; String treeDumpAfter = rocket.toDebugTree();
resultantOffset = booster.getAxialOffset();
assertEquals(" init order error: Booster: populated axial offset: ", expectedAxialOffset, resultantOffset, EPSILON); expectedRelativeX = 2.5; // no change
expectedRelativeX = 1.5;
resultantOffset = booster.getRelativePositionVector().x; resultantOffset = booster.getRelativePositionVector().x;
assertEquals(" init order error: Booster: populated relative X: ", expectedRelativeX, resultantOffset, EPSILON); assertEquals(" init order error: Booster: " + treeDumpBefore + " =======> " + treeDumpAfter + " populated relative X: ", expectedRelativeX, resultantOffset, EPSILON);
expectedAxialOffset = targetOffset; expectedAxialOffset = targetOffset; // again, no change
}
@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);
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(); resultantOffset = booster.getAxialOffset();
assertEquals(" init order error: Booster: initial axial offset: ", expectedAxialOffset, resultantOffset, EPSILON); assertEquals(" init order error: Booster: " + treeDumpBefore + " =======> " + treeDumpAfter + " populated 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 @Test
public void testStageInitializationMethodValueOrder() { public void testStageInitializationMethodValueOrder() {
Rocket rocket = createTestRocket(); Rocket rocket = createTestRocket();
@ -656,8 +631,8 @@ public class StageTest extends BaseTestCase {
boosterB.setName("Booster B Stage"); boosterB.setName("Booster B Stage");
core.addChild(boosterB); core.addChild(boosterB);
double targetOffset = +4.50; double targetOffset = +4.5;
double expectedOffset = +4.0; double expectedOffset = +4.5;
// requirement: regardless of initialization order (which we cannot control) // requirement: regardless of initialization order (which we cannot control)
// two boosters with identical initialization commands should end up at the same place. // two boosters with identical initialization commands should end up at the same place.
@ -665,13 +640,13 @@ public class StageTest extends BaseTestCase {
boosterB.setRelativePositionMethod(Position.TOP); boosterB.setRelativePositionMethod(Position.TOP);
boosterB.setAxialOffset(targetOffset); boosterB.setAxialOffset(targetOffset);
String treeDump = rocket.toDebugTree();
double resultantOffsetA = boosterA.getRelativePositionVector().x; double resultantOffsetA = boosterA.getRelativePositionVector().x;
double resultantOffsetB = boosterB.getRelativePositionVector().x; double resultantOffsetB = boosterB.getRelativePositionVector().x;
assertEquals(" init order error: Booster A: resultant positions: ", expectedOffset, resultantOffsetA, EPSILON); assertEquals(" init order error: " + treeDump + " Booster A: resultant positions: ", expectedOffset, resultantOffsetA, EPSILON);
assertEquals(" init order error: Booster B: resultant positions: ", expectedOffset, resultantOffsetB, EPSILON); assertEquals(" init order error: " + treeDump + " Booster B: resultant positions: ", expectedOffset, resultantOffsetB, EPSILON);
} }

View File

@ -23,7 +23,7 @@ public class BodyTubeShapes extends RocketComponentShape {
Shape[] s = new Shape[instanceOffsets.length]; Shape[] s = new Shape[instanceOffsets.length];
for (int i=0; i < instanceOffsets.length; i++) { 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 s[i] = new Rectangle2D.Double((instanceOffsets[i].x)*S, //x - the X coordinate of the upper-left corner of the newly constructed Rectangle2D
(instanceOffsets[i].y-radius)*S, // y - the Y coordinate of the upper-left corner of the newly constructed Rectangle2D (instanceOffsets[i].y-radius)*S, // y - the Y coordinate of the upper-left corner of the newly constructed Rectangle2D
length*S, // w - the width of the newly constructed Rectangle2D length*S, // w - the width of the newly constructed Rectangle2D
2*radius*S); // h - the height of the newly constructed Rectangle2D 2*radius*S); // h - the height of the newly constructed Rectangle2D

View File

@ -24,8 +24,7 @@ public class FinSetShapes extends RocketComponentShape {
Transformation baseRotation = finset.getBaseRotationTransformation(); // rotation about x-axis Transformation baseRotation = finset.getBaseRotationTransformation(); // rotation about x-axis
Transformation finRotation = finset.getFinRotationTransformation(); Transformation finRotation = finset.getFinRotationTransformation();
double rootChord = finset.getLength(); Coordinate finSetFront = componentAbsoluteLocation;
Coordinate finSetFront = componentAbsoluteLocation.sub( rootChord/2 , 0, 0);
Coordinate finPoints[] = finset.getFinPointsWithTab(); Coordinate finPoints[] = finset.getFinPointsWithTab();
// TODO: MEDIUM: sloping radius // TODO: MEDIUM: sloping radius

View File

@ -18,7 +18,7 @@ public class MassComponentShapes extends RocketComponentShape {
public static RocketComponentShape[] getShapesSide( public static RocketComponentShape[] getShapesSide(
net.sf.openrocket.rocketcomponent.RocketComponent component, net.sf.openrocket.rocketcomponent.RocketComponent component,
Transformation transformation, Transformation transformation,
Coordinate instanceOffset) { Coordinate componentAbsoluteLocation) {
net.sf.openrocket.rocketcomponent.MassObject tube = (net.sf.openrocket.rocketcomponent.MassObject)component; net.sf.openrocket.rocketcomponent.MassObject tube = (net.sf.openrocket.rocketcomponent.MassObject)component;
@ -27,11 +27,16 @@ public class MassComponentShapes extends RocketComponentShape {
double length = tube.getLength(); double length = tube.getLength();
double radius = tube.getRadius(); double radius = tube.getRadius();
double arc = Math.min(length, 2*radius) * 0.7; double arc = Math.min(length, 2*radius) * 0.7;
Coordinate[] start = transformation.transform(tube.toAbsolute(instanceOffset));
Shape[] s = new Shape[start.length]; Coordinate oldStart = transformation.transform( componentAbsoluteLocation );
for (int i=0; i < start.length; i++) { Coordinate start = transformation.transform( componentAbsoluteLocation);
s[i] = new RoundRectangle2D.Double(start[i].x*S,(start[i].y-radius)*S, // Shape s = new RoundRectangle2D.Double(start.x*S,(start.y-radius)*S,
// length*S,2*radius*S,arc*S,arc*S);
Shape[] s = new Shape[1];
for (int i=0; i < 1; i++) {
s[i] = new RoundRectangle2D.Double((start.x)*S,(start.y-radius)*S,
length*S,2*radius*S,arc*S,arc*S); length*S,2*radius*S,arc*S,arc*S);
} }
@ -67,13 +72,13 @@ public class MassComponentShapes extends RocketComponentShape {
public static RocketComponentShape[] getShapesBack( public static RocketComponentShape[] getShapesBack(
net.sf.openrocket.rocketcomponent.RocketComponent component, net.sf.openrocket.rocketcomponent.RocketComponent component,
Transformation transformation, Transformation transformation,
Coordinate instanceOffset) { Coordinate componentAbsoluteLocation) {
net.sf.openrocket.rocketcomponent.MassObject tube = (net.sf.openrocket.rocketcomponent.MassObject)component; net.sf.openrocket.rocketcomponent.MassObject tube = (net.sf.openrocket.rocketcomponent.MassObject)component;
double or = tube.getRadius(); double or = tube.getRadius();
Coordinate[] start = transformation.transform(tube.toAbsolute(instanceOffset)); Coordinate[] start = new Coordinate[]{transformation.transform( componentAbsoluteLocation )};
Shape[] s = new Shape[start.length]; Shape[] s = new Shape[start.length];
for (int i=0; i < start.length; i++) { for (int i=0; i < start.length; i++) {

View File

@ -15,14 +15,14 @@ public class ParachuteShapes extends RocketComponentShape {
public static RocketComponentShape[] getShapesSide( public static RocketComponentShape[] getShapesSide(
net.sf.openrocket.rocketcomponent.RocketComponent component, net.sf.openrocket.rocketcomponent.RocketComponent component,
Transformation transformation, Transformation transformation,
Coordinate instanceOffset) { Coordinate componentAbsoluteLocation) {
net.sf.openrocket.rocketcomponent.MassObject tube = (net.sf.openrocket.rocketcomponent.MassObject)component; net.sf.openrocket.rocketcomponent.MassObject tube = (net.sf.openrocket.rocketcomponent.MassObject)component;
double length = tube.getLength(); double length = tube.getLength();
double radius = tube.getRadius(); double radius = tube.getRadius();
double arc = Math.min(length, 2*radius) * 0.7; double arc = Math.min(length, 2*radius) * 0.7;
Coordinate[] start = transformation.transform(tube.toAbsolute(instanceOffset)); Coordinate[] start = new Coordinate[]{transformation.transform( componentAbsoluteLocation)};
Shape[] s = new Shape[start.length]; Shape[] s = new Shape[start.length];
for (int i=0; i < start.length; i++) { for (int i=0; i < start.length; i++) {

View File

@ -23,8 +23,8 @@ public class StreamerShapes extends RocketComponentShape {
double arc = Math.min(length, 2*radius) * 0.7; double arc = Math.min(length, 2*radius) * 0.7;
Shape[] s = new Shape[1]; Shape[] s = new Shape[1];
Coordinate center = componentAbsoluteLocation; Coordinate frontCenter = componentAbsoluteLocation;
s[0] = new RoundRectangle2D.Double((center.x-radius)*S,(center.y-radius)*S, s[0] = new RoundRectangle2D.Double((frontCenter.x)*S,(frontCenter.y-radius)*S,
length*S,2*radius*S,arc*S,arc*S); length*S,2*radius*S,arc*S,arc*S);
// Coordinate[] start = transformation.transform(tube.toAbsolute(instanceOffset)); // Coordinate[] start = transformation.transform(tube.toAbsolute(instanceOffset));

View File

@ -85,19 +85,18 @@ public class SymmetricComponentShapes extends RocketComponentShape {
//System.out.println("here"); //System.out.println("here");
final int len = points.size(); final int len = points.size();
Coordinate center = componentAbsoluteLocation; Coordinate nose = componentAbsoluteLocation;
Coordinate nose = center.sub( component.getLength()/2, 0, 0);
// TODO: LOW: curved path instead of linear // TODO: LOW: curved path instead of linear
Path2D.Double path = new Path2D.Double(); Path2D.Double path = new Path2D.Double();
path.moveTo((nose.x + points.get(len - 1).x) * scaleFactor, (center.y+points.get(len - 1).y) * scaleFactor); path.moveTo((nose.x + points.get(len - 1).x) * scaleFactor, (nose.y+points.get(len - 1).y) * scaleFactor);
for (i = len - 2; i >= 0; i--) { for (i = len - 2; i >= 0; i--) {
path.lineTo((nose.x+points.get(i).x)* scaleFactor, (center.y+points.get(i).y) * scaleFactor); path.lineTo((nose.x+points.get(i).x)* scaleFactor, (nose.y+points.get(i).y) * scaleFactor);
} }
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
path.lineTo((nose.x+points.get(i).x) * scaleFactor, (center.y-points.get(i).y) * scaleFactor); path.lineTo((nose.x+points.get(i).x) * scaleFactor, (nose.y-points.get(i).y) * scaleFactor);
} }
path.lineTo((nose.x+points.get(len - 1).x) * scaleFactor, (center.y+points.get(len - 1).y) * scaleFactor); path.lineTo((nose.x+points.get(len - 1).x) * scaleFactor, (nose.y+points.get(len - 1).y) * scaleFactor);
path.closePath(); path.closePath();
//s[len] = path; //s[len] = path;

View File

@ -30,20 +30,20 @@ public class TransitionShapes extends RocketComponentShape {
RocketComponentShape[] mainShapes; RocketComponentShape[] mainShapes;
Coordinate center = transformation.transform( componentAbsoluteLocation ); Coordinate frontCenter = transformation.transform( componentAbsoluteLocation );
// this component type does not allow multiple instances // this component type does not allow multiple instances
// Simpler shape for conical transition, others use the method from SymmetricComponent // Simpler shape for conical transition, others use the method from SymmetricComponent
if (transition.getType() == Transition.Shape.CONICAL) { if (transition.getType() == Transition.Shape.CONICAL) {
double halflength = transition.getLength()/2; double length = transition.getLength();
double r1 = transition.getForeRadius(); double r1 = transition.getForeRadius();
double r2 = transition.getAftRadius(); double r2 = transition.getAftRadius();
Path2D.Float path = new Path2D.Float(); Path2D.Float path = new Path2D.Float();
path.moveTo( (center.x-halflength)* scaleFactor, (center.y+ r1)* scaleFactor); path.moveTo( (frontCenter.x)* scaleFactor, (frontCenter.y+ r1)* scaleFactor);
path.lineTo( (center.x+halflength)* scaleFactor, (center.y+r2)* scaleFactor); path.lineTo( (frontCenter.x+length)* scaleFactor, (frontCenter.y+r2)* scaleFactor);
path.lineTo( (center.x+halflength)* scaleFactor, (center.y-r2)* scaleFactor); path.lineTo( (frontCenter.x+length)* scaleFactor, (frontCenter.y-r2)* scaleFactor);
path.lineTo( (center.x-halflength)* scaleFactor, (center.y-r1)* scaleFactor); path.lineTo( (frontCenter.x)* scaleFactor, (frontCenter.y-r1)* scaleFactor);
path.closePath(); path.closePath();
mainShapes = new RocketComponentShape[] { new RocketComponentShape( path, component) }; mainShapes = new RocketComponentShape[] { new RocketComponentShape( path, component) };
@ -55,21 +55,21 @@ public class TransitionShapes extends RocketComponentShape {
int arrayLength = mainShapes.length; int arrayLength = mainShapes.length;
if (transition.getForeShoulderLength() > 0.0005) { if (transition.getForeShoulderLength() > 0.0005) {
Coordinate foreTransitionShoulderCenter = componentAbsoluteLocation.sub( (transition.getLength() + transition.getForeShoulderLength())/2, 0, 0); Coordinate foreTransitionShoulderCenter = componentAbsoluteLocation.sub( transition.getForeShoulderLength()/2, 0, 0);
center = transformation.transform( foreTransitionShoulderCenter); frontCenter = transformation.transform( foreTransitionShoulderCenter);
double rad = transition.getForeShoulderRadius(); double rad = transition.getForeShoulderRadius();
double len = transition.getForeShoulderLength(); double len = transition.getForeShoulderLength();
foreShoulder = new Rectangle2D.Double((center.x-len/2)* scaleFactor, (center.y-rad)* scaleFactor, len* scaleFactor, 2*rad* scaleFactor); foreShoulder = new Rectangle2D.Double((frontCenter.x-len/2)* scaleFactor, (frontCenter.y-rad)* scaleFactor, len* scaleFactor, 2*rad* scaleFactor);
arrayLength++; arrayLength++;
} }
if (transition.getAftShoulderLength() > 0.0005) { if (transition.getAftShoulderLength() > 0.0005) {
Coordinate aftTransitionShoulderCenter = componentAbsoluteLocation.add( (transition.getLength() + transition.getAftShoulderLength())/2, 0, 0); Coordinate aftTransitionShoulderCenter = componentAbsoluteLocation.add( transition.getLength() + (transition.getAftShoulderLength())/2, 0, 0);
center= transformation.transform( aftTransitionShoulderCenter ); frontCenter= transformation.transform( aftTransitionShoulderCenter );
double rad = transition.getAftShoulderRadius(); double rad = transition.getAftShoulderRadius();
double len = transition.getAftShoulderLength(); double len = transition.getAftShoulderLength();
aftShoulder = new Rectangle2D.Double((center.x-len/2)* scaleFactor, (center.y-rad)* scaleFactor, len* scaleFactor, 2*rad* scaleFactor); aftShoulder = new Rectangle2D.Double((frontCenter.x-len/2)* scaleFactor, (frontCenter.y-rad)* scaleFactor, len* scaleFactor, 2*rad* scaleFactor);
arrayLength++; arrayLength++;
} }
if (foreShoulder==null && aftShoulder==null) if (foreShoulder==null && aftShoulder==null)

View File

@ -22,7 +22,7 @@ public class TubeFinSetShapes extends RocketComponentShape {
double outerRadius = finset.getOuterRadius(); double outerRadius = finset.getOuterRadius();
double bodyRadius = finset.getBodyRadius(); double bodyRadius = finset.getBodyRadius();
Coordinate[] start = new Coordinate[]{ transformation.transform( componentAbsoluteLocation.sub( length/2, 0, 0) )}; Coordinate[] start = new Coordinate[]{ transformation.transform( componentAbsoluteLocation )};
start = component.shiftCoordinates( start); start = component.shiftCoordinates( start);
Transformation baseRotation = finset.getBaseRotationTransformation(); Transformation baseRotation = finset.getBaseRotationTransformation();

View File

@ -355,7 +355,7 @@ public class RocketFigure extends AbstractScaleFigure {
double mountLength = mountComponent.getLength(); double mountLength = mountComponent.getLength();
Coordinate[] motorPositions; Coordinate[] motorPositions;
Coordinate[] clusterTop = new Coordinate[]{mountPosition.add( mountLength/2 - motorLength + mount.getMotorOverhang() , 0, 0)}; Coordinate[] clusterTop = new Coordinate[]{mountPosition.add( mountLength - motorLength + mount.getMotorOverhang() , 0, 0)};
motorPositions = mountComponent.shiftCoordinates(clusterTop); motorPositions = mountComponent.shiftCoordinates(clusterTop);