Fixed GUI elements & function f/Boosters/Pods

Model
  Refactored code from AxialStage, BoosterSet, PodSet => ComponentAssembly

GUI
  BoosterSet: Fixed bugs, allowed boosters and pods to be correctly located.
This commit is contained in:
Daniel_M_Williams 2015-08-27 08:54:35 -04:00
parent 0c01123551
commit ea8066f63c
11 changed files with 333 additions and 519 deletions

View File

@ -896,7 +896,7 @@ StageConfig.separation.lbl.plus = plus
StageConfig.separation.lbl.seconds = seconds
StageConfig.parallel.radius = Radial Distance
StageConfig.parallel.angle = Angle
StageConfig.parallel.count = Number of Boosters
StageConfig.parallel.count = Number of Copies
StageConfig.parallel.offset = Offset Value
!EllipticalFinSetConfig

View File

@ -4,12 +4,13 @@ import java.util.HashMap;
import net.sf.openrocket.aerodynamics.Warning;
import net.sf.openrocket.aerodynamics.WarningSet;
import net.sf.openrocket.rocketcomponent.BoosterSet;
import net.sf.openrocket.rocketcomponent.FinSet;
import net.sf.openrocket.rocketcomponent.InternalComponent;
import net.sf.openrocket.rocketcomponent.LaunchLug;
import net.sf.openrocket.rocketcomponent.PodSet;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketcomponent.RocketComponent.Position;
import net.sf.openrocket.rocketcomponent.AxialStage;
import net.sf.openrocket.rocketcomponent.TubeFinSet;
class PositionSetter implements Setter {
@ -45,8 +46,11 @@ class PositionSetter implements Setter {
} else if (c instanceof TubeFinSet) {
((TubeFinSet) c).setRelativePosition(type);
c.setAxialOffset(pos);
} else if (c instanceof AxialStage) {
((AxialStage) c).setRelativePositionMethod(type);
} else if (c instanceof BoosterSet) {
((BoosterSet) c).setRelativePositionMethod(type);
c.setAxialOffset(pos);
} else if (c instanceof PodSet) {
((PodSet) c).setRelativePositionMethod(type);
c.setAxialOffset(pos);
} else {
warnings.add(Warning.FILE_INVALID_PARAMETER);

View File

@ -2,7 +2,6 @@ package net.sf.openrocket.rocketcomponent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.startup.Application;
@ -94,12 +93,6 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC
return copy;
}
public void setRelativePositionMethod(final Position _newPosition) {
// Axial Stages are restricted to .AFTER, and cannot be changed.
return;
}
@Override
public double getPositionValue() {
mutex.verify();
@ -134,24 +127,6 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC
return this.stageNumber;
}
@Override
public double getAxialOffset() {
double returnValue = super.asPositionValue(this.relativePosition);
if (0.000001 > Math.abs(returnValue)) {
returnValue = 0.0;
}
return returnValue;
}
@Override
public void setAxialOffset(final double _pos) {
this.updateBounds();
super.setAxialOffset(this.relativePosition, _pos);
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
@Override
public Coordinate[] shiftCoordinates(Coordinate[] c) {
checkState();
@ -172,67 +147,6 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC
return buf;
}
@Override
public void toDebugTreeNode(final StringBuilder buffer, final String prefix) {
String thisLabel = this.getName() + " (" + this.getStageNumber() + ")";
buffer.append(String.format("%s %-24s %5.3f", prefix, thisLabel, this.getLength()));
buffer.append(String.format(" %24s %24s\n", this.getOffset(), this.getLocation()[0]));
}
@Override
public void updateBounds() {
// currently only updates the length
this.length = 0;
Iterator<RocketComponent> childIterator = this.getChildren().iterator();
while (childIterator.hasNext()) {
RocketComponent curChild = childIterator.next();
if (curChild.isCenterline()) {
this.length += curChild.getLength();
}
}
}
@Override
protected void update() {
if (null == this.parent) {
return;
}
this.updateBounds();
// stages which are directly children of the rocket are inline, and positioned
int childNumber = this.parent.getChildPosition(this);
if (0 == childNumber) {
this.setAfter(this.parent);
} else {
RocketComponent prevStage = this.parent.getChild(childNumber - 1);
this.setAfter(prevStage);
}
// updates the internal 'previousComponent' field.
this.updateChildSequence();
return;
}
protected void updateChildSequence() {
Iterator<RocketComponent> childIterator = this.getChildren().iterator();
RocketComponent prevComp = null;
while (childIterator.hasNext()) {
RocketComponent curChild = childIterator.next();
if (curChild.isCenterline()) {
//curChild.previousComponent = prevComp;
curChild.setAfter(prevComp);
prevComp = curChild;
// } else {
// curChild.previousComponent = null;
}
}
}
}

View File

@ -2,7 +2,6 @@ package net.sf.openrocket.rocketcomponent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.startup.Application;
@ -19,15 +18,9 @@ public class BoosterSet extends AxialStage implements FlightConfigurableComponen
private FlightConfigurationImpl<StageSeparationConfiguration> separationConfigurations;
private double angularPosition_rad = 0;
private double radialPosition_m = 0;
private int count = 2;
private double angularSeparation = Math.PI;
public BoosterSet() {
this.count = 2;
this.relativePosition = Position.BOTTOM;
}
@Override
@ -40,7 +33,6 @@ public class BoosterSet extends AxialStage implements FlightConfigurableComponen
@Override
public Collection<Coordinate> getComponentBounds() {
Collection<Coordinate> bounds = new ArrayList<Coordinate>(8);
final double WAG_FACTOR = 1.1;
double x_min = Double.MAX_VALUE;
double x_max = Double.MIN_VALUE;
double r_max = 0;
@ -54,8 +46,8 @@ public class BoosterSet extends AxialStage implements FlightConfigurableComponen
if (x_max < (currentInstanceLocation.x + this.length)) {
x_max = currentInstanceLocation.x + this.length;
}
if (r_max < (this.getRadialOffset() * WAG_FACTOR)) {
r_max = this.getRadialOffset() * WAG_FACTOR;
if (r_max < (this.getRadialOffset())) {
r_max = this.getRadialOffset();
}
}
addBound(bounds, x_min, r_max);
@ -120,47 +112,6 @@ public class BoosterSet extends AxialStage implements FlightConfigurableComponen
return false;
}
@Override
public int getInstanceCount() {
return this.count;
}
@Override
public void setInstanceCount(final int _count) {
mutex.verify();
if (_count < 2) {
// there must be at least one instance....
return;
}
this.count = _count;
this.angularSeparation = Math.PI * 2 / this.count;
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
@Override
public double getAngularOffset() {
return this.angularPosition_rad;
}
@Override
public void setAngularOffset(final double angle_rad) {
this.angularPosition_rad = angle_rad;
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
@Override
public double getRadialOffset() {
return this.radialPosition_m;
}
@Override
public void setRadialOffset(final double radius) {
// log.error(" set radial position for: " + this.getName() + " to: " + this.radialPosition_m + " ... in meters?");
this.radialPosition_m = radius;
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
@Override
public void setRelativePositionMethod(final Position _newPosition) {
if (null == this.parent) {
@ -205,31 +156,6 @@ public class BoosterSet extends AxialStage implements FlightConfigurableComponen
return this.stageNumber;
}
@Override
public double getAxialOffset() {
double returnValue = Double.NaN;
if ((this.isCenterline() && (Position.AFTER != this.relativePosition))) {
// remember the implicit (this instanceof Stage)
throw new BugException("found a Stage on centerline, but not positioned as AFTER. Please fix this! " + this.getName() + " is " + this.getRelativePosition().name());
} else {
returnValue = super.asPositionValue(this.relativePosition);
}
if (0.000001 > Math.abs(returnValue)) {
returnValue = 0.0;
}
return returnValue;
}
@Override
public void setAxialOffset(final double _pos) {
this.updateBounds();
super.setAxialOffset(this.relativePosition, _pos);
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
@Override
public Coordinate[] shiftCoordinates(Coordinate[] c) {
checkState();
@ -259,70 +185,4 @@ public class BoosterSet extends AxialStage implements FlightConfigurableComponen
return toReturn;
}
@Override
protected StringBuilder toDebugDetail() {
StringBuilder buf = super.toDebugDetail();
// if (-1 == this.getRelativeToStage()) {
// System.err.println(" >>refStageName: " + null + "\n");
// } else {
// Stage refStage = (Stage) this.parent;
// System.err.println(" >>refStageName: " + refStage.getName() + "\n");
// System.err.println(" ..refCenterX: " + refStage.position.x + "\n");
// System.err.println(" ..refLength: " + refStage.getLength() + "\n");
// }
return buf;
}
@Override
public void toDebugTreeNode(final StringBuilder buffer, final String prefix) {
String thisLabel = this.getName() + " (" + this.getStageNumber() + ")";
buffer.append(String.format("%s %-24s %5.3f", prefix, thisLabel, this.getLength()));
if (this.isCenterline()) {
buffer.append(String.format(" %24s %24s\n", this.getOffset(), this.getLocation()[0]));
} else {
buffer.append(String.format(" %4.1f via: %s \n", this.getAxialOffset(), this.relativePosition.name()));
Coordinate[] relCoords = this.shiftCoordinates(new Coordinate[] { Coordinate.ZERO });
Coordinate[] absCoords = this.getLocation();
for (int instanceNumber = 0; instanceNumber < this.count; instanceNumber++) {
Coordinate instanceRelativePosition = relCoords[instanceNumber];
Coordinate instanceAbsolutePosition = absCoords[instanceNumber];
buffer.append(String.format("%s [instance %2d of %2d] %32s %32s\n", prefix, instanceNumber, count,
instanceRelativePosition, instanceAbsolutePosition));
}
}
}
@Override
public void updateBounds() {
// currently only updates the length
this.length = 0;
Iterator<RocketComponent> childIterator = this.getChildren().iterator();
while (childIterator.hasNext()) {
RocketComponent curChild = childIterator.next();
this.length += curChild.getLength();
}
}
@Override
protected void update() {
if (null == this.parent) {
return;
}
this.updateBounds();
// because if parent is instanceof Stage, that means 'this' is positioned externally
super.update();
// updates the internal 'previousComponent' field.
this.updateChildSequence();
return;
}
}

View File

@ -2,9 +2,13 @@ package net.sf.openrocket.rocketcomponent;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import net.sf.openrocket.util.Coordinate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
@ -16,7 +20,14 @@ import net.sf.openrocket.util.Coordinate;
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
*/
public abstract class ComponentAssembly extends RocketComponent {
private static final Logger log = LoggerFactory.getLogger(ComponentAssembly.class);
protected double angularPosition_rad = 0;
protected double radialPosition_m = 0;
protected int count = 1;
protected double angularSeparation = Math.PI;
/**
* Sets the position of the components to POSITION_RELATIVE_AFTER.
* (Should have no effect.)
@ -25,14 +36,31 @@ public abstract class ComponentAssembly extends RocketComponent {
super(RocketComponent.Position.AFTER);
}
@Override
public int getInstanceCount() {
return this.count;
}
public double getAngularOffset() {
return this.angularPosition_rad;
}
@Override
public double getAxialOffset() {
return super.asPositionValue(this.relativePosition);
}
/**
* Null method (ComponentAssembly has no bounds of itself).
*/
@Override
public Collection<Coordinate> getComponentBounds() {
public Collection<Coordinate> getComponentBounds() {
return Collections.emptyList();
}
/**
* Null method (ComponentAssembly has no mass of itself).
*/
@ -40,7 +68,7 @@ public abstract class ComponentAssembly extends RocketComponent {
public Coordinate getComponentCG() {
return Coordinate.NUL;
}
/**
* Null method (ComponentAssembly has no mass of itself).
*/
@ -49,6 +77,11 @@ public abstract class ComponentAssembly extends RocketComponent {
return 0;
}
public double getRadialOffset() {
return this.radialPosition_m;
}
/**
* Null method (ComponentAssembly has no mass of itself).
*/
@ -57,6 +90,11 @@ public abstract class ComponentAssembly extends RocketComponent {
return 0;
}
@Override
public boolean getOverrideSubcomponents() {
return true;
}
/**
* Null method (ComponentAssembly has no mass of itself).
*/
@ -81,12 +119,69 @@ public abstract class ComponentAssembly extends RocketComponent {
public boolean isMassive() {
return false;
}
@Override
public boolean getOverrideSubcomponents() {
return true;
public void setAngularOffset(final double angle_rad) {
if (this.isCenterline()) {
return;
}
this.angularPosition_rad = angle_rad;
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
@Override
public void setAxialOffset(final double _pos) {
this.updateBounds();
// System.err.println("updating axial position for boosters: " + this.getName() + " ( " + this.getComponentName() + ")");
// System.err.println(" requesting offset: " + _pos + " via: " + this.relativePosition.name());
super.setAxialOffset(this.relativePosition, _pos);
// System.err.println(" resultant offset: " + this.position.x + " via: " + this.relativePosition.name());
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
public void setInstanceCount(final int _count) {
mutex.verify();
if (this.isCenterline()) {
return;
}
if (_count < 2) {
// there must be at least one instance....
return;
}
this.count = _count;
this.angularSeparation = Math.PI * 2 / this.count;
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
public void setRadialOffset(final double radius) {
if (false == this.isCenterline()) {
this.radialPosition_m = radius;
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
}
public void setRelativePositionMethod(final Position _newPosition) {
if (null == this.parent) {
throw new NullPointerException(" a Stage requires a parent before any positioning! ");
}
if (this.isCenterline()) {
// Centerline stages must be set via AFTER-- regardless of what was requested:
super.setRelativePosition(Position.AFTER);
} else if (this.parent instanceof PodSet) {
if (Position.AFTER == _newPosition) {
log.warn("Stages cannot be relative to other stages via AFTER! Ignoring.");
super.setRelativePosition(Position.TOP);
} else {
super.setRelativePosition(_newPosition);
}
}
fireComponentChangeEvent(ComponentChangeEvent.AERODYNAMIC_CHANGE);
}
@Override
public void setOverrideSubcomponents(boolean override) {
// No-op
@ -97,4 +192,83 @@ public abstract class ComponentAssembly extends RocketComponent {
return false;
}
@Override
public void toDebugTreeNode(final StringBuilder buffer, final String prefix) {
String thisLabel = this.getName() + " (" + this.getStageNumber() + ")";
buffer.append(String.format("%s %-24s %5.3f", prefix, thisLabel, this.getLength()));
if (this.isCenterline()) {
buffer.append(String.format(" %24s %24s\n", this.getOffset(), this.getLocation()[0]));
} else {
buffer.append(String.format(" (offset: %4.1f via: %s )\n", this.getAxialOffset(), this.relativePosition.name()));
Coordinate[] relCoords = this.shiftCoordinates(new Coordinate[] { Coordinate.ZERO });
Coordinate[] absCoords = this.getLocation();
for (int instanceNumber = 0; instanceNumber < this.count; instanceNumber++) {
Coordinate instanceRelativePosition = relCoords[instanceNumber];
Coordinate instanceAbsolutePosition = absCoords[instanceNumber];
buffer.append(String.format("%s [instance %2d of %2d] %32s %32s\n", prefix, instanceNumber, count,
instanceRelativePosition, instanceAbsolutePosition));
}
}
}
@Override
protected void update() {
if (null == this.parent) {
return;
}
this.updateBounds();
if (this.isCenterline()) {
// stages which are directly children of the rocket are inline, and positioned
int childNumber = this.parent.getChildPosition(this);
if (0 == childNumber) {
this.setAfter(this.parent);
} else {
RocketComponent prevStage = this.parent.getChild(childNumber - 1);
this.setAfter(prevStage);
}
} else {
// this path is for 'external' assemblies: pods and boosters
super.update();
}
this.updateChildSequence();
return;
}
@Override
public void updateBounds() {
// currently only updates the length
this.length = 0;
Iterator<RocketComponent> childIterator = this.getChildren().iterator();
while (childIterator.hasNext()) {
RocketComponent curChild = childIterator.next();
if (curChild.isCenterline()) {
this.length += curChild.getLength();
}
}
}
protected void updateChildSequence() {
Iterator<RocketComponent> childIterator = this.getChildren().iterator();
RocketComponent prevComp = null;
while (childIterator.hasNext()) {
RocketComponent curChild = childIterator.next();
if (curChild.isCenterline()) {
curChild.setAfter(prevComp);
prevComp = curChild;
}
}
}
}

View File

@ -2,7 +2,6 @@ package net.sf.openrocket.rocketcomponent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.startup.Application;
@ -17,15 +16,8 @@ public class PodSet extends ComponentAssembly implements OutsideComponent {
private static final Translator trans = Application.getTranslator();
private static final Logger log = LoggerFactory.getLogger(PodSet.class);
private boolean centerline = true;
private double angularPosition_rad = 0;
private double radialPosition_m = 0;
private int count = 2;
private double angularSeparation = Math.PI;
public PodSet() {
this.count = 2;
this.relativePosition = Position.BOTTOM;
}
@ -45,7 +37,6 @@ public class PodSet extends ComponentAssembly implements OutsideComponent {
@Override
public Collection<Coordinate> getComponentBounds() {
Collection<Coordinate> bounds = new ArrayList<Coordinate>(8);
double x_min = Double.MAX_VALUE;
double x_max = Double.MIN_VALUE;
double r_max = 0;
@ -120,82 +111,6 @@ public class PodSet extends ComponentAssembly implements OutsideComponent {
return false;
}
@Override
public int getInstanceCount() {
return this.count;
}
@Override
public void setInstanceCount(final int _count) {
mutex.verify();
if (this.centerline) {
return;
}
if (_count < 2) {
// there must be at least one instance....
return;
}
this.count = _count;
this.angularSeparation = Math.PI * 2 / this.count;
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
@Override
public double getAngularOffset() {
if (this.centerline) {
return 0.;
} else {
return this.angularPosition_rad;
}
}
@Override
public void setAngularOffset(final double angle_rad) {
if (this.centerline) {
return;
}
this.angularPosition_rad = angle_rad;
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
@Override
public double getRadialOffset() {
if (this.centerline) {
return 0.;
} else {
return this.radialPosition_m;
}
}
@Override
public void setRadialOffset(final double radius) {
// log.error(" set radial position for: " + this.getName() + " to: " + this.radialPosition_m + " ... in meters?");
if (false == this.centerline) {
this.radialPosition_m = radius;
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
}
public void setRelativePositionMethod(final Position _newPosition) {
if (null == this.parent) {
throw new NullPointerException(" a Stage requires a parent before any positioning! ");
}
if (this.isCenterline()) {
// Centerline stages must be set via AFTER-- regardless of what was requested:
super.setRelativePosition(Position.AFTER);
} else if (this.parent instanceof PodSet) {
if (Position.AFTER == _newPosition) {
log.warn("Stages cannot be relative to other stages via AFTER! Ignoring.");
super.setRelativePosition(Position.TOP);
} else {
super.setRelativePosition(_newPosition);
}
}
fireComponentChangeEvent(ComponentChangeEvent.AERODYNAMIC_CHANGE);
}
@Override
public double getPositionValue() {
mutex.verify();
@ -203,13 +118,6 @@ public class PodSet extends ComponentAssembly implements OutsideComponent {
return this.getAxialOffset();
}
/*
* @deprecated remove when the file is fixed....
*/
public void setRelativeToStage(final int _relToStage) {
// no-op
}
/**
* Stages may be positioned relative to other stages. In that case, this will set the stage number
* against which this stage is positioned.
@ -244,13 +152,6 @@ public class PodSet extends ComponentAssembly implements OutsideComponent {
return returnValue;
}
@Override
public void setAxialOffset(final double _pos) {
this.updateBounds();
super.setAxialOffset(this.relativePosition, _pos);
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
@Override
public Coordinate[] shiftCoordinates(Coordinate[] c) {
checkState();
@ -290,68 +191,4 @@ public class PodSet extends ComponentAssembly implements OutsideComponent {
return buf;
}
@Override
public void toDebugTreeNode(final StringBuilder buffer, final String prefix) {
String thisLabel = this.getName() + " (" + this.getStageNumber() + ")";
buffer.append(String.format("%s %-24s %5.3f", prefix, thisLabel, this.getLength()));
buffer.append(String.format(" %4.1f via: %s \n", this.getAxialOffset(), this.relativePosition.name()));
Coordinate[] relCoords = this.shiftCoordinates(new Coordinate[] { Coordinate.ZERO });
Coordinate[] absCoords = this.getLocation();
for (int instanceNumber = 0; instanceNumber < this.count; instanceNumber++) {
Coordinate instanceRelativePosition = relCoords[instanceNumber];
Coordinate instanceAbsolutePosition = absCoords[instanceNumber];
buffer.append(String.format("%s [instance %2d of %2d] %32s %32s\n", prefix, instanceNumber, count,
instanceRelativePosition, instanceAbsolutePosition));
}
}
@Override
public void updateBounds() {
// currently only updates the length
this.length = 0;
Iterator<RocketComponent> childIterator = this.getChildren().iterator();
while (childIterator.hasNext()) {
RocketComponent curChild = childIterator.next();
this.length += curChild.getLength();
}
}
@Override
protected void update() {
if (null == this.parent) {
return;
}
this.updateBounds();
this.updateBounds();
// because if parent is instanceof Stage, that means 'this' is positioned externally
super.update();
// updates the internal 'previousComponent' field.
this.updateChildSequence();
return;
}
protected void updateChildSequence() {
Iterator<RocketComponent> childIterator = this.getChildren().iterator();
RocketComponent prevComp = null;
while (childIterator.hasNext()) {
RocketComponent curChild = childIterator.next();
//curChild.previousComponent = prevComp;
curChild.setAfter(prevComp);
prevComp = curChild;
// } else {
// curChild.previousComponent = null;
}
}
}

View File

@ -884,7 +884,12 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
*
* @param position the relative positioning.
*/
protected void setRelativePosition(RocketComponent.Position position) {
protected void setRelativePosition(final RocketComponent.Position position) {
if (position == this.relativePosition) {
// no change.
return;
}
// this variable does not change the internal representation
// the relativePosition (method) is just the lens through which external code may view this component's position.
this.relativePosition = position;
@ -901,7 +906,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
*/
public double asPositionValue(Position thePosition) {
if (null == this.parent) {
return 0.0;
return Double.NaN;
}
double thisX = this.position.x;
@ -914,9 +919,6 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
break;
case ABSOLUTE:
Coordinate[] insts = this.getLocation();
if (1 < insts.length) {
return Double.NaN;
}
result = insts[0].x;
break;
case TOP:
@ -932,6 +934,12 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
throw new BugException("Unknown position type: " + thePosition);
}
// if ((this instanceof BoosterSet) && (Position.ABSOLUTE == thePosition)) {
// System.err.println("Fetching position Value for: " + this.getName() + " ( " + this.getClass().getSimpleName() + ")");
// System.err.println(" polling offset set to: " + this.position.x + " via: " + this.relativePosition.name());
// System.err.println(" resultant offset: " + result + " via: " + thePosition.name());
// }
//
return result;
}
@ -1033,7 +1041,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
this.relativePosition = positionMethod;
this.offset = newOffset;
final double EPSILON = 0.000001;
double newAxialPosition = Double.NaN;
double refLength = this.parent.getLength();
@ -1058,6 +1066,10 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
throw new BugException("Unknown position type: " + positionMethod);
}
// snap to zero if less than the threshold 'EPSILON'
if (EPSILON > Math.abs(newAxialPosition)) {
newAxialPosition = 0.0;
}
if (Double.NaN == newAxialPosition) {
throw new BugException("setAxialOffset is broken -- attempted to update as NaN: " + this.toDebugDetail());
}
@ -1167,7 +1179,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
//final Coordinate sourceLoc = this.getLocation()[0];
final Coordinate[] destLocs = dest.getLocation();
Coordinate[] toReturn = new Coordinate[destLocs.length];
for (int coordIndex = 0; coordIndex < dest.getInstanceCount(); coordIndex++) {
for (int coordIndex = 0; coordIndex < destLocs.length; coordIndex++) {
toReturn[coordIndex] = this.getLocation()[0].add(c).sub(destLocs[coordIndex]);
}
@ -2061,14 +2073,6 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
buf.append(" offset: " + this.offset + " via: " + this.relativePosition.name() + " => " + this.getAxialOffset() + "\n");
buf.append(" thisCenterX: " + this.position.x + "\n");
buf.append(" this length: " + this.length + "\n");
// if (null == this.previousComponent) {
// buf.append(" ..prevComponent: " + null + "\n");
// } else {
// RocketComponent refComp = this.previousComponent;
// buf.append(" >>prevCompName: " + refComp.getName() + "\n");
// buf.append(" ..prevCenterX: " + refComp.position.x + "\n");
// buf.append(" ..prevLength: " + refComp.getLength() + "\n");
// }
return buf;
}
@ -2076,7 +2080,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
public String toDebugTree() {
StringBuilder buffer = new StringBuilder();
buffer.append("\n ====== ====== ====== ====== ====== ====== ====== ====== ====== ====== ====== ======\n");
buffer.append(" [Name] [Length] [Rel Pos] [Abs Pos] \n");
buffer.append(" [Name] [Length] [Rel Pos] [Abs Pos] \n");
this.dumpTreeHelper(buffer, "");
return buffer.toString();
}

View File

@ -313,7 +313,7 @@ public class BoosterSetTest extends BaseTestCase {
// setup
RocketComponent rocket = createTestRocket();
AxialStage core = (AxialStage) rocket.getChild(1);
AxialStage booster = createBooster();
BoosterSet booster = createBooster();
core.addChild(booster);
double targetX = +17.0;
@ -375,7 +375,7 @@ public class BoosterSetTest extends BaseTestCase {
public void testSetStagePosition_outsideTOP() {
Rocket rocket = this.createTestRocket();
AxialStage core = (AxialStage) rocket.getChild(1);
AxialStage booster = createBooster();
BoosterSet booster = createBooster();
core.addChild(booster);
double targetOffset = +2.0;
@ -405,7 +405,7 @@ public class BoosterSetTest extends BaseTestCase {
// setup
RocketComponent rocket = createTestRocket();
AxialStage core = (AxialStage) rocket.getChild(1);
AxialStage booster = createBooster();
BoosterSet booster = createBooster();
core.addChild(booster);
// when 'external' the stage should be freely movable
@ -435,7 +435,7 @@ public class BoosterSetTest extends BaseTestCase {
// setup
RocketComponent rocket = createTestRocket();
AxialStage core = (AxialStage) rocket.getChild(1);
AxialStage booster = createBooster();
BoosterSet booster = createBooster();
core.addChild(booster);
// vv function under test
@ -464,7 +464,7 @@ public class BoosterSetTest extends BaseTestCase {
// setup
RocketComponent rocket = createTestRocket();
AxialStage core = (AxialStage) rocket.getChild(1);
AxialStage booster = createBooster();
BoosterSet booster = createBooster();
core.addChild(booster);
double targetOffset = +4.50;
@ -488,7 +488,7 @@ public class BoosterSetTest extends BaseTestCase {
// setup
RocketComponent rocket = createTestRocket();
AxialStage core = (AxialStage) rocket.getChild(1);
AxialStage booster = createBooster();
BoosterSet booster = createBooster();
core.addChild(booster);
double targetOffset = +4.50;
@ -512,7 +512,7 @@ public class BoosterSetTest extends BaseTestCase {
// setup
RocketComponent rocket = createTestRocket();
AxialStage core = (AxialStage) rocket.getChild(1);
AxialStage booster = createBooster();
BoosterSet booster = createBooster();
core.addChild(booster);
double targetOffset = +4.50;
@ -537,7 +537,7 @@ public class BoosterSetTest extends BaseTestCase {
// setup
RocketComponent rocket = createTestRocket();
AxialStage core = (AxialStage) rocket.getChild(1);
AxialStage booster = createBooster();
BoosterSet booster = createBooster();
core.addChild(booster);
@ -562,7 +562,7 @@ public class BoosterSetTest extends BaseTestCase {
// setup
RocketComponent rocket = createTestRocket();
AxialStage core = (AxialStage) rocket.getChild(1);
AxialStage booster = createBooster();
BoosterSet booster = createBooster();
core.addChild(booster);
double targetOffset = +4.50;
@ -586,7 +586,7 @@ public class BoosterSetTest extends BaseTestCase {
Rocket rocket = createTestRocket();
AxialStage core = (AxialStage) rocket.getChild(1);
AxialStage booster = new AxialStage();
BoosterSet booster = new BoosterSet();
booster.setName("Booster Stage");
core.addChild(booster);
final double targetOffset = +2.50;
@ -622,10 +622,10 @@ public class BoosterSetTest extends BaseTestCase {
public void testStageInitializationMethodValueOrder() {
Rocket rocket = createTestRocket();
AxialStage core = (AxialStage) rocket.getChild(1);
AxialStage boosterA = createBooster();
BoosterSet boosterA = createBooster();
boosterA.setName("Booster A Stage");
core.addChild(boosterA);
AxialStage boosterB = createBooster();
BoosterSet boosterB = createBooster();
boosterB.setName("Booster B Stage");
core.addChild(boosterB);
@ -653,11 +653,11 @@ public class BoosterSetTest extends BaseTestCase {
Rocket rocket = createTestRocket();
AxialStage sustainer = (AxialStage) rocket.getChild(0);
AxialStage core = (AxialStage) rocket.getChild(1);
AxialStage boosterA = createBooster();
BoosterSet boosterA = createBooster();
boosterA.setName("Booster A Stage");
core.addChild(boosterA);
boosterA.setAxialOffset(Position.BOTTOM, 0.0);
AxialStage boosterB = createBooster();
BoosterSet boosterB = createBooster();
boosterB.setName("Booster B Stage");
core.addChild(boosterB);
boosterB.setAxialOffset(Position.BOTTOM, 0);

View File

@ -1,6 +1,5 @@
package net.sf.openrocket.gui.configdialog;
import javax.swing.ComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
@ -10,18 +9,15 @@ import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.gui.SpinnerEditor;
import net.sf.openrocket.gui.adaptors.DoubleModel;
import net.sf.openrocket.gui.adaptors.EnumModel;
import net.sf.openrocket.gui.adaptors.IntegerModel;
import net.sf.openrocket.gui.components.StyledLabel;
import net.sf.openrocket.gui.components.UnitSelector;
import net.sf.openrocket.gui.components.StyledLabel.Style;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketcomponent.AxialStage;
import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.unit.UnitGroup;
public class AxialStageConfig extends RocketComponentConfig {
public class AxialStageConfig extends ComponentAssemblyConfig {
private static final long serialVersionUID = -944969957186522471L;
private static final Translator trans = Application.getTranslator();
@ -35,78 +31,8 @@ public class AxialStageConfig extends RocketComponentConfig {
trans.get("StageConfig.tab.Separation.ttip"), 1);
}
System.err.println(" building Stage Config Dialogue for: "+component.getName()+" type: "+component.getComponentName());
// only stages which are actually off-centerline will get the dialog here:
if( ! component.isCenterline()){
tabbedPane.insertTab( trans.get("RocketCompCfg.tab.Parallel"), null, parallelTab( (AxialStage) component ), trans.get("RocketCompCfg.tab.ParallelComment"), 2);
}
}
private JPanel parallelTab( final AxialStage stage ){
JPanel motherPanel = new JPanel( new MigLayout("fill"));
// set radial distance
JLabel radiusLabel = new JLabel(trans.get("StageConfig.parallel.radius"));
motherPanel.add( radiusLabel , "align left");
DoubleModel radiusModel = new DoubleModel( stage, "RadialOffset", UnitGroup.UNITS_LENGTH, 0);
//radiusModel.setCurrentUnit( UnitGroup.UNITS_LENGTH.getUnit("cm"));
JSpinner radiusSpinner = new JSpinner( radiusModel.getSpinnerModel());
radiusSpinner.setEditor(new SpinnerEditor(radiusSpinner ));
motherPanel.add(radiusSpinner , "growx 1, align right");
UnitSelector radiusUnitSelector = new UnitSelector(radiusModel);
motherPanel.add(radiusUnitSelector, "growx 1, wrap");
// set location angle around the primary stage
JLabel angleLabel = new JLabel(trans.get("StageConfig.parallel.angle"));
motherPanel.add( angleLabel, "align left");
DoubleModel angleModel = new DoubleModel( stage, "AngularOffset", 1.0, UnitGroup.UNITS_ANGLE, 0.0, Math.PI*2);
angleModel.setCurrentUnit( UnitGroup.UNITS_ANGLE.getUnit("rad"));
JSpinner angleSpinner = new JSpinner(angleModel.getSpinnerModel());
angleSpinner.setEditor(new SpinnerEditor(angleSpinner));
motherPanel.add(angleSpinner, "growx 1");
UnitSelector angleUnitSelector = new UnitSelector(angleModel);
motherPanel.add( angleUnitSelector, "growx 1, wrap");
// set multiplicity
JLabel countLabel = new JLabel(trans.get("StageConfig.parallel.count"));
motherPanel.add( countLabel, "align left");
IntegerModel countModel = new IntegerModel( stage, "InstanceCount", 2);
JSpinner countSpinner = new JSpinner(countModel.getSpinnerModel());
countSpinner.setEditor(new SpinnerEditor(countSpinner));
motherPanel.add(countSpinner, "growx 1, wrap");
// setPositions relative to parent component
JLabel positionLabel = new JLabel(trans.get("LaunchLugCfg.lbl.Posrelativeto"));
motherPanel.add( positionLabel);
// EnumModel(ChangeSource source, String valueName, Enum<T>[] values) {
ComboBoxModel<RocketComponent.Position> relativePositionMethodModel = new EnumModel<RocketComponent.Position>(component, "RelativePositionMethod",
new RocketComponent.Position[] {
RocketComponent.Position.TOP,
RocketComponent.Position.MIDDLE,
RocketComponent.Position.BOTTOM,
RocketComponent.Position.ABSOLUTE
});
JComboBox<?> positionMethodCombo = new JComboBox<RocketComponent.Position>( relativePositionMethodModel );
motherPanel.add(positionMethodCombo, "spanx 2, growx, wrap");
// relative offset labels
JLabel positionPlusLabel = new JLabel(trans.get("StageConfig.parallel.offset"));
motherPanel.add( positionPlusLabel );
DoubleModel axialOffsetModel = new DoubleModel(component, "AxialOffset", UnitGroup.UNITS_LENGTH);
axialOffsetModel.setCurrentUnit(UnitGroup.UNITS_LENGTH.getUnit("cm"));
JSpinner axPosSpin= new JSpinner( axialOffsetModel.getSpinnerModel());
axPosSpin.setEditor(new SpinnerEditor(axPosSpin));
motherPanel.add(axPosSpin, "growx");
UnitSelector axialOffsetUnitSelector = new UnitSelector(axialOffsetModel);
motherPanel.add(axialOffsetUnitSelector, "growx 1, wrap");
// For DEBUG purposes
//System.err.println(stage.getRocket().toDebugTree());
return motherPanel;
}
private JPanel separationTab(AxialStage stage) {
JPanel panel = new JPanel(new MigLayout("fill"));
@ -115,7 +41,7 @@ public class AxialStageConfig extends RocketComponentConfig {
panel.add(new StyledLabel(trans.get("StageConfig.separation.lbl.title") + " " + CommonStrings.dagger, Style.BOLD), "spanx, wrap rel");
StageSeparationConfiguration config = stage.getStageSeparationConfiguration().getDefault();
JComboBox combo = new JComboBox(new EnumModel<StageSeparationConfiguration.SeparationEvent>(config, "SeparationEvent"));
JComboBox<?> combo = new JComboBox(new EnumModel<StageSeparationConfiguration.SeparationEvent>(config, "SeparationEvent"));
panel.add(combo, "");
// ... and delay

View File

@ -0,0 +1,100 @@
package net.sf.openrocket.gui.configdialog;
import javax.swing.ComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.gui.SpinnerEditor;
import net.sf.openrocket.gui.adaptors.DoubleModel;
import net.sf.openrocket.gui.adaptors.EnumModel;
import net.sf.openrocket.gui.adaptors.IntegerModel;
import net.sf.openrocket.gui.components.UnitSelector;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.rocketcomponent.ComponentAssembly;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.unit.UnitGroup;
public class ComponentAssemblyConfig extends RocketComponentConfig {
private static final long serialVersionUID = -944969957186522471L;
private static final Translator trans = Application.getTranslator();
public ComponentAssemblyConfig(OpenRocketDocument document, RocketComponent component) {
super(document, component);
// only stages which are actually off-centerline will get the dialog here:
if(( component instanceof ComponentAssembly )&&( ! component.isCenterline() )){
tabbedPane.insertTab( trans.get("RocketCompCfg.tab.Parallel"), null, parallelTab( (ComponentAssembly) component ), trans.get("RocketCompCfg.tab.ParallelComment"), 2);
}
}
private JPanel parallelTab( final ComponentAssembly assembly ){
JPanel motherPanel = new JPanel( new MigLayout("fill"));
// set radial distance
JLabel radiusLabel = new JLabel(trans.get("StageConfig.parallel.radius"));
motherPanel.add( radiusLabel , "align left");
DoubleModel radiusModel = new DoubleModel( assembly, "RadialOffset", UnitGroup.UNITS_LENGTH, 0);
//radiusModel.setCurrentUnit( UnitGroup.UNITS_LENGTH.getUnit("cm"));
JSpinner radiusSpinner = new JSpinner( radiusModel.getSpinnerModel());
radiusSpinner.setEditor(new SpinnerEditor(radiusSpinner ));
motherPanel.add(radiusSpinner , "growx 1, align right");
UnitSelector radiusUnitSelector = new UnitSelector(radiusModel);
motherPanel.add(radiusUnitSelector, "growx 1, wrap");
// set location angle around the primary stage
JLabel angleLabel = new JLabel(trans.get("StageConfig.parallel.angle"));
motherPanel.add( angleLabel, "align left");
DoubleModel angleModel = new DoubleModel( assembly, "AngularOffset", 1.0, UnitGroup.UNITS_ANGLE, 0.0, Math.PI*2);
angleModel.setCurrentUnit( UnitGroup.UNITS_ANGLE.getUnit("rad"));
JSpinner angleSpinner = new JSpinner(angleModel.getSpinnerModel());
angleSpinner.setEditor(new SpinnerEditor(angleSpinner));
motherPanel.add(angleSpinner, "growx 1");
UnitSelector angleUnitSelector = new UnitSelector(angleModel);
motherPanel.add( angleUnitSelector, "growx 1, wrap");
// set multiplicity
JLabel countLabel = new JLabel(trans.get("StageConfig.parallel.count"));
motherPanel.add( countLabel, "align left");
IntegerModel countModel = new IntegerModel( assembly, "InstanceCount", 2);
JSpinner countSpinner = new JSpinner(countModel.getSpinnerModel());
countSpinner.setEditor(new SpinnerEditor(countSpinner));
motherPanel.add(countSpinner, "growx 1, wrap");
// setPositions relative to parent component
JLabel positionLabel = new JLabel(trans.get("LaunchLugCfg.lbl.Posrelativeto"));
motherPanel.add( positionLabel);
// EnumModel(ChangeSource source, String valueName, Enum<T>[] values) {
ComboBoxModel<RocketComponent.Position> relativePositionMethodModel = new EnumModel<RocketComponent.Position>(component, "RelativePositionMethod",
new RocketComponent.Position[] {
RocketComponent.Position.TOP,
RocketComponent.Position.MIDDLE,
RocketComponent.Position.BOTTOM,
RocketComponent.Position.ABSOLUTE
});
JComboBox<?> positionMethodCombo = new JComboBox<RocketComponent.Position>( relativePositionMethodModel );
motherPanel.add(positionMethodCombo, "spanx 2, growx, wrap");
// relative offset labels
JLabel positionPlusLabel = new JLabel(trans.get("StageConfig.parallel.offset"));
motherPanel.add( positionPlusLabel );
DoubleModel axialOffsetModel = new DoubleModel( assembly, "AxialOffset", UnitGroup.UNITS_LENGTH);
axialOffsetModel.setCurrentUnit(UnitGroup.UNITS_LENGTH.getUnit("cm"));
JSpinner axPosSpin= new JSpinner( axialOffsetModel.getSpinnerModel());
axPosSpin.setEditor(new SpinnerEditor(axPosSpin));
motherPanel.add(axPosSpin, "growx");
UnitSelector axialOffsetUnitSelector = new UnitSelector(axialOffsetModel);
motherPanel.add(axialOffsetUnitSelector, "growx 1, wrap");
// For DEBUG purposes
//System.err.println(stage.getRocket().toDebugTree());
return motherPanel;
}
}

View File

@ -23,16 +23,11 @@ import net.sf.openrocket.gui.figureelements.FigureElement;
import net.sf.openrocket.gui.util.ColorConversion;
import net.sf.openrocket.gui.util.SwingPreferences;
import net.sf.openrocket.motor.Motor;
import net.sf.openrocket.rocketcomponent.BodyTube;
import net.sf.openrocket.rocketcomponent.ClusterConfiguration;
import net.sf.openrocket.rocketcomponent.ComponentAssembly;
import net.sf.openrocket.rocketcomponent.Configuration;
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
import net.sf.openrocket.rocketcomponent.InnerTube;
import net.sf.openrocket.rocketcomponent.MotorConfiguration;
import net.sf.openrocket.rocketcomponent.MotorMount;
import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketcomponent.AxialStage;
import net.sf.openrocket.gui.rocketfigure.RocketComponentShape;
import net.sf.openrocket.gui.scalefigure.RocketPanel;
import net.sf.openrocket.startup.Application;
@ -453,7 +448,7 @@ public class RocketFigure extends AbstractScaleFigure {
// generate shapes:
if( comp instanceof Rocket){
// no-op. no shapes
}else if( comp instanceof AxialStage ){
}else if( comp instanceof ComponentAssembly ){
// no-op; no shapes here, either.
}else{
// get all shapes for this component, add to return list.