[Bugfix] Ironing out motor-instance model changes.

- renamed <RocketComponent>.getLocation() => getLocations()
    - trailing 's' matches return type
- made <RocketComponent>.shiftCoordinates protected (from public)
    => references converted to <>.getLocation() calls
- Reduced functions in "Instanceable" interface.
- Fixed Motor Instancing Code
- Removed 'isCenterline()' tester method
- added 'isAfter()' tester method
- OutsideComponent interface removed.
    => was redundant with RingInstanceable.
This commit is contained in:
Daniel_M_Williams 2015-10-20 17:22:55 -04:00
parent 3491139750
commit 8e78a314cd
30 changed files with 263 additions and 266 deletions

View File

@ -210,7 +210,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
forces.zero();
calcMap.get(component).calculateNonaxialForces(conditions, forces, warnings);
int instanceCount = component.getLocation().length;
int instanceCount = component.getLocations().length;
Coordinate x_cp_comp = forces.getCP();
Coordinate x_cp_weighted = x_cp_comp.setWeight(x_cp_comp.weight * instanceCount);
Coordinate x_cp_absolute = component.toAbsolute(x_cp_weighted)[0];

View File

@ -19,7 +19,7 @@ public class AxialStageSaver extends ComponentAssemblySaver {
public static ArrayList<String> getElements(net.sf.openrocket.rocketcomponent.RocketComponent c) {
ArrayList<String> list = new ArrayList<String>();
if (c.isCenterline()) {
if (c.isAfter()) {
// yes, this test is redundant. I'm merely paranoid, and attempting to future-proof it
if (c.getClass().equals(AxialStage.class)) {
// kept as simply 'stage' for backward compatability

View File

@ -4,7 +4,6 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import net.sf.openrocket.rocketcomponent.BoosterSet;
import net.sf.openrocket.rocketcomponent.ComponentAssembly;
import net.sf.openrocket.rocketcomponent.Instanceable;
import net.sf.openrocket.rocketcomponent.PodSet;
@ -19,16 +18,15 @@ public class ComponentAssemblySaver extends RocketComponentSaver {
public static ArrayList<String> getElements(net.sf.openrocket.rocketcomponent.RocketComponent c) {
ArrayList<String> list = new ArrayList<String>();
if (!c.isCenterline()) {
if (!c.isAfter()) {
if (c instanceof PodSet) {
list.add("<podset>");
instance.addParams(c, list);
list.add("</podset>");
} else if (c instanceof BoosterSet) {
list.add("<booster>");
instance.addParams(c, list);
list.add("</booster>");
}
// BoosterSets are saved from subclass AxialStageSaver
// else if (c instanceof BoosterSet) {
}
return list;
@ -39,7 +37,7 @@ public class ComponentAssemblySaver extends RocketComponentSaver {
super.addParams(c, elements);
ComponentAssembly ca = (ComponentAssembly) c;
if (!ca.isCenterline()) {
if (!ca.isAfter()) {
elements.addAll(this.addAssemblyInstanceParams(ca));
}

View File

@ -104,8 +104,13 @@ public class InnerBodyTubeDTO extends BodyTubeDTO implements AttachableParts {
*/
private void handleCluster(InnerTube it, AttachableParts p) {
Coordinate[] coords = { Coordinate.NUL };
coords = it.shiftCoordinates(coords);
// old version - Oct, 19 2015
//Coordinate[] coords = { Coordinate.NUL };
//coords = it.shiftCoordinates(coords);
// new version
Coordinate[] coords = it.getLocations();
for (int x = 0; x < coords.length; x++) {
InnerTube partialClone = InnerTube.makeIndividualClusterComponent(coords[x], it.getName() + " #" + (x + 1), it);
p.addAttachedPart(new InnerBodyTubeDTO(partialClone, p));

View File

@ -42,7 +42,7 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC
@Override
public Collection<Coordinate> getComponentBounds() {
Collection<Coordinate> bounds = new ArrayList<Coordinate>(8);
Coordinate[] instanceLocations = this.getLocation();
Coordinate[] instanceLocations = this.getLocations();
double x_min = instanceLocations[0].x;
double x_max = x_min + this.length;
double r_max = 0;
@ -101,7 +101,7 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC
public int getRelativeToStage() {
if (null == this.parent) {
return -1;
} else if (this.isCenterline()) {
} else if(1 == this.getInstanceCount()){
return --this.stageNumber;
} else {
return this.parent.getStageNumber();
@ -113,16 +113,15 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC
return this.stageNumber;
}
@Override
public boolean isAfter(){
return true;
}
public void setStageNumber(final int newStageNumber) {
this.stageNumber = newStageNumber;
}
@Override
public Coordinate[] shiftCoordinates(Coordinate[] c) {
checkState();
return c;
}
@Override
protected StringBuilder toDebugDetail() {
StringBuilder buf = super.toDebugDetail();

View File

@ -311,7 +311,7 @@ public class BodyTube extends SymmetricComponent implements MotorMount, Coaxial
double x_max_shape = this.length;
double r_max_shape = getOuterRadius();
Coordinate[] locs = this.getLocation();
Coordinate[] locs = this.getLocations();
// not strictly accurate, but this should provide an acceptable estimate for total vehicle size
double x_min_inst = Double.MAX_VALUE;
double x_max_inst = Double.MIN_VALUE;

View File

@ -11,7 +11,7 @@ import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.Coordinate;
public class BoosterSet extends AxialStage implements FlightConfigurableComponent, RingInstanceable, OutsideComponent {
public class BoosterSet extends AxialStage implements FlightConfigurableComponent, RingInstanceable {
private static final Translator trans = Application.getTranslator();
private static final Logger log = LoggerFactory.getLogger(BoosterSet.class);
@ -49,7 +49,7 @@ public class BoosterSet extends AxialStage implements FlightConfigurableComponen
double x_max = Double.MIN_VALUE;
double r_max = 0;
Coordinate[] instanceLocations = this.getLocation();
Coordinate[] instanceLocations = this.getLocations();
for (Coordinate currentInstanceLocation : instanceLocations) {
if (x_min > (currentInstanceLocation.x)) {
@ -102,7 +102,11 @@ public class BoosterSet extends AxialStage implements FlightConfigurableComponen
return this.count;
}
@Override
public boolean isAfter(){
return true;
}
@Override
public void setInstanceCount( final int newCount ){
mutex.verify();
@ -110,7 +114,7 @@ public class BoosterSet extends AxialStage implements FlightConfigurableComponen
// there must be at least one instance....
return;
}
System.err.println("?! Setting BoosterSet instance count to: "+newCount );
this.count = newCount;
this.angularSeparation = Math.PI * 2 / this.count;
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
@ -122,41 +126,27 @@ public class BoosterSet extends AxialStage implements FlightConfigurableComponen
}
@Override
public Coordinate[] getLocation() {
public Coordinate[] getLocations() {
if (null == this.parent) {
throw new BugException(" Attempted to get absolute position Vector of a Stage without a parent. ");
}
Coordinate[] parentInstances = this.parent.getLocation();
Coordinate[] parentInstances = this.parent.getLocations();
if (1 != parentInstances.length) {
throw new BugException(" OpenRocket does not (yet) support external stages attached to external stages. " +
"(assumed reason for getting multiple parent locations into an external stage.)");
}
parentInstances[0] = parentInstances[0].add( this.position);
Coordinate[] toReturn = this.shiftCoordinates(parentInstances);
return toReturn;
}
@Override
public boolean getOutside() {
return !isCenterline();
}
@Override
public String getPatternName(){
return (this.getInstanceCount() + "-ring");
}
/**
* Boosters are, by definition, not centerline.
*
* @return whether this Stage is along the center line of the Rocket. Always false.
*/
@Override
public boolean isCenterline() {
return false;
}
@Override
public void setRelativePositionMethod(final Position _newPosition) {
@ -191,28 +181,23 @@ public class BoosterSet extends AxialStage implements FlightConfigurableComponen
}
@Override
public Coordinate[] shiftCoordinates(Coordinate[] c) {
protected Coordinate[] shiftCoordinates(Coordinate[] c) {
checkState();
if (this.isCenterline()) {
return c;
}
if (1 < c.length) {
throw new BugException("implementation of 'shiftCoordinates' assumes the coordinate array has len == 1; this is not true, and may produce unexpected behavior! ");
throw new BugException("implementation of 'shiftCoordinates' assumes the coordinate array has len == 1; The length here is "+c.length+"! ");
}
double radius = this.radialPosition_m;
double angle0 = this.angularPosition_rad;
double angleIncr = this.angularSeparation;
Coordinate center = this.position;
Coordinate center = c[0];
Coordinate[] toReturn = new Coordinate[this.count];
Coordinate thisOffset;
//Coordinate thisOffset;
double thisAngle = angle0;
for (int instanceNumber = 0; instanceNumber < this.count; instanceNumber++) {
thisOffset = center.add(0, radius * Math.cos(thisAngle), radius * Math.sin(thisAngle));
toReturn[instanceNumber] = center.add(0, radius * Math.cos(thisAngle), radius * Math.sin(thisAngle));
toReturn[instanceNumber] = thisOffset.add(c[0]);
thisAngle += angleIncr;
}
@ -223,24 +208,16 @@ public class BoosterSet extends AxialStage implements FlightConfigurableComponen
@Override
public void toDebugTreeNode(final StringBuilder buffer, final String prefix) {
buffer.append(String.format("%s %-24s (stage: %d)", prefix, this.getName(), this.getStageNumber()));
buffer.append(String.format(" (len: %5.3f offset: %4.1f via: %s )\n", this.getLength(), this.getAxialOffset(), this.relativePosition.name()));
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));
}
Coordinate[] relCoords = this.shiftCoordinates(new Coordinate[] { Coordinate.ZERO });
Coordinate[] absCoords = this.getLocations();
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] %28s %28s\n", prefix, instanceNumber, count,
instanceRelativePosition, instanceAbsolutePosition));
}
}

View File

@ -7,6 +7,7 @@ import java.util.Iterator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.Coordinate;
@ -108,39 +109,26 @@ public abstract class ComponentAssembly extends RocketComponent {
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;
}
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 ((this instanceof BoosterSet ) || ( this instanceof PodSet )){
if (Position.AFTER == _newPosition) {
log.warn("Stages cannot be relative to other stages via AFTER! Ignoring.");
log.warn("Stages (or Pods) cannot be relative to other stages via AFTER! Ignoring.");
super.setRelativePosition(Position.TOP);
} else {
super.setRelativePosition(_newPosition);
}
}else if( this.getClass().equals( AxialStage.class)){
// Centerline stages must be set via AFTER-- regardless of what was requested:
super.setRelativePosition(Position.AFTER);
}else{
throw new BugException("Unrecognized subclass of Component Assembly. Please update this method.");
}
fireComponentChangeEvent(ComponentChangeEvent.AERODYNAMIC_CHANGE);
}
@Override
public void setOverrideSubcomponents(boolean override) {
// No-op
@ -158,13 +146,13 @@ public abstract class ComponentAssembly extends RocketComponent {
}
this.updateBounds();
if (this.isCenterline()) {
if (this.isAfter()){
// stages which are directly children of the rocket are inline, and positioned
int childNumber = this.parent.getChildPosition(this);
if (0 == childNumber) {
int thisChildNumber = this.parent.getChildPosition(this);
if (0 == thisChildNumber) {
this.setAfter(this.parent);
} else {
RocketComponent prevStage = this.parent.getChild(childNumber - 1);
RocketComponent prevStage = this.parent.getChild(thisChildNumber - 1);
this.setAfter(prevStage);
}
} else {
@ -185,7 +173,7 @@ public abstract class ComponentAssembly extends RocketComponent {
Iterator<RocketComponent> childIterator = this.getChildren().iterator();
while (childIterator.hasNext()) {
RocketComponent curChild = childIterator.next();
if (curChild.isCenterline()) {
if(curChild.isAfter()){
this.length += curChild.getLength();
}
}
@ -197,7 +185,7 @@ public abstract class ComponentAssembly extends RocketComponent {
RocketComponent prevComp = null;
while (childIterator.hasNext()) {
RocketComponent curChild = childIterator.next();
if (curChild.isCenterline()) {
if(Position.AFTER == curChild.getRelativePositionMethod()){
curChild.setAfter(prevComp);
prevComp = curChild;
}

View File

@ -144,7 +144,10 @@ public abstract class FinSet extends ExternalComponent {
this.filletMaterial = Application.getPreferences().getDefaultComponentMaterial(this.getClass(), Material.Type.BULK);
}
@Override
public boolean isAfter(){
return false;
}
/**
* Return the number of fins in the set.

View File

@ -135,8 +135,6 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
*/
public void setStageActive(final int stageNumber, final boolean _active) {
if ((0 <= stageNumber) && (stageMap.containsKey(stageNumber))) {
String activeString = (_active ? "active" : "inactive");
log.error("debug: setting stage " + stageNumber + " to " + activeString + " " + this.toDebug());
stageMap.get(stageNumber).active = _active;
fireChangeEvent();
return;
@ -149,8 +147,6 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
if ((0 <= stageNumber) && (stageMap.containsKey(stageNumber))) {
StageFlags flags = stageMap.get(stageNumber);
flags.active = !flags.active;
String activeString = (flags.active ? "active" : "inactive");
log.error("debug: toggling stage " + stageNumber + " to " + activeString + " " + this.toDebug());
fireChangeEvent();
return;
}

View File

@ -157,10 +157,10 @@ public class InnerTube extends ThicknessRingComponent implements Clusterable, Ra
}
@Override
public boolean isCenterline() {
return (1 == this.getClusterCount());
public boolean isAfter(){
return false;
}
/**
* Set the cluster scaling.
* @see #getClusterScale()
@ -215,9 +215,23 @@ public class InnerTube extends ThicknessRingComponent implements Clusterable, Ra
return list;
}
@Override
public Coordinate[] getLocations(){
if (null == this.parent) {
throw new BugException(" Attempted to get absolute position Vector of a Stage without a parent. ");
}
Coordinate[] parentInstances = this.parent.getLocations();
for( int i=0; i< parentInstances.length; i++){
parentInstances[i] = parentInstances[i].add( this.position );
}
Coordinate[] toReturn = this.shiftCoordinates(parentInstances);
return toReturn;
}
@Override
public Coordinate[] shiftCoordinates(Coordinate[] array) {
protected Coordinate[] shiftCoordinates(Coordinate[] array) {
array = super.shiftCoordinates(array);
int count = getClusterCount();
@ -372,5 +386,34 @@ public class InnerTube extends ThicknessRingComponent implements Clusterable, Ra
this.motors.printDebug();
}
@Override
public void toDebugTreeNode(final StringBuilder buffer, final String prefix) {
buffer.append(String.format("%s %-24s (cluster: %s)", prefix, this.getName(), this.getPatternName()));
buffer.append(String.format(" (len: %5.3f offset: %4.1f via: %s )\n", this.getLength(), this.getAxialOffset(), this.relativePosition.name()));
Coordinate[] relCoords = this.shiftCoordinates(new Coordinate[] { Coordinate.ZERO });
Coordinate[] absCoords = this.getLocations();
int count = this.getInstanceCount();
for (int instanceNumber = 0; instanceNumber < count; instanceNumber++) {
Coordinate instanceRelativePosition = relCoords[instanceNumber];
Coordinate instanceAbsolutePosition = absCoords[instanceNumber];
buffer.append(String.format("%s [instance %2d / %2d] %28s %28s\n", prefix, instanceNumber, count,
instanceRelativePosition, instanceAbsolutePosition));
}
if( this.hasMotor()){
MotorInstance curInstance = this.getMotorInstance(null);
Motor curMotor = curInstance.getMotor();
buffer.append(String.format("%s %-24s (cluster: %s)", prefix, curMotor.getDesignation(), this.getPatternName()));
for (int instanceNumber = 0; instanceNumber < count; instanceNumber++) {
Coordinate instanceRelativePosition = relCoords[instanceNumber];
Coordinate instanceAbsolutePosition = absCoords[instanceNumber];
buffer.append(String.format("%s [MotorInstance %2d / %2d] %28s %28s\n", prefix, instanceNumber, count,
instanceRelativePosition, instanceAbsolutePosition));
}
}else{
buffer.append(prefix+" [X] This Instance doesn't have any motors.\n");
}
}
}

View File

@ -4,23 +4,35 @@ import net.sf.openrocket.util.Coordinate;
public interface Instanceable {
/** duplicate override... especially vs shiftCoordinates...
// one of the two should be private
/**
* Note: <code> this.getLocation().length == this.getInstanceCount() </code> should ALWAYS be true. If getInstanceCount() returns anything besides 1,
* this function should be override as well.
*
* @return coordinates each instance of this component
* Note: This is function has a concrete implementation in RocketComponent.java ... it is included here only as a reminder.
*
* @return coordinates of each instance of this component -- specifically the front center of each instance
*/
public Coordinate[] getLocation();
// overrides a method in RocketComponent
// not modifiable
public boolean isCenterline();
public Coordinate[] getLocations();
/**
* How many instances of this component are represented. This should generally be editable.
* @param newCount number of instances to set
*/
public void setInstanceCount( final int newCount );
/**
* How many instances of this component are represented. This should generally be editable.
*
* @return number of instances this component currently represent.
*/
public int getInstanceCount();
public Coordinate[] shiftCoordinates(Coordinate[] c);
/**
* Get a human-readable name for this instance arrangement.
* Note: the same instance count may have different pattern names
*
* @return pattern name
*/
public String getPatternName();
}

View File

@ -39,7 +39,6 @@ public abstract class LaunchButton extends ExternalComponent implements LineInst
length = 0.03;
}
// @Override
// public double getOuterRadius() {
// return radius;
@ -102,7 +101,7 @@ public abstract class LaunchButton extends ExternalComponent implements LineInst
@Override
public boolean isCenterline() {
public boolean isAfter() {
return false;
}
@ -146,7 +145,7 @@ public abstract class LaunchButton extends ExternalComponent implements LineInst
@Override
public Coordinate[] shiftCoordinates(Coordinate[] array) {
protected Coordinate[] shiftCoordinates(Coordinate[] array) {
array = super.shiftCoordinates(array);
for (int i = 0; i < array.length; i++) {

View File

@ -99,7 +99,7 @@ public class LaunchLug extends ExternalComponent implements Coaxial, LineInstanc
@Override
public boolean isCenterline() {
public boolean isAfter() {
return false;
}
@ -143,7 +143,7 @@ public class LaunchLug extends ExternalComponent implements Coaxial, LineInstanc
@Override
public Coordinate[] shiftCoordinates(Coordinate[] array) {
protected Coordinate[] shiftCoordinates(Coordinate[] array) {
array = super.shiftCoordinates(array);
for (int i = 0; i < array.length; i++) {

View File

@ -43,6 +43,11 @@ public abstract class MassObject extends InternalComponent {
this.setPositionValue(0.0);
}
@Override
public boolean isAfter(){
return false;
}
public void setLength(double length) {
length = Math.max(length, 0);
@ -105,7 +110,8 @@ public abstract class MassObject extends InternalComponent {
* Shift the coordinates according to the radial position and direction.
*/
@Override
public final Coordinate[] shiftCoordinates(Coordinate[] array) {
protected
final Coordinate[] shiftCoordinates(Coordinate[] array) {
for (int i = 0; i < array.length; i++) {
array[i] = array[i].add(0, shiftY, shiftZ);
}

View File

@ -1,57 +0,0 @@
package net.sf.openrocket.rocketcomponent;
public interface OutsideComponent {
/**
* Indicates whether this component is located inside or outside of the rest of the rocket. (Specifically, inside or outside its parent.)
*
* @return <code> False </code> This component is aligned with its parent
* <code> True </code> This component is offset from its parent -- like an external pod, or strap-on stage
*/
public boolean getOutside();
/**
* Get the position of this component in polar coordinates
*
* @return Angular position in radians.
*/
public double getAngularOffset();
/**
* Set the position of this component in polar coordinates
*
* @param phi Angular position in radians
*/
public void setAngularOffset(final double phi);
/**
* Number of instances this stage represents
*
* @return number of instances this stage currently represents
*/
public int getInstanceCount();
/**
* Set the multiplicity of this component
*
* @param number of instances this component should represent
*/
public void setInstanceCount(final int phi);
/**
* Get the position of this component in polar coordinates
*
* @return Radial position in radians (m)
*/
public double getRadialOffset();
/**
* Get the position of this component in polar coordinates
*
* @param radius Radial distance in standard units. (m)
*/
public void setRadialOffset(final double radius);
}

View File

@ -8,7 +8,7 @@ import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.Coordinate;
public class PodSet extends ComponentAssembly implements RingInstanceable, OutsideComponent {
public class PodSet extends ComponentAssembly implements RingInstanceable {
private static final Translator trans = Application.getTranslator();
//private static final Logger log = LoggerFactory.getLogger(PodSet.class);
@ -44,7 +44,7 @@ public class PodSet extends ComponentAssembly implements RingInstanceable, Outsi
double x_max = Double.MIN_VALUE;
double r_max = 0;
Coordinate[] instanceLocations = this.getLocation();
Coordinate[] instanceLocations = this.getLocations();
for (Coordinate currentInstanceLocation : instanceLocations) {
if (x_min > (currentInstanceLocation.x)) {
@ -77,15 +77,15 @@ public class PodSet extends ComponentAssembly implements RingInstanceable, Outsi
}
@Override
public Coordinate[] getLocation() {
public Coordinate[] getLocations() {
if (null == this.parent) {
throw new BugException(" Attempted to get absolute position Vector of a Stage without a parent. ");
}
if (this.isCenterline()) {
return super.getLocation();
if (this.isAfter()) {
return super.getLocations();
} else {
Coordinate[] parentInstances = this.parent.getLocation();
Coordinate[] parentInstances = this.parent.getLocations();
if (1 != parentInstances.length) {
throw new BugException(" OpenRocket does not (yet) support external stages attached to external stages. " +
"(assumed reason for getting multiple parent locations into an external stage.)");
@ -99,18 +99,7 @@ public class PodSet extends ComponentAssembly implements RingInstanceable, Outsi
}
@Override
public boolean getOutside() {
return !isCenterline();
}
/**
* Detects if this Stage is attached directly to the Rocket (and is thus centerline)
* Or if this stage is a parallel (external) stage.
*
* @return whether this Stage is along the center line of the Rocket.
*/
@Override
public boolean isCenterline() {
public boolean isAfter() {
return false;
}
@ -141,7 +130,7 @@ public class PodSet extends ComponentAssembly implements RingInstanceable, Outsi
public double getAxialOffset() {
double returnValue = Double.NaN;
if ((this.isCenterline() && (Position.AFTER != this.relativePosition))) {
if (this.isAfter()){
// 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 {
@ -193,7 +182,7 @@ public class PodSet extends ComponentAssembly implements RingInstanceable, Outsi
}
@Override
public Coordinate[] shiftCoordinates(Coordinate[] c) {
protected Coordinate[] shiftCoordinates(Coordinate[] c) {
checkState();
if (1 < c.length) {

View File

@ -177,7 +177,7 @@ public abstract class RingComponent extends StructuralComponent implements Coaxi
* Shift the coordinates according to the radial position and direction.
*/
@Override
public Coordinate[] shiftCoordinates(Coordinate[] array) {
protected Coordinate[] shiftCoordinates(Coordinate[] array) {
for (int i = 0; i < array.length; i++) {
array[i] = array[i].add(0, shiftY, shiftZ);
}

View File

@ -271,12 +271,12 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
//////////// Methods that may be overridden ////////////
/**
* This enables one-line testing if a component is on the rocket center-line or not.
* Convenience method.
*
* @return indicates if this component is centered around the rocket's centerline
* @return indicates if a component is positioned via AFTER
*/
public boolean isCenterline() {
return true;
public boolean isAfter(){
return (Position.AFTER == this.getRelativePositionMethod());
}
@ -292,7 +292,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
* @return an array of shifted coordinates. The method may modify the contents
* of the passed array and return the array itself.
*/
public Coordinate[] shiftCoordinates(Coordinate[] c) {
protected Coordinate[] shiftCoordinates(Coordinate[] c) {
checkState();
return c;
}
@ -927,7 +927,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
result = thisX - relativeLength;
break;
case ABSOLUTE:
Coordinate[] insts = this.getLocation();
Coordinate[] insts = this.getLocations();
result = insts[0].x;
break;
case TOP:
@ -1032,8 +1032,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
// if this is the root of a hierarchy, constrain the position to zero.
if (null == this.parent) {
return;
} else if ((this.isCenterline()) && (this instanceof AxialStage)) {
// enforce AFTER
} else if ( this.isAfter()){
positionMethod = Position.AFTER;
}
checkState();
@ -1098,12 +1097,12 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
}
}
public Coordinate[] getLocation() {
public Coordinate[] getLocations() {
if (null == this.parent) {
// == improperly initialized components OR the root Rocket instance
return new Coordinate[] { Coordinate.ZERO };
} else {
Coordinate[] parentPositions = this.parent.getLocation();
Coordinate[] parentPositions = this.parent.getLocations();
int instCount = parentPositions.length;
Coordinate[] thesePositions = new Coordinate[instCount];
@ -1128,7 +1127,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
checkState();
final String lockText = "toAbsolute";
mutex.lock(lockText);
Coordinate[] thesePositions = this.getLocation();
Coordinate[] thesePositions = this.getLocations();
final int instanceCount = thesePositions.length;
@ -1177,10 +1176,10 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
// not sure if this will give us an answer, or THE answer...
//final Coordinate sourceLoc = this.getLocation()[0];
final Coordinate[] destLocs = dest.getLocation();
final Coordinate[] destLocs = dest.getLocations();
Coordinate[] toReturn = new Coordinate[destLocs.length];
for (int coordIndex = 0; coordIndex < destLocs.length; coordIndex++) {
toReturn[coordIndex] = this.getLocation()[0].add(c).sub(destLocs[coordIndex]);
toReturn[coordIndex] = this.getLocations()[0].add(c).sub(destLocs[coordIndex]);
}
mutex.unlock("toRelative");
@ -2087,7 +2086,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
public void toDebugTreeNode(final StringBuilder buffer, final String prefix) {
buffer.append(String.format("%s %-24s %5.3f %24s %24s\n", prefix, this.getName(), this.getLength(),
this.getOffset(), this.getLocation()[0]));
this.getOffset(), this.getLocations()[0]));
}
public void dumpTreeHelper(StringBuilder buffer, final String prefix) {

View File

@ -116,6 +116,10 @@ public abstract class SymmetricComponent extends BodyComponent implements Radial
return filled;
}
@Override
public boolean isAfter(){
return true;
}
/**
* Sets whether the component is set as filled. If the component is filled, then
@ -276,8 +280,6 @@ public abstract class SymmetricComponent extends BodyComponent implements Radial
return rotationalInertia;
}
/**
* Performs integration over the length of the component and updates the cached variables.
*/

View File

@ -166,6 +166,12 @@ public class TubeFinSet extends ExternalComponent {
return fins;
}
@Override
public boolean isAfter(){
return false;
}
/**
* Sets the number of fins in the set.
* @param n The number of fins, greater of equal to one.

View File

@ -4,12 +4,13 @@ package net.sf.openrocket.rocketcomponent;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import org.junit.Test;
import net.sf.openrocket.rocketcomponent.RocketComponent.Position;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.BaseTestCase.BaseTestCase;
import org.junit.Test;
public class BoosterSetTest extends BaseTestCase {
// tolerance for compared double test results
@ -127,21 +128,21 @@ public class BoosterSetTest extends BaseTestCase {
double sustainerX;
sustainerX = sustainer.getOffset().x;
assertThat(" createTestRocket failed:\n" + rocketTree + " sustainer Relative position: ", sustainerX, equalTo(expectedSustainerX));
sustainerX = sustainer.getLocation()[0].x;
sustainerX = sustainer.getLocations()[0].x;
assertThat(" createTestRocket failed:\n" + rocketTree + " sustainer Absolute position: ", sustainerX, equalTo(expectedSustainerX));
double expectedSustainerNoseX = 0;
double sustainerNosePosition = sustainerNose.getOffset().x;
assertThat(" createTestRocket failed:\n" + rocketTree + " sustainer Nose X position: ", sustainerNosePosition, equalTo(expectedSustainerNoseX));
expectedSustainerNoseX = 0;
sustainerNosePosition = sustainerNose.getLocation()[0].x;
sustainerNosePosition = sustainerNose.getLocations()[0].x;
assertThat(" createTestRocket failed:\n" + rocketTree + " sustainer Nose X position: ", sustainerNosePosition, equalTo(expectedSustainerNoseX));
double expectedSustainerBodyX = 2;
double sustainerBodyX = sustainerBody.getOffset().x;
assertThat(" createTestRocket failed:\n" + rocketTree + " sustainer body rel X position: ", sustainerBodyX, equalTo(expectedSustainerBodyX));
expectedSustainerBodyX = 2;
sustainerBodyX = sustainerBody.getLocation()[0].x;
sustainerBodyX = sustainerBody.getLocations()[0].x;
assertThat(" createTestRocket failed:\n" + rocketTree + " sustainer body abs X position: ", sustainerBodyX, equalTo(expectedSustainerBodyX));
}
@ -167,7 +168,7 @@ public class BoosterSetTest extends BaseTestCase {
coreX = core.getOffset().x;
assertThat(" createTestRocket failed:\n" + rocketTree + " core Relative position: ", coreX, equalTo(expectedCoreX));
coreX = core.getLocation()[0].x;
coreX = core.getLocations()[0].x;
assertThat(" createTestRocket failed:\n" + rocketTree + " core Absolute position: ", coreX, equalTo(expectedCoreX));
RocketComponent coreUpperBody = core.getChild(0);
@ -175,7 +176,7 @@ public class BoosterSetTest extends BaseTestCase {
double resultantX = coreUpperBody.getOffset().x;
assertThat(" createTestRocket failed:\n" + rocketTree + " core body rel X: ", resultantX, equalTo(expectedX));
expectedX = expectedCoreX;
resultantX = coreUpperBody.getLocation()[0].x;
resultantX = coreUpperBody.getLocations()[0].x;
assertThat(" createTestRocket failed:\n" + rocketTree + " core body abs X: ", resultantX, equalTo(expectedX));
RocketComponent coreLowerBody = core.getChild(1);
@ -183,7 +184,7 @@ public class BoosterSetTest extends BaseTestCase {
resultantX = coreLowerBody.getOffset().x;
assertEquals(" createTestRocket failed:\n" + rocketTree + " core body rel X: ", expectedX, resultantX, EPSILON);
expectedX = expectedCoreX + coreUpperBody.getLength();
resultantX = coreLowerBody.getLocation()[0].x;
resultantX = coreLowerBody.getLocations()[0].x;
assertEquals(" createTestRocket failed:\n" + rocketTree + " core body abs X: ", expectedX, resultantX, EPSILON);
@ -195,7 +196,7 @@ public class BoosterSetTest extends BaseTestCase {
// 5 + 1.8 + 4.2 = 11
// 11 - 4 = 7;
expectedX = 7.0;
resultantX = coreFins.getLocation()[0].x;
resultantX = coreFins.getLocations()[0].x;
assertEquals(" createTestRocket failed:\n" + rocketTree + " core Fins abs X: ", expectedX, resultantX, EPSILON);
}
@ -211,7 +212,7 @@ public class BoosterSetTest extends BaseTestCase {
// without making the rocket 'external' and the Stage should be restricted to AFTER positioning.
sustainer.setRelativePositionMethod(Position.ABSOLUTE);
assertThat("Setting a centerline stage to anything other than AFTER is ignored.", sustainer.isCenterline(), equalTo(true));
assertThat("Setting a centerline stage to anything other than AFTER is ignored.", sustainer.isAfter(), equalTo(true));
assertThat("Setting a centerline stage to anything other than AFTER is ignored.", sustainer.getRelativePosition(), equalTo(Position.AFTER));
// vv function under test
@ -222,7 +223,7 @@ public class BoosterSetTest extends BaseTestCase {
Coordinate resultantRelativePosition = sustainer.getOffset();
assertThat(" 'setAxialPosition(double)' failed:\n" + rocketTree + " Relative position: ", resultantRelativePosition.x, equalTo(expectedPosition.x));
// for all stages, the absolute position should equal the relative, because the direct parent is the rocket component (i.e. the Rocket)
Coordinate resultantAbsolutePosition = sustainer.getLocation()[0];
Coordinate resultantAbsolutePosition = sustainer.getLocations()[0];
assertThat(" 'setAxialPosition(double)' failed:\n" + rocketTree + " Absolute position: ", resultantAbsolutePosition.x, equalTo(expectedPosition.x));
}
@ -249,7 +250,7 @@ public class BoosterSetTest extends BaseTestCase {
assertThat(" 'setInstancecount(int)' failed: ", instanceCount, equalTo(expectedInstanceCount));
double expectedAbsX = 6.0;
double resultantX = set0.getLocation()[0].x;
double resultantX = set0.getLocations()[0].x;
assertEquals(">>'setAxialOffset()' failed:\n" + treeDump + " 1st Inst absolute position", expectedAbsX, resultantX, EPSILON);
double expectedRadialOffset = 4.0;
@ -285,7 +286,7 @@ public class BoosterSetTest extends BaseTestCase {
double angle = Math.PI * 2 / targetInstanceCount;
double radius = targetRadialOffset;
Coordinate[] instanceAbsoluteCoords = set0.getLocation();
Coordinate[] instanceAbsoluteCoords = set0.getLocations();
// Coordinate[] instanceRelativeCoords = new Coordinate[] { componentAbsolutePosition };
// instanceRelativeCoords = boosterSet.shiftCoordinates(instanceRelativeCoords);
@ -317,7 +318,7 @@ public class BoosterSetTest extends BaseTestCase {
core.addChild(booster);
double targetX = +17.0;
double expectedX = targetX - core.getLocation()[0].x;
double expectedX = targetX - core.getLocations()[0].x;
// when subStages should be freely movable
// vv function under test
@ -332,7 +333,7 @@ public class BoosterSetTest extends BaseTestCase {
double resultantAxialPosition = booster.getAxialOffset();
assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Relative position: ", resultantAxialPosition, equalTo(targetX));
// for all stages, the absolute position should equal the relative, because the direct parent is the rocket component (i.e. the Rocket)
Coordinate resultantAbsolutePosition = booster.getLocation()[0];
Coordinate resultantAbsolutePosition = booster.getLocations()[0];
assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Absolute position: ", resultantAbsolutePosition.x, equalTo(targetX));
}
@ -367,7 +368,7 @@ public class BoosterSetTest extends BaseTestCase {
double resultantAxialOffset = sustainer.getAxialOffset();
assertThat(" 'getAxialPosition()' failed: \n" + treeDump + " Relative position: ", resultantAxialOffset, equalTo(expectedAxialOffset));
// for all stages, the absolute position should equal the relative, because the direct parent is the rocket component (i.e. the Rocket)
Coordinate resultantAbsolutePosition = sustainer.getLocation()[0];
Coordinate resultantAbsolutePosition = sustainer.getLocations()[0];
assertThat(" 'setAbsolutePositionVector()' failed: \n" + treeDump + " Absolute position: ", resultantAbsolutePosition.x, equalTo(expectedX));
}
@ -390,7 +391,7 @@ public class BoosterSetTest extends BaseTestCase {
Coordinate resultantRelativePosition = booster.getOffset();
assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Relative position: ", resultantRelativePosition.x, equalTo(expectedRelativeX));
// for all stages, the absolute position should equal the relative, because the direct parent is the rocket component (i.e. the Rocket)
Coordinate resultantAbsolutePosition = booster.getLocation()[0];
Coordinate resultantAbsolutePosition = booster.getLocations()[0];
assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Absolute position: ", resultantAbsolutePosition.x, equalTo(expectedAbsoluteX));
double resultantAxialOffset = booster.getAxialOffset();
@ -420,7 +421,7 @@ public class BoosterSetTest extends BaseTestCase {
Coordinate resultantRelativePosition = booster.getOffset();
assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Relative position: ", resultantRelativePosition.x, equalTo(expectedRelativeX));
// for all stages, the absolute position should equal the relative, because the direct parent is the rocket component (i.e. the Rocket)
Coordinate resultantAbsolutePosition = booster.getLocation()[0];
Coordinate resultantAbsolutePosition = booster.getLocations()[0];
assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Absolute position: ", resultantAbsolutePosition.x, equalTo(expectedAbsoluteX));
double resultantPositionValue = booster.getPositionValue();
@ -449,7 +450,7 @@ public class BoosterSetTest extends BaseTestCase {
Coordinate resultantRelativePosition = booster.getOffset();
assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Relative position: ", resultantRelativePosition.x, equalTo(expectedRelativeX));
// for all stages, the absolute position should equal the relative, because the direct parent is the rocket component (i.e. the Rocket)
Coordinate resultantAbsolutePosition = booster.getLocation()[0];
Coordinate resultantAbsolutePosition = booster.getLocations()[0];
assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Absolute position: ", resultantAbsolutePosition.x, equalTo(expectedAbsoluteX));
double resultantPositionValue = booster.getPositionValue();

View File

@ -14,6 +14,7 @@ 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.AxialStage;
import net.sf.openrocket.rocketcomponent.ComponentAssembly;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.startup.Application;
@ -26,8 +27,14 @@ public class ComponentAssemblyConfig extends RocketComponentConfig {
public ComponentAssemblyConfig(OpenRocketDocument document, RocketComponent component) {
super(document, component);
// For DEBUG purposes
if( component instanceof AxialStage ){
System.err.println(" Dumping AxialStage tree info for devel / debugging.");
System.err.println(component.toDebugTree());
}
// only stages which are actually off-centerline will get the dialog here:
if(( component instanceof ComponentAssembly )&&( ! component.isCenterline() )){
if(( component instanceof ComponentAssembly )&&( 1 < component.getInstanceCount() )){
tabbedPane.insertTab( trans.get("RocketCompCfg.tab.Parallel"), null, parallelTab( (ComponentAssembly) component ), trans.get("RocketCompCfg.tab.ParallelComment"), 1);
}
}
@ -93,7 +100,7 @@ public class ComponentAssemblyConfig extends RocketComponentConfig {
motherPanel.add(axialOffsetUnitSelector, "growx 1, wrap");
// For DEBUG purposes
//System.err.println(stage.getRocket().toDebugTree());
//System.err.println(assembly.getRocket().toDebugTree());
return motherPanel;
}

View File

@ -348,8 +348,9 @@ public class InnerTubeConfig extends RocketComponentConfig {
document.addUndoPosition("Split cluster");
Coordinate[] coords = new Coordinate[]{Coordinate.NUL };
coords = component.shiftCoordinates( coords);
Coordinate[] coords = new Coordinate[]{Coordinate.ZERO };
// coords = component.shiftCoordinates( coords); // old version
coords = component.getLocations();
parent.removeChild(index);
for (int i = 0; i < coords.length; i++) {
InnerTube copy = InnerTube.makeIndividualClusterComponent(coords[i], component.getName() + " #" + (i + 1), component);

View File

@ -19,14 +19,10 @@ import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JSpinner;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.database.ComponentPresetDatabase;
@ -47,8 +43,6 @@ import net.sf.openrocket.material.Material;
import net.sf.openrocket.preset.ComponentPreset;
import net.sf.openrocket.rocketcomponent.ComponentAssembly;
import net.sf.openrocket.rocketcomponent.ExternalComponent;
import net.sf.openrocket.rocketcomponent.OutsideComponent;
import net.sf.openrocket.rocketcomponent.AxialStage;
import net.sf.openrocket.rocketcomponent.ExternalComponent.Finish;
import net.sf.openrocket.rocketcomponent.NoseCone;
import net.sf.openrocket.rocketcomponent.RocketComponent;

View File

@ -1,12 +1,12 @@
package net.sf.openrocket.gui.rocketfigure;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.Transformation;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.Transformation;
public class BodyTubeShapes extends RocketComponentShape {
@ -18,9 +18,14 @@ public class BodyTubeShapes extends RocketComponentShape {
double length = tube.getLength();
double radius = tube.getOuterRadius();
Coordinate[] instanceOffsets = new Coordinate[]{ transformation.transform( componentAbsoluteLocation )};
instanceOffsets = component.shiftCoordinates(instanceOffsets);
// old version
//Coordinate[] instanceOffsets = new Coordinate[]{ transformation.transform( componentAbsoluteLocation )};
//instanceOffsets = component.shiftCoordinates(instanceOffsets);
// new version
Coordinate[] instanceOffsets = transformation.transform( component.getLocations());
Shape[] s = new Shape[instanceOffsets.length];
for (int i=0; i < instanceOffsets.length; i++) {
s[i] = new Rectangle2D.Double((instanceOffsets[i].x)*S, //x - the X coordinate of the upper-left corner of the newly constructed Rectangle2D
@ -41,7 +46,10 @@ public class BodyTubeShapes extends RocketComponentShape {
double or = tube.getOuterRadius();
Coordinate[] instanceOffsets = new Coordinate[]{ transformation.transform( componentAbsoluteLocation )};
instanceOffsets = component.shiftCoordinates(instanceOffsets);
//instanceOffsets = component.shiftCoordinates(instanceOffsets);
instanceOffsets = component.getLocations();
Shape[] s = new Shape[instanceOffsets.length];
for (int i=0; i < instanceOffsets.length; i++) {

View File

@ -19,7 +19,7 @@ public class LaunchLugShapes extends RocketComponentShape {
double length = lug.getLength();
double radius = lug.getOuterRadius();
Coordinate[] start = transformation.transform( lug.getLocation());
Coordinate[] start = transformation.transform( lug.getLocations());
Shape[] s = new Shape[start.length];
for (int i=0; i < start.length; i++) {

View File

@ -23,8 +23,13 @@ public class RingComponentShapes extends RocketComponentShape {
double or = tube.getOuterRadius();
double ir = tube.getInnerRadius();
Coordinate[] instanceOffsets = new Coordinate[]{ transformation.transform( componentAbsoluteLocation )};
instanceOffsets = component.shiftCoordinates(instanceOffsets);
// old version
//Coordinate[] instanceOffsets = new Coordinate[]{ transformation.transform( componentAbsoluteLocation )};
//instanceOffsets = component.shiftCoordinates(instanceOffsets);
// new version
Coordinate[] instanceOffsets = transformation.transform( component.getLocations());
if ((or-ir >= 0.0012) && (ir > 0)) {
// Draw outer and inner
@ -58,8 +63,12 @@ public class RingComponentShapes extends RocketComponentShape {
double ir = tube.getInnerRadius();
Coordinate[] instanceOffsets = new Coordinate[]{ transformation.transform( componentAbsoluteLocation )};
instanceOffsets = component.shiftCoordinates(instanceOffsets);
// old version
//instanceOffsets = component.shiftCoordinates(instanceOffsets);
// new version
instanceOffsets = component.getLocations();
if ((ir < or) && (ir > 0)) {
// Draw inner and outer

View File

@ -1,12 +1,12 @@
package net.sf.openrocket.gui.rocketfigure;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.Transformation;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.Transformation;
public class TubeFinSetShapes extends RocketComponentShape {
@ -21,9 +21,12 @@ public class TubeFinSetShapes extends RocketComponentShape {
double length = finset.getLength();
double outerRadius = finset.getOuterRadius();
double bodyRadius = finset.getBodyRadius();
Coordinate[] start = new Coordinate[]{ transformation.transform( componentAbsoluteLocation )};
start = component.shiftCoordinates( start);
// old version - Oct, 19 2015
//Coordinate[] instanceOffsets = new Coordinate[]{ transformation.transform( componentAbsoluteLocation )};
//instanceOffsets = component.shiftCoordinates(instanceOffsets);
// new version
Coordinate[] start = transformation.transform( component.getLocations());
Transformation baseRotation = finset.getBaseRotationTransformation();
Transformation finRotation = finset.getFinRotationTransformation();
@ -55,8 +58,12 @@ public class TubeFinSetShapes extends RocketComponentShape {
double outerradius = finset.getOuterRadius();
double bodyradius = finset.getBodyRadius();
Coordinate[] start = new Coordinate[]{ transformation.transform( componentAbsoluteLocation.sub( 0, 0, 0) )};
start = component.shiftCoordinates( start);
// old version - Oct, 19 2015
//Coordinate[] instanceOffsets = new Coordinate[]{ transformation.transform( componentAbsoluteLocation )};
//instanceOffsets = component.shiftCoordinates(instanceOffsets);
// new version
Coordinate[] start = transformation.transform( component.getLocations());
Transformation baseRotation = finset.getBaseRotationTransformation();
Transformation finRotation = finset.getFinRotationTransformation();

View File

@ -228,8 +228,7 @@ public class RocketFigure extends AbstractScaleFigure {
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
System.err.println(" paintingComponent... ");
AffineTransform baseTransform = g2.getTransform();
// Update figure shapes if necessary
@ -353,13 +352,19 @@ public class RocketFigure extends AbstractScaleFigure {
// 3) therefore <component>.getLocation() will return all the instances of this owning component
// 4) Then, for each instance of the component, draw each cluster.
RocketComponent mountComponent = ((RocketComponent) mount);
Coordinate[] mountLocations = mountComponent.getLocation();
Coordinate[] mountLocations = mountComponent.getLocations();
double mountLength = mountComponent.getLength();
for ( Coordinate curInstanceLocation : mountLocations ){
Coordinate[] motorPositions;
Coordinate[] clusterCenterTop = new Coordinate[]{ curInstanceLocation.add( mountLength - motorLength + mount.getMotorOverhang(), 0, 0)};
motorPositions = mountComponent.shiftCoordinates(clusterCenterTop);
// old code...
// motorPositions = mountComponent.shiftCoordinates(clusterCenterTop);
// new code
motorPositions = mountComponent.getLocations();
System.err.println("the motors are probably being drawn wrong, and its probably from here.... ");
for (int i = 0; i < motorPositions.length; i++) {
motorPositions[i] = transformation.transform(motorPositions[i]);
@ -451,7 +456,7 @@ public class RocketFigure extends AbstractScaleFigure {
RocketPanel.VIEW_TYPE viewType = this.currentViewType;
Transformation viewTransform = this.transformation;
Coordinate[] locs = comp.getLocation();
Coordinate[] locs = comp.getLocations();
// generate shapes
for( Coordinate curLocation : locs){