[refactor] RocketComponent positioning is now centralized in AxialMethod class

- also relaxed visibility for Component::setAxialMethod(...)
This commit is contained in:
Daniel_M_Williams 2018-09-16 11:54:48 -04:00
parent 7d813b4e55
commit b268d3aa59
25 changed files with 146 additions and 341 deletions

View File

@ -325,7 +325,8 @@ class FinSetHandler extends AbstractElementHandler {
result.setBaseRotation(radialAngle);
result.setCrossSection(convertTipShapeCode(tipShapeCode));
result.setAxialMethod(axialMethod);
PositionDependentHandler.setLocation(result, axialMethod, location);
result.setAxialOffset(location);
return result;
}

View File

@ -15,7 +15,6 @@ import net.sf.openrocket.file.simplesax.PlainTextHandler;
import net.sf.openrocket.material.Material;
import net.sf.openrocket.rocketcomponent.InnerTube;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
/**
* A SAX handler for Rocksim inside tubes.
@ -99,17 +98,6 @@ class InnerBodyTubeHandler extends PositionDependentHandler<InnerTube> {
return bodyTube;
}
/**
* Set the relative position onto the component. This cannot be done directly because setRelativePosition is not
* public in all components.
*
* @param position the OpenRocket position
*/
@Override
public void setAxialMethod(AxialMethod position) {
bodyTube.setAxialMethod(position);
}
/**
* Get the required type of material for this component.
*

View File

@ -16,7 +16,6 @@ import net.sf.openrocket.file.simplesax.PlainTextHandler;
import net.sf.openrocket.material.Material;
import net.sf.openrocket.rocketcomponent.LaunchLug;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
/**
* The SAX handler for Rocksim Launch Lugs.
@ -91,17 +90,6 @@ class LaunchLugHandler extends PositionDependentHandler<LaunchLug> {
return lug;
}
/**
* Set the relative position onto the component. This cannot be done directly because setRelativePosition is not
* public in all components.
*
* @param newMethod the OpenRocket position
*/
@Override
public void setAxialMethod(AxialMethod newMethod) {
lug.setAxialMethod(newMethod);
}
/**
* Get the required type of material for this component.
*

View File

@ -17,7 +17,6 @@ import net.sf.openrocket.rocketcomponent.MassComponent;
import net.sf.openrocket.rocketcomponent.MassObject;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketcomponent.ShockCord;
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
import org.xml.sax.SAXException;
@ -184,17 +183,6 @@ class MassObjectHandler extends PositionDependentHandler<MassObject> {
return current;
}
/**
* Set the relative position onto the component. This cannot be done directly because setRelativePosition is not
* public in all components.
*
* @param position the OpenRocket position
*/
@Override
public void setAxialMethod( AxialMethod position) {
current.setAxialMethod(position);
}
/**
* Get the required type of material for this component. Does not apply to MassComponents, but does apply to Shock
* Cords.

View File

@ -15,18 +15,18 @@ import net.sf.openrocket.rocketcomponent.position.AxialMethod;
import org.xml.sax.SAXException;
/**
* An abstract base class that handles position dependencies for all lower level components that
* are position aware.
* An abstract base class that handles axialMethod dependencies for all lower level components that
* are axialMethod aware.
*
* @param <C> the specific position dependent RocketComponent subtype for which the concrete handler can create
* @param <C> the specific axialMethod dependent RocketComponent subtype for which the concrete handler can create
*/
public abstract class PositionDependentHandler<C extends RocketComponent> extends BaseHandler<C> {
/** Temporary position value. */
/** Temporary axialMethod value. */
private Double positionValue = 0d;
/** Temporary position. */
private AxialMethod position = AxialMethod.TOP;
/** Temporary axialMethod. */
private AxialMethod axialMethod = AxialMethod.TOP;
public PositionDependentHandler(DocumentLoadingContext context) {
super(context);
@ -43,15 +43,15 @@ public abstract class PositionDependentHandler<C extends RocketComponent> extend
positionValue = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH;
}
if (RocksimCommonConstants.LOCATION_MODE.equals(element)) {
position = RocksimLocationMode.fromCode(Integer.parseInt(
axialMethod = RocksimLocationMode.fromCode(Integer.parseInt(
content)).asOpenRocket();
}
}
/**
* This method sets the position information onto the component. Rocksim splits the location/position
* This method sets the axialMethod information onto the component. Rocksim splits the location/axialMethod
* information into two disparate data elements. Both pieces of data are necessary to map into OpenRocket's
* position model.
* axialMethod model.
*
* @param element the element name
* @param attributes the attributes
@ -63,31 +63,18 @@ public abstract class PositionDependentHandler<C extends RocketComponent> extend
public void endHandler(String element, HashMap<String, String> attributes,
String content, WarningSet warnings) throws SAXException {
super.endHandler(element, attributes, content, warnings);
setAxialMethod(position);
setLocation(getComponent(), position, positionValue);
setLocation();
}
/**
* Set the relative position onto the component. This cannot be done directly because setRelativePosition is not
* public in all components.
*
* @param position the OpenRocket position
* Set the axialMethod of a component.
*/
protected abstract void setAxialMethod(AxialMethod position);
/**
* Set the position of a component.
*
* @param component the component
* @param position the relative position
* @param location the actual position value
*/
public static void setLocation(RocketComponent component, AxialMethod position, double location) {
if (position.equals(AxialMethod.BOTTOM)) {
component.setAxialOffset(-1d * location);
}
else {
component.setAxialOffset(location);
protected void setLocation() {
getComponent().setAxialMethod(axialMethod);
if (axialMethod.equals(AxialMethod.BOTTOM)) {
getComponent().setAxialOffset(-1d * positionValue);
} else {
getComponent().setAxialOffset(positionValue);
}
}

View File

@ -11,7 +11,6 @@ import net.sf.openrocket.file.rocksim.RocksimCommonConstants;
import net.sf.openrocket.file.rocksim.RocksimDensityType;
import net.sf.openrocket.material.Material;
import net.sf.openrocket.rocketcomponent.RecoveryDevice;
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
import org.xml.sax.SAXException;
@ -95,18 +94,7 @@ public abstract class RecoveryDeviceHandler<C extends RecoveryDevice> extends Po
}
return result;
}
/**
* Set the relative position onto the component. This cannot be done directly because setRelativePosition is not
* public in all components.
*
* @param position the OpenRocket position
*/
@Override
public void setAxialMethod( AxialMethod position) {
getComponent().setAxialMethod(position);
}
/**
* Get the required type of material for this component. This is the OpenRocket type, which does NOT always
* correspond to Rocksim. Some streamer material is defined as BULK in the Rocksim file. In those cases

View File

@ -19,7 +19,6 @@ import net.sf.openrocket.rocketcomponent.EngineBlock;
import net.sf.openrocket.rocketcomponent.RingComponent;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketcomponent.TubeCoupler;
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
/**
* A SAX handler for centering rings, tube couplers, and bulkheads.
@ -180,17 +179,6 @@ class RingHandler extends PositionDependentHandler<CenteringRing> {
result.setThickness(result.getThickness());
}
/**
* Set the relative position onto the component. This cannot be done directly because setAxialMethod is not
* public in all components.
*
* @param position the OpenRocket position
*/
@Override
public void setAxialMethod(AxialMethod position) {
ring.setAxialMethod(position);
}
@Override
public void endHandler(String element, HashMap<String, String> attributes, String content, WarningSet warnings) throws SAXException {
super.endHandler(element, attributes, content, warnings);

View File

@ -9,7 +9,6 @@ import net.sf.openrocket.file.simplesax.PlainTextHandler;
import net.sf.openrocket.material.Material;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketcomponent.TubeFinSet;
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
import org.xml.sax.SAXException;
@ -34,25 +33,14 @@ public class TubeFinSetHandler extends PositionDependentHandler<TubeFinSet> {
* @throws IllegalArgumentException thrown if <code>c</code> is null
*/
public TubeFinSetHandler(DocumentLoadingContext context, RocketComponent c, WarningSet warnings) throws IllegalArgumentException {
super(context);
if (c == null) {
throw new IllegalArgumentException("The parent component of a tube fin may not be null.");
}
tubeFin = new TubeFinSet();
if (isCompatible(c, TubeFinSet.class, warnings)) {
c.addChild(tubeFin);
}
}
/**
* Set the relative position onto the component.
*
* @param position the OpenRocket position
*/
@Override
protected void setAxialMethod(final AxialMethod position) {
tubeFin.setAxialMethod(position);
super(context);
if (c == null) {
throw new IllegalArgumentException("The parent component of a tube fin may not be null.");
}
tubeFin = new TubeFinSet();
if (isCompatible(c, TubeFinSet.class, warnings)) {
c.addChild(tubeFin);
}
}
/**

View File

@ -32,7 +32,11 @@ public abstract class ComponentAssembly extends RocketComponent implements Axia
public ComponentAssembly() {
super( AxialMethod.AFTER);
}
public ComponentAssembly( final AxialMethod initialAxialMethod) {
super(initialAxialMethod);
}
@Override
public boolean allowsChildren(){
return true;
@ -40,7 +44,7 @@ public abstract class ComponentAssembly extends RocketComponent implements Axia
@Override
public double getAxialOffset() {
return asPositionValue( this.axialMethod );
return getAxialOffset( this.axialMethod );
}
/**

View File

@ -476,7 +476,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
* Copy all available information attached to this, and attached copies to the
* new configuration
*
* @param copyId attached the new configuration to this Id
* @param newId attached the new configuration to this Id
* @return the new configuration
*/
@Override

View File

@ -21,7 +21,7 @@ public class LaunchLug extends ExternalComponent implements AnglePositionable, C
private double thickness;
private double radialDirection = 0;
protected double radialDistance = 0;
private double radialDistance = 0;
private int instanceCount = 1;
private double instanceSeparation = 0; // front-front along the positive rocket axis. i.e. [1,0,0];
@ -98,15 +98,7 @@ public class LaunchLug extends ExternalComponent implements AnglePositionable, C
public boolean isAfter() {
return false;
}
@Override
public void setAxialMethod( AxialMethod position) {
super.setAxialMethod(position);
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
@Override
protected void loadFromPreset(ComponentPreset preset) {
if (preset.has(ComponentPreset.OUTER_DIAMETER)) {

View File

@ -157,7 +157,7 @@ public class PodSet extends ComponentAssembly implements RingInstanceable {
// remember the implicit (this instanceof Stage)
throw new BugException("found a pod positioned via: AFTER, but is not on the centerline?!: " + this.getName() + " is " + this.getAxialMethod().name() );
} else {
returnValue = super.asPositionValue(this.axialMethod);
returnValue = super.getAxialOffset(this.axialMethod);
}
if (0.000001 > Math.abs(returnValue)) {

View File

@ -11,8 +11,10 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.ArrayList;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.MathUtil;
import net.sf.openrocket.util.StateChangeListener;
import net.sf.openrocket.util.UniqueID;
@ -74,6 +76,7 @@ public class Rocket extends ComponentAssembly {
///////////// Constructor /////////////
public Rocket() {
super(AxialMethod.ABSOLUTE);
modID = UniqueID.next();
massModID = modID;
aeroModID = modID;
@ -244,7 +247,18 @@ public class Rocket extends ComponentAssembly {
/*package-local*/ void forgetStage(final AxialStage oldStage) {
this.stageMap.remove(oldStage.getStageNumber());
}
@Override
public void setAxialMethod(final AxialMethod newAxialMethod) {
this.axialMethod = AxialMethod.ABSOLUTE;
}
@Override
public void setAxialOffset( final double requestOffset ) {
this.axialOffset = 0.;
this.position = Coordinate.ZERO;
}
public ReferenceType getReferenceType() {
checkState();
return refType;
@ -707,9 +721,9 @@ public class Rocket extends ComponentAssembly {
* Return a flight configuration. If the supplied index is out of bounds, an exception is thrown.
* If the default instance is allowed, the default will be at index 0.
*
* @param includeDefault Whether to allow returning the default instance
* @param allowDefault Whether to allow returning the default instance
* @param configIndex The flight configuration index number
* @return a FlightConfiguration instance
* @return FlightConfiguration instance
*/
public FlightConfiguration getFlightConfigurationByIndex( int configIndex, final boolean allowDefault ) {
if( allowDefault ){

View File

@ -910,7 +910,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
/**
* Get the positioning of the component relative to its parent component.
* This is one of the enums of {@link Position}. A setter method is not provided,
* This is one of the enums of {@link AxialMethod}. A setter method is not provided,
* but can be provided by a subclass.
*/
public final AxialMethod getAxialMethod() {
@ -929,7 +929,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
*
* @param newAxialMethod the relative positioning.
*/
protected void setAxialMethod(final AxialMethod newAxialMethod) {
public void setAxialMethod(final AxialMethod newAxialMethod) {
if (newAxialMethod == this.axialMethod) {
// no change.
return;
@ -938,44 +938,32 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
// 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.axialMethod = newAxialMethod;
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
/**
* Determine position relative to given position argument. Note: This is a side-effect free method. No state
* is modified.
*
* @param outOffsetMethod the relative position to be used as the basis for the computation
* @param relativeTo the position is computed relative the the given component
* @param asMethod the relative positioning method to be used for the computation
*
* @return double position of the component relative to the parent, with respect to <code>position</code>
*/
public double asPositionValue(AxialMethod asMethod) {
public double getAxialOffset(AxialMethod asMethod) {
double parentLength = 0;
if (null != this.parent) {
parentLength = this.parent.length;
}
double result = Double.NaN;
if( AxialMethod.AFTER == asMethod) {
result = this.position.x - parentLength;
}else if( AxialMethod.ABSOLUTE == asMethod) {
result = this.getComponentLocations()[0].x;
}else if( AxialMethod.TOP == asMethod) {
result = this.position.x;
}else if( AxialMethod.MIDDLE == asMethod) {
result = this.position.x + ( this.length - parentLength) / 2;
}else if( AxialMethod.BOTTOM == asMethod) {
result = this.position.x + ( this.length - parentLength);
if(AxialMethod.ABSOLUTE == asMethod){
return this.getComponentLocations()[0].x;
}else {
throw new BugException("Unknown position type: " + asMethod.name() );
return asMethod.getAsOffset(this.position.x, this.length, parentLength);
}
return result;
}
public double getAxialOffset() {
mutex.verify();
return this.asPositionValue(this.axialMethod);
return this.axialOffset;
}
public double getRadiusOffset() {
@ -1003,7 +991,6 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
return false;
}
protected void setAfter() {
checkState();
@ -1013,87 +1000,59 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
}
// if first component in the stage. => position from the top of the parent
double newAxialPosition= 0;
final int thisIndex = this.parent.getChildPosition( this );
if( 0 < thisIndex ) {
RocketComponent referenceComponent = parent.getChild( thisIndex - 1 );
double refLength = referenceComponent.getLength();
double refRelX = referenceComponent.getPosition().x;
newAxialPosition = refRelX + refLength;
this.axialMethod = AxialMethod.AFTER;
this.axialOffset = 0.;
this.position = this.position.setX(refRelX + refLength);
}
this.position = this.position.setX( newAxialPosition );
}
/**
* Set the position value of the component. The exact meaning of the value
* depends on the current relative positioning.
* <p>
* Mince many components do not support setting the relative position. A component that does support
* it should override this with a public method that simply calls this
* supermethod AND fire a suitable ComponentChangeEvent.
*
* @param value the position value of the component.
*
* @param newOffset the position value of the component.
*/
public void setAxialOffset(double _value) {
this.setAxialOffset(this.axialMethod, _value);
public void setAxialOffset(double newOffset) {
this.setAxialOffset(this.axialMethod, newOffset);
this.fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
protected void setAxialOffset( final AxialMethod requestedMethod, double requestedOffset) {
final protected void setAxialOffset( final AxialMethod requestedMethod, final double requestedOffset) {
checkState();
AxialMethod newMethod = requestedMethod;
double newOffset = requestedOffset;
double newX = Double.NaN;
if ( this.isAfter()){
newMethod= AxialMethod.AFTER;
}
if( this instanceof Rocket ){
newMethod = AxialMethod.ABSOLUTE;
newOffset = 0.;
newX = 0.;
}else if(null == this.parent) {
if (null == this.parent) {
// best-effort approximation. this should be corrected later on in the initialization process.
newX = newOffset;
}else {
final double refLength = this.parent.getLength();
if( AxialMethod.ABSOLUTE == newMethod) {
newX = newOffset - this.parent.getComponentLocations()[0].x;
}else if( AxialMethod.AFTER == newMethod) {
newOffset = 0;
this.setAfter();
newX = this.position.x;
}else if( AxialMethod.TOP == newMethod) {
newX = newOffset;
}else if( AxialMethod.MIDDLE == newMethod) {
newX = (refLength - this.length) / 2 + newOffset;
}else if( AxialMethod.BOTTOM == newMethod) {
newX = (refLength - this.length) + newOffset;
}else{
throw new BugException("Unknown position type: " + this.axialMethod);
}
newX = requestedOffset;
} else if (AxialMethod.ABSOLUTE == requestedMethod){
// in this case, this is simply the intended result
newX = requestedOffset - this.parent.getComponentLocations()[0].x;
} else if ( this.isAfter()){
this.setAfter();
return;
} else {
newX = requestedMethod.getAsPosition(requestedOffset, this.length, this.parent.getLength());
}
// snap to zero if less than the threshold 'EPSILON'
final double EPSILON = 0.000001;
if (EPSILON > Math.abs(newX)) {
newX = 0.0;
}
if (Double.isNaN(newX)){
} else if (Double.isNaN(newX)){
throw new BugException("setAxialOffset is broken -- attempted to update as NaN: " + this.toDebugDetail());
}
this.axialMethod = newMethod;
this.axialOffset = newOffset;
// store for later:
this.axialMethod = requestedMethod;
this.axialOffset = requestedOffset;
this.position = this.position.setX( newX );
}
@ -1118,12 +1077,9 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
* For example, the absolute position of any given instance is the parent's position
* plus the instance position returned by this method
* <p>
* NOTE: this default implementation simply returns this.position
* NOTE: the length of this array returned always equals this.getInstanceCount()
*
* @param c an array of coordinates to shift.
* @return an array of shifted coordinates. The method may modify the contents
* of the passed array and return the array itself.
* @return an generated (i.e. new) array of instance locations
*/
// @Override Me !
public Coordinate[] getInstanceLocations(){
@ -1142,13 +1098,14 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
/**
* Provides locations of all instances of component relative to this component's reference point
*
*
* <p>
* NOTE: the length of this array returned always equals this.getInstanceCount()
* @return
* NOTE: default implementation just returns (0,0,0)
*
* @returns returns an array of coordinates, relative to its parent's position
*/
public Coordinate[] getInstanceOffsets(){
// According to the language specification, Java will initialized double values to 0.0
return new Coordinate[]{Coordinate.ZERO};
}
@ -1159,13 +1116,15 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
return getComponentLocations();
}
/**
* Provides locations of all instances of component *accounting for all parent instancing*
*
* <p>
* NOTE: the length of this array MAY OR MAY NOT EQUAL this.getInstanceCount()
* @return
* --> RocketComponent::getInstanceCount() counts how many times this component replicates on its own
* --> vs. the total instance count due to parent assembly instancing
*
* @return Coordinates of all instance locations in the rocket, relative to the rocket's origin
*/
public Coordinate[] getComponentLocations() {
if (null == this.parent) {
@ -1175,23 +1134,20 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
Coordinate[] parentPositions = this.parent.getComponentLocations();
int parentCount = parentPositions.length;
// override <instance>.getInstanceOffsets() in the subclass you want to fix.
Coordinate[] instanceOffsets = this.getInstanceLocations();
int instanceCount = instanceOffsets.length;
// override <instance>.getInstanceLocations() in each subclass
Coordinate[] instanceLocations = this.getInstanceLocations();
int instanceCount = instanceLocations.length;
// usual case optimization
if((1 == parentCount)&&(1 == instanceCount)){
return new Coordinate[]{parentPositions[0].add(instanceOffsets[0])};
return new Coordinate[]{parentPositions[0].add(instanceLocations[0])};
}
int thisCount = instanceCount*parentCount;
Coordinate[] thesePositions = new Coordinate[thisCount];
for (int pi = 0; pi < parentCount; pi++) {
for( int ii = 0; ii < instanceCount; ii++ ){
// System.err.println(" #"+pi+", "+ii+" = "+(pi + parentCount*ii));
// System.err.println(" "+parentPositions[pi]+" + "+instanceOffsets[ii]);
thesePositions[pi + parentCount*ii] = parentPositions[pi].add(instanceOffsets[ii]);
// System.err.println(" ="+thesePositions[pi+parentCount*ii]);
thesePositions[pi + parentCount*ii] = parentPositions[pi].add(instanceLocations[ii]);
}
}
return thesePositions;
@ -1228,17 +1184,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
mutex.unlock(lockText);
return toReturn;
}
// public Coordinate[] toAbsolute(final Coordinate[] toMove) {
// Coordinate[] toReturn = new Coordinate[toMove.length];
//
// Coordinate translation = this.getAbsolutePositionVector();
// for (int coordIndex = 0; coordIndex < toMove.length; coordIndex++) {
// toReturn[coordIndex] = translation.add(toMove[coordIndex]);
// }
// return toReturn;
// }
/**
* Return coordinate <code>c</code> described in the coordinate system of
* <code>dest</code>. If <code>dest</code> is <code>null</code> returns

View File

@ -31,9 +31,9 @@ public enum AxialMethod implements DistanceMethod {
@Override
public double getAsOffset(double position, double innerLength, double outerLength){
return outerLength - position;
return position - outerLength;
}
},
},
// measure from the top of the target component to the top of the subject component
TOP (Application.getTranslator().get("RocketComponent.Position.Method.Axial.TOP")){
@ -60,7 +60,7 @@ public enum AxialMethod implements DistanceMethod {
@Override
public double getAsPosition(double offset, double innerLength, double outerLength){
return (outerLength - innerLength) / 2 - offset;
return offset + (outerLength - innerLength) / 2;
}
@Override
@ -76,7 +76,7 @@ public enum AxialMethod implements DistanceMethod {
@Override
public double getAsPosition(double offset, double innerLength, double outerLength){
return outerLength - innerLength - offset;
return offset + (outerLength - innerLength);
}
@Override

View File

@ -9,7 +9,6 @@ import net.sf.openrocket.file.simplesax.PlainTextHandler;
import net.sf.openrocket.material.Material;
import net.sf.openrocket.rocketcomponent.BodyTube;
import net.sf.openrocket.rocketcomponent.InnerTube;
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
import org.junit.Assert;
@ -118,20 +117,6 @@ public class InnerBodyTubeHandlerTest extends RocksimTestBase {
handler.closeElement("Name", attributes, "Test Name", warnings);
Assert.assertEquals("Test Name", component.getName());
}
/**
* Method: setRelativePosition(AxialMethod position)
*
* @throws Exception thrown if something goes awry
*/
@org.junit.Test
public void testSetRelativePosition() throws Exception {
BodyTube tube = new BodyTube();
InnerBodyTubeHandler handler = new InnerBodyTubeHandler(null, tube, new WarningSet());
InnerTube component = (InnerTube) getField(handler, "bodyTube");
handler.setAxialMethod(AxialMethod.ABSOLUTE);
Assert.assertEquals(AxialMethod.ABSOLUTE, component.getAxialMethod());
}
/**
* Method: getComponent()

View File

@ -10,7 +10,6 @@ import net.sf.openrocket.material.Material;
import net.sf.openrocket.rocketcomponent.BodyTube;
import net.sf.openrocket.rocketcomponent.ExternalComponent;
import net.sf.openrocket.rocketcomponent.LaunchLug;
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
import org.junit.Assert;
@ -109,20 +108,6 @@ public class LaunchLugHandlerTest extends RocksimTestBase {
handler.closeElement("Name", attributes, "Test Name", warnings);
Assert.assertEquals("Test Name", component.getName());
}
/**
* Method: setRelativePosition(AxialMethod position)
*
* @throws Exception thrown if something goes awry
*/
@org.junit.Test
public void testSetRelativePosition() throws Exception {
BodyTube tube = new BodyTube();
LaunchLugHandler handler = new LaunchLugHandler(null, tube, new WarningSet());
LaunchLug component = (LaunchLug) getField(handler, "lug");
handler.setAxialMethod(AxialMethod.ABSOLUTE);
Assert.assertEquals(AxialMethod.ABSOLUTE, component.getAxialMethod());
}
/**
* Method: getComponent()

View File

@ -9,7 +9,6 @@ import net.sf.openrocket.file.simplesax.PlainTextHandler;
import net.sf.openrocket.material.Material;
import net.sf.openrocket.rocketcomponent.BodyTube;
import net.sf.openrocket.rocketcomponent.MassComponent;
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
import org.junit.Assert;
@ -90,20 +89,6 @@ public class MassObjectHandlerTest extends RocksimTestBase {
warnings.clear();
}
/**
* Method: setRelativePosition(AxialMethod position)
*
* @throws Exception thrown if something goes awry
*/
@org.junit.Test
public void testSetRelativePosition() throws Exception {
BodyTube tube = new BodyTube();
MassObjectHandler handler = new MassObjectHandler(null, tube, new WarningSet());
MassComponent component = (MassComponent) getField(handler, "mass");
handler.setAxialMethod(AxialMethod.ABSOLUTE);
Assert.assertEquals(AxialMethod.ABSOLUTE, component.getAxialMethod());
}
/**
* Method: getComponent()

View File

@ -113,7 +113,7 @@ public class ParachuteHandlerTest extends RocksimTestBase {
BodyTube tube = new BodyTube();
ParachuteHandler handler = new ParachuteHandler(null, tube, new WarningSet());
Parachute component = (Parachute) getField(handler, "chute");
handler.setAxialMethod(AxialMethod.ABSOLUTE);
handler.getComponent().setAxialMethod(AxialMethod.ABSOLUTE);
Assert.assertEquals(AxialMethod.ABSOLUTE, component.getAxialMethod());
}

View File

@ -246,21 +246,6 @@ public class RingHandlerTest extends RocksimTestBase {
@SuppressWarnings("unused")
CenteringRing component = (CenteringRing) getField(handler, "ring");
}
/**
* Method: setAxialMethod(AxialMethod position)
*
* @throws Exception thrown if something goes awry
*/
@org.junit.Test
public void testsetAxialMethod() throws Exception {
BodyTube tube = new BodyTube();
RingHandler handler = new RingHandler(null, tube, new WarningSet());
CenteringRing component = (CenteringRing) getField(handler, "ring");
handler.setAxialMethod(AxialMethod.ABSOLUTE);
Assert.assertEquals(AxialMethod.ABSOLUTE, component.getAxialMethod());
}
/**
* Method: getComponent()

View File

@ -109,7 +109,7 @@ public class StreamerHandlerTest extends RocksimTestBase {
BodyTube tube = new BodyTube();
StreamerHandler handler = new StreamerHandler(null, tube, new WarningSet());
Streamer component = (Streamer) getField(handler, "streamer");
handler.setAxialMethod(AxialMethod.ABSOLUTE);
handler.getComponent().setAxialMethod(AxialMethod.ABSOLUTE);
Assert.assertEquals(AxialMethod.ABSOLUTE, component.getAxialMethod());
}

View File

@ -2,8 +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 static org.junit.Assert.*;
import org.junit.Test;
@ -18,20 +17,15 @@ public class ParallelStageTest extends BaseTestCase {
// tolerance for compared double test results
protected final double EPSILON = 0.000001;
protected final Coordinate ZERO = new Coordinate(0., 0., 0.);
/* From OpenRocket Technical Documentation
*
* 3.1.4 Coordinate systems
* During calculation of the aerodynamic properties a coordinate system fixed to the rocket will be used.
* The origin of the coordinates is at the nose cone tip with the positive x-axis directed along the rocket
@@ -41,70 +35,302 @@ public class BodyTubeTest extends TestCase {
* when discussing the fins. During simulation, however, the y- and z-axes are fixed in relation to the rocket,
* when discussing the fins. During simulation, however, the y- and z-axes are fixed in relation to the rocket,
* and do not necessarily align with the plane of the pitching moments.
*/
public ParallelStage createExtraBooster() {
double tubeRadius = 0.8;
@ -60,7 +54,7 @@ public class ParallelStageTest extends BaseTestCase {
@Test
public void testSetRocketPositionFail() {
final Rocket rocket = TestRockets.makeFalcon9Heavy();
// case 1: the rocket Rocket should be stationary
rocket.setAxialOffset( +4.8 );
@ -106,10 +100,10 @@ public class ParallelStageTest extends BaseTestCase {
// WARNING: this test will not pass unless 'testAddTopStage' is passing as well -- that function tests the dependencies...
@Test
public void testCreateCoreStage() {
// 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
final Rocket rocket = TestRockets.makeFalcon9Heavy();
// ^^^^ function under test ^^^^
// Payload Stage
AxialStage payloadStage = (AxialStage)rocket.getChild(0);
final double expectedPayloadLength = 0.564;
@ -195,7 +189,7 @@ public class ParallelStageTest extends BaseTestCase {
assertThat(" 'setInstancecount(int)' failed: ", 2, equalTo(parallelBoosterSet.getInstanceCount()));
assertEquals( RadiusMethod.FREE.clampToZero(), false );
assertFalse( RadiusMethod.FREE.clampToZero());
assertEquals(" error while setting radius method: ", RadiusMethod.FREE, parallelBoosterSet.getRadiusMethod() );
assertEquals(" error while setting radius offset: ", 2.0, parallelBoosterSet.getRadiusOffset(), EPSILON);
@ -220,7 +214,7 @@ public class ParallelStageTest extends BaseTestCase {
assertThat(" 'setInstancecount(int)' failed: ", 2, equalTo(parallelBoosterStage.getInstanceCount()));
assertEquals( RadiusMethod.SURFACE.clampToZero(), true );
assertTrue( RadiusMethod.SURFACE.clampToZero());
assertEquals(" error while setting radius method: ", RadiusMethod.SURFACE, parallelBoosterStage.getRadiusMethod() );
assertEquals(" error while setting radius offset: ", 0.0, parallelBoosterStage.getRadiusOffset(), EPSILON);
@ -260,7 +254,7 @@ public class ParallelStageTest extends BaseTestCase {
parallelBoosterStage.setRadius( RadiusMethod.RELATIVE, targetRadiusOffset );
// ^^ function under test
assertEquals( RadiusMethod.RELATIVE.clampToZero(), false );
assertFalse(RadiusMethod.RELATIVE.clampToZero());
assertEquals(" error while setting radius method: ", RadiusMethod.RELATIVE, parallelBoosterStage.getRadiusMethod() );
assertEquals(" error while setting radius offset: ", targetRadiusOffset, parallelBoosterStage.getRadiusOffset() , EPSILON);
@ -332,16 +326,16 @@ public class ParallelStageTest extends BaseTestCase {
double targetAbsoluteX = 0.8;
double expectedRelativeX = 0.236;
double expectedAbsoluteX = 0.8;
// when subStages should be freely movable
// when substages should be freely movable
// vv function under test
boosterStage.setAxialOffset(AxialMethod.ABSOLUTE, targetAbsoluteX);
// ^^ function under test
assertEquals("setAxialOffset( method, double) failed: ", AxialMethod.ABSOLUTE, boosterStage.getAxialMethod() );
assertEquals("setAxialOffset( method, double) failed: ", targetAbsoluteX, boosterStage.getAxialOffset(), EPSILON );
double actualRelativeX = boosterStage.asPositionValue(AxialMethod.TOP);
double actualRelativeX = boosterStage.getAxialOffset(AxialMethod.TOP);
assertEquals(" 'setAxialPosition(double)' failed: Relative position: ", expectedRelativeX, actualRelativeX, EPSILON );
double actualAbsoluteX = boosterStage.getComponentLocations()[0].x;
@ -410,7 +404,7 @@ public class ParallelStageTest extends BaseTestCase {
final RocketComponent rocket = TestRockets.makeFalcon9Heavy();
final AxialStage coreStage = (AxialStage) rocket.getChild(1);
final ParallelStage boosterStage = (ParallelStage)coreStage.getChild(0).getChild(0);
// when 'external' the stage should be freely movable
// vv function under test
double targetOffset = 0.2;
@ -418,11 +412,10 @@ public class ParallelStageTest extends BaseTestCase {
// ^^ function under test
Assert.assertEquals( targetOffset, boosterStage.getAxialOffset(), EPSILON );
Assert.assertEquals( 0.16, boosterStage.getPosition().x, EPSILON );
Assert.assertEquals( 0.724, boosterStage.getComponentLocations()[0].x, EPSILON );
}
@Test
@ -456,14 +449,14 @@ public class ParallelStageTest extends BaseTestCase {
// ^^ function under test
Assert.assertEquals( targetOffset, boosterStage.getAxialOffset(), EPSILON );
Assert.assertEquals( 0.2, boosterStage.getPosition().x, EPSILON );
Assert.assertEquals( targetOffset, boosterStage.getPosition().x, EPSILON );
final double expectedRelativePositionX = targetOffset;
final double expectedRelativePositionX = 0.2;
final double resultantRelativePosition = boosterStage.getPosition().x;
Assert.assertEquals(expectedRelativePositionX, resultantRelativePosition, EPSILON);
// vv function under test
final double actualAbsoluteX = boosterStage.asPositionValue(AxialMethod.ABSOLUTE);
final double actualAbsoluteX = boosterStage.getAxialOffset(AxialMethod.ABSOLUTE);
// ^^ function under test
Assert.assertEquals( 0.764, actualAbsoluteX, EPSILON );
@ -486,7 +479,7 @@ public class ParallelStageTest extends BaseTestCase {
// vv function under test
double actualPositionXAfter = boosterStage.asPositionValue(AxialMethod.AFTER);
double actualPositionXAfter = boosterStage.getAxialOffset(AxialMethod.AFTER);
// ^^ function under test
Assert.assertEquals( -0.6, actualPositionXAfter, EPSILON );
@ -508,7 +501,7 @@ public class ParallelStageTest extends BaseTestCase {
Assert.assertEquals( 0.2, boosterStage.getPosition().x, EPSILON );
// vv function under test
final double actualAxialPosition = boosterStage.asPositionValue(AxialMethod.MIDDLE);
final double actualAxialPosition = boosterStage.getAxialOffset(AxialMethod.MIDDLE);
// ^^ function under test
Assert.assertEquals( 0.24, actualAxialPosition, EPSILON );
@ -530,7 +523,7 @@ public class ParallelStageTest extends BaseTestCase {
Assert.assertEquals( 0.2, boosterStage.getPosition().x, EPSILON );
// vv function under test
double actualAxialBottomOffset = boosterStage.asPositionValue(AxialMethod.BOTTOM);
double actualAxialBottomOffset = boosterStage.getAxialOffset(AxialMethod.BOTTOM);
// ^^ function under test
Assert.assertEquals( 0.28, actualAxialBottomOffset, EPSILON );
@ -552,7 +545,7 @@ public class ParallelStageTest extends BaseTestCase {
Assert.assertEquals( 0.120, boosterStage.getPosition().x, EPSILON);
// vv function under test
double actualAxialTopOffset = boosterStage.asPositionValue(AxialMethod.TOP);
double actualAxialTopOffset = boosterStage.getAxialOffset(AxialMethod.TOP);
// ^^ function under test
Assert.assertEquals( 0.12, actualAxialTopOffset, EPSILON);

View File

@ -257,7 +257,7 @@ public abstract class FinSetConfig extends RocketComponentConfig {
if (!rings.isEmpty()) {
AxialMethod temp = (AxialMethod) em.getSelectedItem();
em.setSelectedItem(AxialMethod.TOP);
double len = computeFinTabLength(rings, component.asPositionValue(AxialMethod.TOP),
double len = computeFinTabLength(rings, component.getAxialOffset(AxialMethod.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.
@ -306,8 +306,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(AxialMethod.TOP) -
centeringRing1.asPositionValue(AxialMethod.TOP)));
return (int) (1000d * (centeringRing.getAxialOffset(AxialMethod.TOP) -
centeringRing1.getAxialOffset(AxialMethod.TOP)));
}
});
@ -316,7 +316,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(AxialMethod.TOP)) {
centeringRing.getAxialOffset(AxialMethod.TOP)) {
SortableRing adjacent = positionsFromTop.get(positionsFromTop.size() - 1);
adjacent.merge(centeringRing, relativeTo);
} else {
@ -441,7 +441,7 @@ public abstract class FinSetConfig extends RocketComponentConfig {
*/
SortableRing(CenteringRing r, RocketComponent relativeTo) {
thickness = r.getLength();
positionFromTop = r.asPositionValue(AxialMethod.TOP);
positionFromTop = r.getAxialOffset(AxialMethod.TOP);
}
/**
@ -450,7 +450,7 @@ public abstract class FinSetConfig extends RocketComponentConfig {
* @param adjacent the adjacent ring
*/
public void merge(CenteringRing adjacent, RocketComponent relativeTo) {
double v = adjacent.asPositionValue(AxialMethod.TOP);
double v = adjacent.getAxialOffset(AxialMethod.TOP);
if (positionFromTop < v) {
thickness = (v + adjacent.getLength()) - positionFromTop;
} else {

View File

@ -87,8 +87,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( AxialMethod.ABSOLUTE);
final double mmTopPosition = two.asPositionValue( AxialMethod.ABSOLUTE);
final double crTopPosition = one.getAxialOffset( AxialMethod.ABSOLUTE);
final double mmTopPosition = two.getAxialOffset( AxialMethod.ABSOLUTE);
final double crBottomPosition = one.getLength() + crTopPosition;
final double mmBottomPosition = two.getLength() + mmTopPosition;

View File

@ -159,7 +159,7 @@ public class FinPointFigure extends AbstractScaleFigure {
Transition body = (Transition) finset.getParent();
final float xResolution_m = 0.01f; // distance between draw points, in meters
final double xFinStart = finset.asPositionValue(AxialMethod.TOP); //<< in body frame
final double xFinStart = finset.getAxialOffset(AxialMethod.TOP); //<< in body frame
// vv in fin-frame == draw-frame vv
final double xOffset = -xFinStart;
@ -355,7 +355,7 @@ public class FinPointFigure extends AbstractScaleFigure {
// update to bound the parent body:
SymmetricComponent parent = (SymmetricComponent)this.finset.getParent();
final double xFinFront = finset.asPositionValue(AxialMethod.TOP);
final double xFinFront = finset.getAxialOffset(AxialMethod.TOP);
final double xParent = -xFinFront;
final double yParent = -parent.getRadius(xParent); // from parent centerline to fin front.
final double rParent = Math.max(parent.getForeRadius(), parent.getAftRadius());