[refactor] RocketComponent positioning is now centralized in AxialMethod class
- also relaxed visibility for Component::setAxialMethod(...)
This commit is contained in:
parent
7d813b4e55
commit
b268d3aa59
@ -325,7 +325,8 @@ class FinSetHandler extends AbstractElementHandler {
|
|||||||
result.setBaseRotation(radialAngle);
|
result.setBaseRotation(radialAngle);
|
||||||
result.setCrossSection(convertTipShapeCode(tipShapeCode));
|
result.setCrossSection(convertTipShapeCode(tipShapeCode));
|
||||||
result.setAxialMethod(axialMethod);
|
result.setAxialMethod(axialMethod);
|
||||||
PositionDependentHandler.setLocation(result, axialMethod, location);
|
result.setAxialOffset(location);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,6 @@ import net.sf.openrocket.file.simplesax.PlainTextHandler;
|
|||||||
import net.sf.openrocket.material.Material;
|
import net.sf.openrocket.material.Material;
|
||||||
import net.sf.openrocket.rocketcomponent.InnerTube;
|
import net.sf.openrocket.rocketcomponent.InnerTube;
|
||||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A SAX handler for Rocksim inside tubes.
|
* A SAX handler for Rocksim inside tubes.
|
||||||
@ -99,17 +98,6 @@ class InnerBodyTubeHandler extends PositionDependentHandler<InnerTube> {
|
|||||||
return bodyTube;
|
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.
|
* Get the required type of material for this component.
|
||||||
*
|
*
|
||||||
|
@ -16,7 +16,6 @@ import net.sf.openrocket.file.simplesax.PlainTextHandler;
|
|||||||
import net.sf.openrocket.material.Material;
|
import net.sf.openrocket.material.Material;
|
||||||
import net.sf.openrocket.rocketcomponent.LaunchLug;
|
import net.sf.openrocket.rocketcomponent.LaunchLug;
|
||||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The SAX handler for Rocksim Launch Lugs.
|
* The SAX handler for Rocksim Launch Lugs.
|
||||||
@ -91,17 +90,6 @@ class LaunchLugHandler extends PositionDependentHandler<LaunchLug> {
|
|||||||
return lug;
|
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.
|
* Get the required type of material for this component.
|
||||||
*
|
*
|
||||||
|
@ -17,7 +17,6 @@ import net.sf.openrocket.rocketcomponent.MassComponent;
|
|||||||
import net.sf.openrocket.rocketcomponent.MassObject;
|
import net.sf.openrocket.rocketcomponent.MassObject;
|
||||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
import net.sf.openrocket.rocketcomponent.ShockCord;
|
import net.sf.openrocket.rocketcomponent.ShockCord;
|
||||||
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
|
|
||||||
|
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
@ -184,17 +183,6 @@ class MassObjectHandler extends PositionDependentHandler<MassObject> {
|
|||||||
return current;
|
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
|
* Get the required type of material for this component. Does not apply to MassComponents, but does apply to Shock
|
||||||
* Cords.
|
* Cords.
|
||||||
|
@ -15,18 +15,18 @@ import net.sf.openrocket.rocketcomponent.position.AxialMethod;
|
|||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An abstract base class that handles position dependencies for all lower level components that
|
* An abstract base class that handles axialMethod dependencies for all lower level components that
|
||||||
* are position aware.
|
* 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> {
|
public abstract class PositionDependentHandler<C extends RocketComponent> extends BaseHandler<C> {
|
||||||
|
|
||||||
/** Temporary position value. */
|
/** Temporary axialMethod value. */
|
||||||
private Double positionValue = 0d;
|
private Double positionValue = 0d;
|
||||||
|
|
||||||
/** Temporary position. */
|
/** Temporary axialMethod. */
|
||||||
private AxialMethod position = AxialMethod.TOP;
|
private AxialMethod axialMethod = AxialMethod.TOP;
|
||||||
|
|
||||||
public PositionDependentHandler(DocumentLoadingContext context) {
|
public PositionDependentHandler(DocumentLoadingContext context) {
|
||||||
super(context);
|
super(context);
|
||||||
@ -43,15 +43,15 @@ public abstract class PositionDependentHandler<C extends RocketComponent> extend
|
|||||||
positionValue = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH;
|
positionValue = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH;
|
||||||
}
|
}
|
||||||
if (RocksimCommonConstants.LOCATION_MODE.equals(element)) {
|
if (RocksimCommonConstants.LOCATION_MODE.equals(element)) {
|
||||||
position = RocksimLocationMode.fromCode(Integer.parseInt(
|
axialMethod = RocksimLocationMode.fromCode(Integer.parseInt(
|
||||||
content)).asOpenRocket();
|
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
|
* 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 element the element name
|
||||||
* @param attributes the attributes
|
* @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,
|
public void endHandler(String element, HashMap<String, String> attributes,
|
||||||
String content, WarningSet warnings) throws SAXException {
|
String content, WarningSet warnings) throws SAXException {
|
||||||
super.endHandler(element, attributes, content, warnings);
|
super.endHandler(element, attributes, content, warnings);
|
||||||
setAxialMethod(position);
|
setLocation();
|
||||||
setLocation(getComponent(), position, positionValue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the relative position onto the component. This cannot be done directly because setRelativePosition is not
|
* Set the axialMethod of a component.
|
||||||
* public in all components.
|
|
||||||
*
|
|
||||||
* @param position the OpenRocket position
|
|
||||||
*/
|
*/
|
||||||
protected abstract void setAxialMethod(AxialMethod position);
|
protected void setLocation() {
|
||||||
|
getComponent().setAxialMethod(axialMethod);
|
||||||
/**
|
if (axialMethod.equals(AxialMethod.BOTTOM)) {
|
||||||
* Set the position of a component.
|
getComponent().setAxialOffset(-1d * positionValue);
|
||||||
*
|
} else {
|
||||||
* @param component the component
|
getComponent().setAxialOffset(positionValue);
|
||||||
* @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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@ import net.sf.openrocket.file.rocksim.RocksimCommonConstants;
|
|||||||
import net.sf.openrocket.file.rocksim.RocksimDensityType;
|
import net.sf.openrocket.file.rocksim.RocksimDensityType;
|
||||||
import net.sf.openrocket.material.Material;
|
import net.sf.openrocket.material.Material;
|
||||||
import net.sf.openrocket.rocketcomponent.RecoveryDevice;
|
import net.sf.openrocket.rocketcomponent.RecoveryDevice;
|
||||||
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
|
|
||||||
|
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
@ -96,17 +95,6 @@ public abstract class RecoveryDeviceHandler<C extends RecoveryDevice> extends Po
|
|||||||
return result;
|
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
|
* 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
|
* correspond to Rocksim. Some streamer material is defined as BULK in the Rocksim file. In those cases
|
||||||
|
@ -19,7 +19,6 @@ import net.sf.openrocket.rocketcomponent.EngineBlock;
|
|||||||
import net.sf.openrocket.rocketcomponent.RingComponent;
|
import net.sf.openrocket.rocketcomponent.RingComponent;
|
||||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
import net.sf.openrocket.rocketcomponent.TubeCoupler;
|
import net.sf.openrocket.rocketcomponent.TubeCoupler;
|
||||||
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A SAX handler for centering rings, tube couplers, and bulkheads.
|
* A SAX handler for centering rings, tube couplers, and bulkheads.
|
||||||
@ -180,17 +179,6 @@ class RingHandler extends PositionDependentHandler<CenteringRing> {
|
|||||||
result.setThickness(result.getThickness());
|
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
|
@Override
|
||||||
public void endHandler(String element, HashMap<String, String> attributes, String content, WarningSet warnings) throws SAXException {
|
public void endHandler(String element, HashMap<String, String> attributes, String content, WarningSet warnings) throws SAXException {
|
||||||
super.endHandler(element, attributes, content, warnings);
|
super.endHandler(element, attributes, content, warnings);
|
||||||
|
@ -9,7 +9,6 @@ import net.sf.openrocket.file.simplesax.PlainTextHandler;
|
|||||||
import net.sf.openrocket.material.Material;
|
import net.sf.openrocket.material.Material;
|
||||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
import net.sf.openrocket.rocketcomponent.TubeFinSet;
|
import net.sf.openrocket.rocketcomponent.TubeFinSet;
|
||||||
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
|
|
||||||
|
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
@ -44,17 +43,6 @@ public class TubeFinSetHandler extends PositionDependentHandler<TubeFinSet> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the relative position onto the component.
|
|
||||||
*
|
|
||||||
* @param position the OpenRocket position
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected void setAxialMethod(final AxialMethod position) {
|
|
||||||
tubeFin.setAxialMethod(position);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the OR instance after the XML parsing is done.
|
* Get the OR instance after the XML parsing is done.
|
||||||
*
|
*
|
||||||
|
@ -33,6 +33,10 @@ public abstract class ComponentAssembly extends RocketComponent implements Axia
|
|||||||
super( AxialMethod.AFTER);
|
super( AxialMethod.AFTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ComponentAssembly( final AxialMethod initialAxialMethod) {
|
||||||
|
super(initialAxialMethod);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean allowsChildren(){
|
public boolean allowsChildren(){
|
||||||
return true;
|
return true;
|
||||||
@ -40,7 +44,7 @@ public abstract class ComponentAssembly extends RocketComponent implements Axia
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getAxialOffset() {
|
public double getAxialOffset() {
|
||||||
return asPositionValue( this.axialMethod );
|
return getAxialOffset( this.axialMethod );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -476,7 +476,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
|||||||
* Copy all available information attached to this, and attached copies to the
|
* Copy all available information attached to this, and attached copies to the
|
||||||
* new configuration
|
* new configuration
|
||||||
*
|
*
|
||||||
* @param copyId attached the new configuration to this Id
|
* @param newId attached the new configuration to this Id
|
||||||
* @return the new configuration
|
* @return the new configuration
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@ -21,7 +21,7 @@ public class LaunchLug extends ExternalComponent implements AnglePositionable, C
|
|||||||
private double thickness;
|
private double thickness;
|
||||||
|
|
||||||
private double radialDirection = 0;
|
private double radialDirection = 0;
|
||||||
protected double radialDistance = 0;
|
private double radialDistance = 0;
|
||||||
|
|
||||||
private int instanceCount = 1;
|
private int instanceCount = 1;
|
||||||
private double instanceSeparation = 0; // front-front along the positive rocket axis. i.e. [1,0,0];
|
private double instanceSeparation = 0; // front-front along the positive rocket axis. i.e. [1,0,0];
|
||||||
@ -99,14 +99,6 @@ public class LaunchLug extends ExternalComponent implements AnglePositionable, C
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setAxialMethod( AxialMethod position) {
|
|
||||||
super.setAxialMethod(position);
|
|
||||||
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void loadFromPreset(ComponentPreset preset) {
|
protected void loadFromPreset(ComponentPreset preset) {
|
||||||
if (preset.has(ComponentPreset.OUTER_DIAMETER)) {
|
if (preset.has(ComponentPreset.OUTER_DIAMETER)) {
|
||||||
|
@ -157,7 +157,7 @@ public class PodSet extends ComponentAssembly implements RingInstanceable {
|
|||||||
// remember the implicit (this instanceof Stage)
|
// 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() );
|
throw new BugException("found a pod positioned via: AFTER, but is not on the centerline?!: " + this.getName() + " is " + this.getAxialMethod().name() );
|
||||||
} else {
|
} else {
|
||||||
returnValue = super.asPositionValue(this.axialMethod);
|
returnValue = super.getAxialOffset(this.axialMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0.000001 > Math.abs(returnValue)) {
|
if (0.000001 > Math.abs(returnValue)) {
|
||||||
|
@ -11,8 +11,10 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import net.sf.openrocket.l10n.Translator;
|
import net.sf.openrocket.l10n.Translator;
|
||||||
|
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
|
||||||
import net.sf.openrocket.startup.Application;
|
import net.sf.openrocket.startup.Application;
|
||||||
import net.sf.openrocket.util.ArrayList;
|
import net.sf.openrocket.util.ArrayList;
|
||||||
|
import net.sf.openrocket.util.Coordinate;
|
||||||
import net.sf.openrocket.util.MathUtil;
|
import net.sf.openrocket.util.MathUtil;
|
||||||
import net.sf.openrocket.util.StateChangeListener;
|
import net.sf.openrocket.util.StateChangeListener;
|
||||||
import net.sf.openrocket.util.UniqueID;
|
import net.sf.openrocket.util.UniqueID;
|
||||||
@ -74,6 +76,7 @@ public class Rocket extends ComponentAssembly {
|
|||||||
///////////// Constructor /////////////
|
///////////// Constructor /////////////
|
||||||
|
|
||||||
public Rocket() {
|
public Rocket() {
|
||||||
|
super(AxialMethod.ABSOLUTE);
|
||||||
modID = UniqueID.next();
|
modID = UniqueID.next();
|
||||||
massModID = modID;
|
massModID = modID;
|
||||||
aeroModID = modID;
|
aeroModID = modID;
|
||||||
@ -245,6 +248,17 @@ public class Rocket extends ComponentAssembly {
|
|||||||
this.stageMap.remove(oldStage.getStageNumber());
|
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() {
|
public ReferenceType getReferenceType() {
|
||||||
checkState();
|
checkState();
|
||||||
return refType;
|
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.
|
* 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.
|
* 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
|
* @param configIndex The flight configuration index number
|
||||||
* @return a FlightConfiguration instance
|
* @return FlightConfiguration instance
|
||||||
*/
|
*/
|
||||||
public FlightConfiguration getFlightConfigurationByIndex( int configIndex, final boolean allowDefault ) {
|
public FlightConfiguration getFlightConfigurationByIndex( int configIndex, final boolean allowDefault ) {
|
||||||
if( allowDefault ){
|
if( allowDefault ){
|
||||||
|
@ -910,7 +910,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the positioning of the component relative to its parent component.
|
* 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.
|
* but can be provided by a subclass.
|
||||||
*/
|
*/
|
||||||
public final AxialMethod getAxialMethod() {
|
public final AxialMethod getAxialMethod() {
|
||||||
@ -929,7 +929,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
|||||||
*
|
*
|
||||||
* @param newAxialMethod the relative positioning.
|
* @param newAxialMethod the relative positioning.
|
||||||
*/
|
*/
|
||||||
protected void setAxialMethod(final AxialMethod newAxialMethod) {
|
public void setAxialMethod(final AxialMethod newAxialMethod) {
|
||||||
if (newAxialMethod == this.axialMethod) {
|
if (newAxialMethod == this.axialMethod) {
|
||||||
// no change.
|
// no change.
|
||||||
return;
|
return;
|
||||||
@ -938,44 +938,32 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
|||||||
// this variable does not change the internal representation
|
// 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.
|
// the relativePosition (method) is just the lens through which external code may view this component's position.
|
||||||
this.axialMethod = newAxialMethod;
|
this.axialMethod = newAxialMethod;
|
||||||
|
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine position relative to given position argument. Note: This is a side-effect free method. No state
|
* Determine position relative to given position argument. Note: This is a side-effect free method. No state
|
||||||
* is modified.
|
* is modified.
|
||||||
*
|
*
|
||||||
* @param outOffsetMethod the relative position to be used as the basis for the computation
|
* @param asMethod the relative positioning method to be used for the computation
|
||||||
* @param relativeTo the position is computed relative the the given component
|
|
||||||
*
|
*
|
||||||
* @return double position of the component relative to the parent, with respect to <code>position</code>
|
* @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;
|
double parentLength = 0;
|
||||||
if (null != this.parent) {
|
if (null != this.parent) {
|
||||||
parentLength = this.parent.length;
|
parentLength = this.parent.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
double result = Double.NaN;
|
if(AxialMethod.ABSOLUTE == asMethod){
|
||||||
if( AxialMethod.AFTER == asMethod) {
|
return this.getComponentLocations()[0].x;
|
||||||
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);
|
|
||||||
}else {
|
}else {
|
||||||
throw new BugException("Unknown position type: " + asMethod.name() );
|
return asMethod.getAsOffset(this.position.x, this.length, parentLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getAxialOffset() {
|
public double getAxialOffset() {
|
||||||
mutex.verify();
|
return this.axialOffset;
|
||||||
return this.asPositionValue(this.axialMethod);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getRadiusOffset() {
|
public double getRadiusOffset() {
|
||||||
@ -1003,7 +991,6 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void setAfter() {
|
protected void setAfter() {
|
||||||
checkState();
|
checkState();
|
||||||
|
|
||||||
@ -1013,8 +1000,6 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if first component in the stage. => position from the top of the parent
|
// if first component in the stage. => position from the top of the parent
|
||||||
double newAxialPosition= 0;
|
|
||||||
|
|
||||||
final int thisIndex = this.parent.getChildPosition( this );
|
final int thisIndex = this.parent.getChildPosition( this );
|
||||||
if( 0 < thisIndex ) {
|
if( 0 < thisIndex ) {
|
||||||
RocketComponent referenceComponent = parent.getChild( thisIndex - 1 );
|
RocketComponent referenceComponent = parent.getChild( thisIndex - 1 );
|
||||||
@ -1022,78 +1007,52 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
|||||||
double refLength = referenceComponent.getLength();
|
double refLength = referenceComponent.getLength();
|
||||||
double refRelX = referenceComponent.getPosition().x;
|
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
|
* Set the position value of the component. The exact meaning of the value
|
||||||
* depends on the current relative positioning.
|
* 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) {
|
public void setAxialOffset(double newOffset) {
|
||||||
this.setAxialOffset(this.axialMethod, _value);
|
this.setAxialOffset(this.axialMethod, newOffset);
|
||||||
this.fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
|
this.fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final protected void setAxialOffset( final AxialMethod requestedMethod, final double requestedOffset) {
|
||||||
protected void setAxialOffset( final AxialMethod requestedMethod, double requestedOffset) {
|
|
||||||
checkState();
|
checkState();
|
||||||
|
|
||||||
AxialMethod newMethod = requestedMethod;
|
|
||||||
double newOffset = requestedOffset;
|
|
||||||
double newX = Double.NaN;
|
double newX = Double.NaN;
|
||||||
|
|
||||||
if ( this.isAfter()){
|
if (null == this.parent) {
|
||||||
newMethod= AxialMethod.AFTER;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if( this instanceof Rocket ){
|
|
||||||
newMethod = AxialMethod.ABSOLUTE;
|
|
||||||
newOffset = 0.;
|
|
||||||
newX = 0.;
|
|
||||||
}else if(null == this.parent) {
|
|
||||||
// best-effort approximation. this should be corrected later on in the initialization process.
|
// best-effort approximation. this should be corrected later on in the initialization process.
|
||||||
newX = newOffset;
|
newX = requestedOffset;
|
||||||
}else {
|
} else if (AxialMethod.ABSOLUTE == requestedMethod){
|
||||||
final double refLength = this.parent.getLength();
|
// in this case, this is simply the intended result
|
||||||
|
newX = requestedOffset - this.parent.getComponentLocations()[0].x;
|
||||||
if( AxialMethod.ABSOLUTE == newMethod) {
|
} else if ( this.isAfter()){
|
||||||
newX = newOffset - this.parent.getComponentLocations()[0].x;
|
|
||||||
}else if( AxialMethod.AFTER == newMethod) {
|
|
||||||
newOffset = 0;
|
|
||||||
this.setAfter();
|
this.setAfter();
|
||||||
newX = this.position.x;
|
return;
|
||||||
}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 {
|
} else {
|
||||||
throw new BugException("Unknown position type: " + this.axialMethod);
|
newX = requestedMethod.getAsPosition(requestedOffset, this.length, this.parent.getLength());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// snap to zero if less than the threshold 'EPSILON'
|
// snap to zero if less than the threshold 'EPSILON'
|
||||||
final double EPSILON = 0.000001;
|
final double EPSILON = 0.000001;
|
||||||
if (EPSILON > Math.abs(newX)) {
|
if (EPSILON > Math.abs(newX)) {
|
||||||
newX = 0.0;
|
newX = 0.0;
|
||||||
}
|
} else if (Double.isNaN(newX)){
|
||||||
if (Double.isNaN(newX)){
|
|
||||||
throw new BugException("setAxialOffset is broken -- attempted to update as NaN: " + this.toDebugDetail());
|
throw new BugException("setAxialOffset is broken -- attempted to update as NaN: " + this.toDebugDetail());
|
||||||
}
|
}
|
||||||
|
|
||||||
this.axialMethod = newMethod;
|
// store for later:
|
||||||
this.axialOffset = newOffset;
|
this.axialMethod = requestedMethod;
|
||||||
|
this.axialOffset = requestedOffset;
|
||||||
this.position = this.position.setX( newX );
|
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
|
* For example, the absolute position of any given instance is the parent's position
|
||||||
* plus the instance position returned by this method
|
* plus the instance position returned by this method
|
||||||
* <p>
|
* <p>
|
||||||
* NOTE: this default implementation simply returns this.position
|
|
||||||
* NOTE: the length of this array returned always equals this.getInstanceCount()
|
* NOTE: the length of this array returned always equals this.getInstanceCount()
|
||||||
*
|
*
|
||||||
* @param c an array of coordinates to shift.
|
* @return an generated (i.e. new) array of instance locations
|
||||||
* @return an array of shifted coordinates. The method may modify the contents
|
|
||||||
* of the passed array and return the array itself.
|
|
||||||
*/
|
*/
|
||||||
// @Override Me !
|
// @Override Me !
|
||||||
public Coordinate[] getInstanceLocations(){
|
public Coordinate[] getInstanceLocations(){
|
||||||
@ -1145,10 +1101,11 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
|||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* NOTE: the length of this array returned always equals this.getInstanceCount()
|
* 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(){
|
public Coordinate[] getInstanceOffsets(){
|
||||||
// According to the language specification, Java will initialized double values to 0.0
|
|
||||||
return new Coordinate[]{Coordinate.ZERO};
|
return new Coordinate[]{Coordinate.ZERO};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1159,13 +1116,15 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
|||||||
return getComponentLocations();
|
return getComponentLocations();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides locations of all instances of component *accounting for all parent instancing*
|
* Provides locations of all instances of component *accounting for all parent instancing*
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* NOTE: the length of this array MAY OR MAY NOT EQUAL this.getInstanceCount()
|
* 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() {
|
public Coordinate[] getComponentLocations() {
|
||||||
if (null == this.parent) {
|
if (null == this.parent) {
|
||||||
@ -1175,23 +1134,20 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
|||||||
Coordinate[] parentPositions = this.parent.getComponentLocations();
|
Coordinate[] parentPositions = this.parent.getComponentLocations();
|
||||||
int parentCount = parentPositions.length;
|
int parentCount = parentPositions.length;
|
||||||
|
|
||||||
// override <instance>.getInstanceOffsets() in the subclass you want to fix.
|
// override <instance>.getInstanceLocations() in each subclass
|
||||||
Coordinate[] instanceOffsets = this.getInstanceLocations();
|
Coordinate[] instanceLocations = this.getInstanceLocations();
|
||||||
int instanceCount = instanceOffsets.length;
|
int instanceCount = instanceLocations.length;
|
||||||
|
|
||||||
// usual case optimization
|
// usual case optimization
|
||||||
if((1 == parentCount)&&(1 == instanceCount)){
|
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;
|
int thisCount = instanceCount*parentCount;
|
||||||
Coordinate[] thesePositions = new Coordinate[thisCount];
|
Coordinate[] thesePositions = new Coordinate[thisCount];
|
||||||
for (int pi = 0; pi < parentCount; pi++) {
|
for (int pi = 0; pi < parentCount; pi++) {
|
||||||
for( int ii = 0; ii < instanceCount; ii++ ){
|
for( int ii = 0; ii < instanceCount; ii++ ){
|
||||||
// System.err.println(" #"+pi+", "+ii+" = "+(pi + parentCount*ii));
|
thesePositions[pi + parentCount*ii] = parentPositions[pi].add(instanceLocations[ii]);
|
||||||
// System.err.println(" "+parentPositions[pi]+" + "+instanceOffsets[ii]);
|
|
||||||
thesePositions[pi + parentCount*ii] = parentPositions[pi].add(instanceOffsets[ii]);
|
|
||||||
// System.err.println(" ="+thesePositions[pi+parentCount*ii]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return thesePositions;
|
return thesePositions;
|
||||||
@ -1229,16 +1185,6 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
|||||||
return toReturn;
|
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
|
* Return coordinate <code>c</code> described in the coordinate system of
|
||||||
* <code>dest</code>. If <code>dest</code> is <code>null</code> returns
|
* <code>dest</code>. If <code>dest</code> is <code>null</code> returns
|
||||||
|
@ -31,7 +31,7 @@ public enum AxialMethod implements DistanceMethod {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getAsOffset(double position, double innerLength, double outerLength){
|
public double getAsOffset(double position, double innerLength, double outerLength){
|
||||||
return outerLength - position;
|
return position - outerLength;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ public enum AxialMethod implements DistanceMethod {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getAsPosition(double offset, double innerLength, double outerLength){
|
public double getAsPosition(double offset, double innerLength, double outerLength){
|
||||||
return (outerLength - innerLength) / 2 - offset;
|
return offset + (outerLength - innerLength) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -76,7 +76,7 @@ public enum AxialMethod implements DistanceMethod {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getAsPosition(double offset, double innerLength, double outerLength){
|
public double getAsPosition(double offset, double innerLength, double outerLength){
|
||||||
return outerLength - innerLength - offset;
|
return offset + (outerLength - innerLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -9,7 +9,6 @@ import net.sf.openrocket.file.simplesax.PlainTextHandler;
|
|||||||
import net.sf.openrocket.material.Material;
|
import net.sf.openrocket.material.Material;
|
||||||
import net.sf.openrocket.rocketcomponent.BodyTube;
|
import net.sf.openrocket.rocketcomponent.BodyTube;
|
||||||
import net.sf.openrocket.rocketcomponent.InnerTube;
|
import net.sf.openrocket.rocketcomponent.InnerTube;
|
||||||
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
|
|
||||||
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
|
||||||
@ -119,20 +118,6 @@ public class InnerBodyTubeHandlerTest extends RocksimTestBase {
|
|||||||
Assert.assertEquals("Test Name", component.getName());
|
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()
|
* Method: getComponent()
|
||||||
*
|
*
|
||||||
|
@ -10,7 +10,6 @@ import net.sf.openrocket.material.Material;
|
|||||||
import net.sf.openrocket.rocketcomponent.BodyTube;
|
import net.sf.openrocket.rocketcomponent.BodyTube;
|
||||||
import net.sf.openrocket.rocketcomponent.ExternalComponent;
|
import net.sf.openrocket.rocketcomponent.ExternalComponent;
|
||||||
import net.sf.openrocket.rocketcomponent.LaunchLug;
|
import net.sf.openrocket.rocketcomponent.LaunchLug;
|
||||||
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
|
|
||||||
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
|
||||||
@ -110,20 +109,6 @@ public class LaunchLugHandlerTest extends RocksimTestBase {
|
|||||||
Assert.assertEquals("Test Name", component.getName());
|
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()
|
* Method: getComponent()
|
||||||
*
|
*
|
||||||
|
@ -9,7 +9,6 @@ import net.sf.openrocket.file.simplesax.PlainTextHandler;
|
|||||||
import net.sf.openrocket.material.Material;
|
import net.sf.openrocket.material.Material;
|
||||||
import net.sf.openrocket.rocketcomponent.BodyTube;
|
import net.sf.openrocket.rocketcomponent.BodyTube;
|
||||||
import net.sf.openrocket.rocketcomponent.MassComponent;
|
import net.sf.openrocket.rocketcomponent.MassComponent;
|
||||||
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
|
|
||||||
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
|
||||||
@ -91,20 +90,6 @@ public class MassObjectHandlerTest extends RocksimTestBase {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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()
|
* Method: getComponent()
|
||||||
*
|
*
|
||||||
|
@ -113,7 +113,7 @@ public class ParachuteHandlerTest extends RocksimTestBase {
|
|||||||
BodyTube tube = new BodyTube();
|
BodyTube tube = new BodyTube();
|
||||||
ParachuteHandler handler = new ParachuteHandler(null, tube, new WarningSet());
|
ParachuteHandler handler = new ParachuteHandler(null, tube, new WarningSet());
|
||||||
Parachute component = (Parachute) getField(handler, "chute");
|
Parachute component = (Parachute) getField(handler, "chute");
|
||||||
handler.setAxialMethod(AxialMethod.ABSOLUTE);
|
handler.getComponent().setAxialMethod(AxialMethod.ABSOLUTE);
|
||||||
Assert.assertEquals(AxialMethod.ABSOLUTE, component.getAxialMethod());
|
Assert.assertEquals(AxialMethod.ABSOLUTE, component.getAxialMethod());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,21 +247,6 @@ public class RingHandlerTest extends RocksimTestBase {
|
|||||||
CenteringRing component = (CenteringRing) getField(handler, "ring");
|
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()
|
* Method: getComponent()
|
||||||
*
|
*
|
||||||
|
@ -109,7 +109,7 @@ public class StreamerHandlerTest extends RocksimTestBase {
|
|||||||
BodyTube tube = new BodyTube();
|
BodyTube tube = new BodyTube();
|
||||||
StreamerHandler handler = new StreamerHandler(null, tube, new WarningSet());
|
StreamerHandler handler = new StreamerHandler(null, tube, new WarningSet());
|
||||||
Streamer component = (Streamer) getField(handler, "streamer");
|
Streamer component = (Streamer) getField(handler, "streamer");
|
||||||
handler.setAxialMethod(AxialMethod.ABSOLUTE);
|
handler.getComponent().setAxialMethod(AxialMethod.ABSOLUTE);
|
||||||
Assert.assertEquals(AxialMethod.ABSOLUTE, component.getAxialMethod());
|
Assert.assertEquals(AxialMethod.ABSOLUTE, component.getAxialMethod());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,8 +2,7 @@ package net.sf.openrocket.rocketcomponent;
|
|||||||
|
|
||||||
//import junit.framework.TestCase;
|
//import junit.framework.TestCase;
|
||||||
import static org.hamcrest.CoreMatchers.equalTo;
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.*;
|
||||||
import static org.junit.Assert.assertThat;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@ -18,20 +17,15 @@ public class ParallelStageTest extends BaseTestCase {
|
|||||||
// tolerance for compared double test results
|
// tolerance for compared double test results
|
||||||
protected final double EPSILON = 0.000001;
|
protected final double EPSILON = 0.000001;
|
||||||
|
|
||||||
protected final Coordinate ZERO = new Coordinate(0., 0., 0.);
|
|
||||||
|
|
||||||
|
|
||||||
/* From OpenRocket Technical Documentation
|
/* From OpenRocket Technical Documentation
|
||||||
*
|
*
|
||||||
* 3.1.4 Coordinate systems
|
* 3.1.4 Coordinate systems
|
||||||
* During calculation of the aerodynamic properties a coordinate system fixed to the rocket will be used.
|
* 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
|
* 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.
|
* and do not necessarily align with the plane of the pitching moments.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
public ParallelStage createExtraBooster() {
|
public ParallelStage createExtraBooster() {
|
||||||
double tubeRadius = 0.8;
|
double tubeRadius = 0.8;
|
||||||
|
|
||||||
@ -106,7 +100,7 @@ public class ParallelStageTest extends BaseTestCase {
|
|||||||
// WARNING: this test will not pass unless 'testAddTopStage' is passing as well -- that function tests the dependencies...
|
// WARNING: this test will not pass unless 'testAddTopStage' is passing as well -- that function tests the dependencies...
|
||||||
@Test
|
@Test
|
||||||
public void testCreateCoreStage() {
|
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();
|
final Rocket rocket = TestRockets.makeFalcon9Heavy();
|
||||||
// ^^^^ function under test ^^^^
|
// ^^^^ function under test ^^^^
|
||||||
|
|
||||||
@ -195,7 +189,7 @@ public class ParallelStageTest extends BaseTestCase {
|
|||||||
|
|
||||||
assertThat(" 'setInstancecount(int)' failed: ", 2, equalTo(parallelBoosterSet.getInstanceCount()));
|
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 method: ", RadiusMethod.FREE, parallelBoosterSet.getRadiusMethod() );
|
||||||
assertEquals(" error while setting radius offset: ", 2.0, parallelBoosterSet.getRadiusOffset(), EPSILON);
|
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()));
|
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 method: ", RadiusMethod.SURFACE, parallelBoosterStage.getRadiusMethod() );
|
||||||
assertEquals(" error while setting radius offset: ", 0.0, parallelBoosterStage.getRadiusOffset(), EPSILON);
|
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 );
|
parallelBoosterStage.setRadius( RadiusMethod.RELATIVE, targetRadiusOffset );
|
||||||
// ^^ function under test
|
// ^^ 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 method: ", RadiusMethod.RELATIVE, parallelBoosterStage.getRadiusMethod() );
|
||||||
assertEquals(" error while setting radius offset: ", targetRadiusOffset, parallelBoosterStage.getRadiusOffset() , EPSILON);
|
assertEquals(" error while setting radius offset: ", targetRadiusOffset, parallelBoosterStage.getRadiusOffset() , EPSILON);
|
||||||
|
|
||||||
@ -333,7 +327,7 @@ public class ParallelStageTest extends BaseTestCase {
|
|||||||
double expectedRelativeX = 0.236;
|
double expectedRelativeX = 0.236;
|
||||||
double expectedAbsoluteX = 0.8;
|
double expectedAbsoluteX = 0.8;
|
||||||
|
|
||||||
// when subStages should be freely movable
|
// when substages should be freely movable
|
||||||
// vv function under test
|
// vv function under test
|
||||||
boosterStage.setAxialOffset(AxialMethod.ABSOLUTE, targetAbsoluteX);
|
boosterStage.setAxialOffset(AxialMethod.ABSOLUTE, targetAbsoluteX);
|
||||||
// ^^ function under test
|
// ^^ function under test
|
||||||
@ -341,7 +335,7 @@ public class ParallelStageTest extends BaseTestCase {
|
|||||||
assertEquals("setAxialOffset( method, double) failed: ", AxialMethod.ABSOLUTE, boosterStage.getAxialMethod() );
|
assertEquals("setAxialOffset( method, double) failed: ", AxialMethod.ABSOLUTE, boosterStage.getAxialMethod() );
|
||||||
assertEquals("setAxialOffset( method, double) failed: ", targetAbsoluteX, boosterStage.getAxialOffset(), EPSILON );
|
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 );
|
assertEquals(" 'setAxialPosition(double)' failed: Relative position: ", expectedRelativeX, actualRelativeX, EPSILON );
|
||||||
|
|
||||||
double actualAbsoluteX = boosterStage.getComponentLocations()[0].x;
|
double actualAbsoluteX = boosterStage.getComponentLocations()[0].x;
|
||||||
@ -422,7 +416,6 @@ public class ParallelStageTest extends BaseTestCase {
|
|||||||
Assert.assertEquals( 0.16, boosterStage.getPosition().x, EPSILON );
|
Assert.assertEquals( 0.16, boosterStage.getPosition().x, EPSILON );
|
||||||
|
|
||||||
Assert.assertEquals( 0.724, boosterStage.getComponentLocations()[0].x, EPSILON );
|
Assert.assertEquals( 0.724, boosterStage.getComponentLocations()[0].x, EPSILON );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -456,14 +449,14 @@ public class ParallelStageTest extends BaseTestCase {
|
|||||||
// ^^ function under test
|
// ^^ function under test
|
||||||
|
|
||||||
Assert.assertEquals( targetOffset, boosterStage.getAxialOffset(), EPSILON );
|
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;
|
final double resultantRelativePosition = boosterStage.getPosition().x;
|
||||||
Assert.assertEquals(expectedRelativePositionX, resultantRelativePosition, EPSILON);
|
Assert.assertEquals(expectedRelativePositionX, resultantRelativePosition, EPSILON);
|
||||||
|
|
||||||
// vv function under test
|
// vv function under test
|
||||||
final double actualAbsoluteX = boosterStage.asPositionValue(AxialMethod.ABSOLUTE);
|
final double actualAbsoluteX = boosterStage.getAxialOffset(AxialMethod.ABSOLUTE);
|
||||||
// ^^ function under test
|
// ^^ function under test
|
||||||
|
|
||||||
Assert.assertEquals( 0.764, actualAbsoluteX, EPSILON );
|
Assert.assertEquals( 0.764, actualAbsoluteX, EPSILON );
|
||||||
@ -486,7 +479,7 @@ public class ParallelStageTest extends BaseTestCase {
|
|||||||
|
|
||||||
|
|
||||||
// vv function under test
|
// vv function under test
|
||||||
double actualPositionXAfter = boosterStage.asPositionValue(AxialMethod.AFTER);
|
double actualPositionXAfter = boosterStage.getAxialOffset(AxialMethod.AFTER);
|
||||||
// ^^ function under test
|
// ^^ function under test
|
||||||
|
|
||||||
Assert.assertEquals( -0.6, actualPositionXAfter, EPSILON );
|
Assert.assertEquals( -0.6, actualPositionXAfter, EPSILON );
|
||||||
@ -508,7 +501,7 @@ public class ParallelStageTest extends BaseTestCase {
|
|||||||
Assert.assertEquals( 0.2, boosterStage.getPosition().x, EPSILON );
|
Assert.assertEquals( 0.2, boosterStage.getPosition().x, EPSILON );
|
||||||
|
|
||||||
// vv function under test
|
// vv function under test
|
||||||
final double actualAxialPosition = boosterStage.asPositionValue(AxialMethod.MIDDLE);
|
final double actualAxialPosition = boosterStage.getAxialOffset(AxialMethod.MIDDLE);
|
||||||
// ^^ function under test
|
// ^^ function under test
|
||||||
|
|
||||||
Assert.assertEquals( 0.24, actualAxialPosition, EPSILON );
|
Assert.assertEquals( 0.24, actualAxialPosition, EPSILON );
|
||||||
@ -530,7 +523,7 @@ public class ParallelStageTest extends BaseTestCase {
|
|||||||
Assert.assertEquals( 0.2, boosterStage.getPosition().x, EPSILON );
|
Assert.assertEquals( 0.2, boosterStage.getPosition().x, EPSILON );
|
||||||
|
|
||||||
// vv function under test
|
// vv function under test
|
||||||
double actualAxialBottomOffset = boosterStage.asPositionValue(AxialMethod.BOTTOM);
|
double actualAxialBottomOffset = boosterStage.getAxialOffset(AxialMethod.BOTTOM);
|
||||||
// ^^ function under test
|
// ^^ function under test
|
||||||
|
|
||||||
Assert.assertEquals( 0.28, actualAxialBottomOffset, EPSILON );
|
Assert.assertEquals( 0.28, actualAxialBottomOffset, EPSILON );
|
||||||
@ -552,7 +545,7 @@ public class ParallelStageTest extends BaseTestCase {
|
|||||||
Assert.assertEquals( 0.120, boosterStage.getPosition().x, EPSILON);
|
Assert.assertEquals( 0.120, boosterStage.getPosition().x, EPSILON);
|
||||||
|
|
||||||
// vv function under test
|
// vv function under test
|
||||||
double actualAxialTopOffset = boosterStage.asPositionValue(AxialMethod.TOP);
|
double actualAxialTopOffset = boosterStage.getAxialOffset(AxialMethod.TOP);
|
||||||
// ^^ function under test
|
// ^^ function under test
|
||||||
|
|
||||||
Assert.assertEquals( 0.12, actualAxialTopOffset, EPSILON);
|
Assert.assertEquals( 0.12, actualAxialTopOffset, EPSILON);
|
||||||
|
@ -257,7 +257,7 @@ public abstract class FinSetConfig extends RocketComponentConfig {
|
|||||||
if (!rings.isEmpty()) {
|
if (!rings.isEmpty()) {
|
||||||
AxialMethod temp = (AxialMethod) em.getSelectedItem();
|
AxialMethod temp = (AxialMethod) em.getSelectedItem();
|
||||||
em.setSelectedItem(AxialMethod.TOP);
|
em.setSelectedItem(AxialMethod.TOP);
|
||||||
double len = computeFinTabLength(rings, component.asPositionValue(AxialMethod.TOP),
|
double len = computeFinTabLength(rings, component.getAxialOffset(AxialMethod.TOP),
|
||||||
component.getLength(), mts, parent);
|
component.getLength(), mts, parent);
|
||||||
mtl.setValue(len);
|
mtl.setValue(len);
|
||||||
//Be nice to the user and set the tab relative position enum back the way they had it.
|
//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>() {
|
Collections.sort(rings, new Comparator<CenteringRing>() {
|
||||||
@Override
|
@Override
|
||||||
public int compare(CenteringRing centeringRing, CenteringRing centeringRing1) {
|
public int compare(CenteringRing centeringRing, CenteringRing centeringRing1) {
|
||||||
return (int) (1000d * (centeringRing.asPositionValue(AxialMethod.TOP) -
|
return (int) (1000d * (centeringRing.getAxialOffset(AxialMethod.TOP) -
|
||||||
centeringRing1.asPositionValue(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.
|
//Handle centering rings that overlap or are adjacent by synthetically merging them into one virtual ring.
|
||||||
if (!positionsFromTop.isEmpty() &&
|
if (!positionsFromTop.isEmpty() &&
|
||||||
positionsFromTop.get(positionsFromTop.size() - 1).bottomSidePositionFromTop() >=
|
positionsFromTop.get(positionsFromTop.size() - 1).bottomSidePositionFromTop() >=
|
||||||
centeringRing.asPositionValue(AxialMethod.TOP)) {
|
centeringRing.getAxialOffset(AxialMethod.TOP)) {
|
||||||
SortableRing adjacent = positionsFromTop.get(positionsFromTop.size() - 1);
|
SortableRing adjacent = positionsFromTop.get(positionsFromTop.size() - 1);
|
||||||
adjacent.merge(centeringRing, relativeTo);
|
adjacent.merge(centeringRing, relativeTo);
|
||||||
} else {
|
} else {
|
||||||
@ -441,7 +441,7 @@ public abstract class FinSetConfig extends RocketComponentConfig {
|
|||||||
*/
|
*/
|
||||||
SortableRing(CenteringRing r, RocketComponent relativeTo) {
|
SortableRing(CenteringRing r, RocketComponent relativeTo) {
|
||||||
thickness = r.getLength();
|
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
|
* @param adjacent the adjacent ring
|
||||||
*/
|
*/
|
||||||
public void merge(CenteringRing adjacent, RocketComponent relativeTo) {
|
public void merge(CenteringRing adjacent, RocketComponent relativeTo) {
|
||||||
double v = adjacent.asPositionValue(AxialMethod.TOP);
|
double v = adjacent.getAxialOffset(AxialMethod.TOP);
|
||||||
if (positionFromTop < v) {
|
if (positionFromTop < v) {
|
||||||
thickness = (v + adjacent.getLength()) - positionFromTop;
|
thickness = (v + adjacent.getLength()) - positionFromTop;
|
||||||
} else {
|
} else {
|
||||||
|
@ -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
|
* @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) {
|
private boolean overlaps(CenteringRing one, InnerTube two) {
|
||||||
final double crTopPosition = one.asPositionValue( AxialMethod.ABSOLUTE);
|
final double crTopPosition = one.getAxialOffset( AxialMethod.ABSOLUTE);
|
||||||
final double mmTopPosition = two.asPositionValue( AxialMethod.ABSOLUTE);
|
final double mmTopPosition = two.getAxialOffset( AxialMethod.ABSOLUTE);
|
||||||
final double crBottomPosition = one.getLength() + crTopPosition;
|
final double crBottomPosition = one.getLength() + crTopPosition;
|
||||||
final double mmBottomPosition = two.getLength() + mmTopPosition;
|
final double mmBottomPosition = two.getLength() + mmTopPosition;
|
||||||
|
|
||||||
|
@ -159,7 +159,7 @@ public class FinPointFigure extends AbstractScaleFigure {
|
|||||||
Transition body = (Transition) finset.getParent();
|
Transition body = (Transition) finset.getParent();
|
||||||
final float xResolution_m = 0.01f; // distance between draw points, in meters
|
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
|
// vv in fin-frame == draw-frame vv
|
||||||
final double xOffset = -xFinStart;
|
final double xOffset = -xFinStart;
|
||||||
@ -355,7 +355,7 @@ public class FinPointFigure extends AbstractScaleFigure {
|
|||||||
|
|
||||||
// update to bound the parent body:
|
// update to bound the parent body:
|
||||||
SymmetricComponent parent = (SymmetricComponent)this.finset.getParent();
|
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 xParent = -xFinFront;
|
||||||
final double yParent = -parent.getRadius(xParent); // from parent centerline to fin front.
|
final double yParent = -parent.getRadius(xParent); // from parent centerline to fin front.
|
||||||
final double rParent = Math.max(parent.getForeRadius(), parent.getAftRadius());
|
final double rParent = Math.max(parent.getForeRadius(), parent.getAftRadius());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user