[Bugfix] Fixed Core Positioning Code
- Launch Lugs correctly position themselves (used to default to the centerline of the rocket) added LaunchLugTest class - Booster Sets automatically adjust radial distance - based on own, and others' body radius. - Refactored shiftCoordinates(...) => getInstanceLocations()
This commit is contained in:
parent
afe56365f4
commit
ec5a3119c5
@ -21,7 +21,7 @@ import net.sf.openrocket.rocketcomponent.ExternalComponent.Finish;
|
||||
import net.sf.openrocket.rocketcomponent.FinSet;
|
||||
import net.sf.openrocket.rocketcomponent.FreeformFinSet;
|
||||
import net.sf.openrocket.rocketcomponent.InnerTube;
|
||||
import net.sf.openrocket.rocketcomponent.LaunchButton;
|
||||
import net.sf.openrocket.rocketcomponent.RailButton;
|
||||
import net.sf.openrocket.rocketcomponent.LaunchLug;
|
||||
import net.sf.openrocket.rocketcomponent.MassComponent;
|
||||
import net.sf.openrocket.rocketcomponent.MassObject;
|
||||
@ -164,9 +164,9 @@ class DocumentConfig {
|
||||
|
||||
// LaunchButton
|
||||
setters.put("LaunchButton:instancecount", new IntSetter(
|
||||
Reflection.findMethod(LaunchButton.class, "setInstanceCount",int.class)));
|
||||
Reflection.findMethod(RailButton.class, "setInstanceCount",int.class)));
|
||||
setters.put("LaunchButton:instanceseparation", new DoubleSetter(
|
||||
Reflection.findMethod( LaunchButton.class, "setInstanceSeparation", double.class)));
|
||||
Reflection.findMethod( RailButton.class, "setInstanceSeparation", double.class)));
|
||||
|
||||
// LaunchLug
|
||||
setters.put("LaunchLug:instancecount", new IntSetter(
|
||||
|
@ -14,7 +14,7 @@ import net.sf.openrocket.util.Coordinate;
|
||||
public class BoosterSet extends AxialStage implements FlightConfigurableComponent, RingInstanceable {
|
||||
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
private static final Logger log = LoggerFactory.getLogger(BoosterSet.class);
|
||||
//private static final Logger log = LoggerFactory.getLogger(BoosterSet.class);
|
||||
|
||||
protected int count = 1;
|
||||
|
||||
@ -127,7 +127,24 @@ public class BoosterSet extends AxialStage implements FlightConfigurableComponen
|
||||
|
||||
@Override
|
||||
public Coordinate[] getInstanceOffsets(){
|
||||
return this.shiftCoordinates(new Coordinate[]{Coordinate.ZERO});
|
||||
checkState();
|
||||
|
||||
final double radius = this.radialPosition_m;
|
||||
final double startAngle = this.angularPosition_rad;
|
||||
final double angleIncr = this.angularSeparation;
|
||||
Coordinate center = Coordinate.ZERO;
|
||||
|
||||
double curAngle = startAngle;
|
||||
Coordinate[] toReturn = new Coordinate[this.count];
|
||||
for (int instanceNumber = 0; instanceNumber < this.count; instanceNumber++) {
|
||||
final double curY = radius * Math.cos(curAngle);
|
||||
final double curZ = radius * Math.sin(curAngle);
|
||||
toReturn[instanceNumber] = center.add(0, curY, curZ );
|
||||
|
||||
curAngle += angleIncr;
|
||||
}
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -142,8 +159,12 @@ public class BoosterSet extends AxialStage implements FlightConfigurableComponen
|
||||
"(assumed reason for getting multiple parent locations into an external stage.)");
|
||||
}
|
||||
|
||||
parentInstances[0] = parentInstances[0].add( this.position);
|
||||
Coordinate[] toReturn = this.shiftCoordinates(parentInstances);
|
||||
final Coordinate center = parentInstances[0].add( this.position);
|
||||
Coordinate[] instanceLocations = this.getInstanceOffsets();
|
||||
Coordinate[] toReturn = new Coordinate[ instanceLocations.length];
|
||||
for( int i = 0; i < toReturn.length; i++){
|
||||
toReturn[i] = center.add( instanceLocations[i]);
|
||||
}
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
@ -185,30 +206,30 @@ public class BoosterSet extends AxialStage implements FlightConfigurableComponen
|
||||
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Coordinate[] shiftCoordinates(Coordinate[] c) {
|
||||
checkState();
|
||||
|
||||
if (1 < c.length) {
|
||||
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 = c[0];
|
||||
Coordinate[] toReturn = new Coordinate[this.count];
|
||||
//Coordinate thisOffset;
|
||||
double thisAngle = angle0;
|
||||
for (int instanceNumber = 0; instanceNumber < this.count; instanceNumber++) {
|
||||
toReturn[instanceNumber] = center.add(0, radius * Math.cos(thisAngle), radius * Math.sin(thisAngle));
|
||||
|
||||
thisAngle += angleIncr;
|
||||
}
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// protected Coordinate[] shiftCoordinates(Coordinate[] c) {
|
||||
// checkState();
|
||||
//
|
||||
// if (1 < c.length) {
|
||||
// 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 = c[0];
|
||||
// Coordinate[] toReturn = new Coordinate[this.count];
|
||||
// //Coordinate thisOffset;
|
||||
// double thisAngle = angle0;
|
||||
// for (int instanceNumber = 0; instanceNumber < this.count; instanceNumber++) {
|
||||
// toReturn[instanceNumber] = center.add(0, radius * Math.cos(thisAngle), radius * Math.sin(thisAngle));
|
||||
//
|
||||
// thisAngle += angleIncr;
|
||||
// }
|
||||
//
|
||||
// return toReturn;
|
||||
// }
|
||||
//
|
||||
|
||||
|
||||
@Override
|
||||
@ -216,7 +237,7 @@ public class BoosterSet extends AxialStage implements FlightConfigurableComponen
|
||||
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()));
|
||||
|
||||
Coordinate[] relCoords = this.shiftCoordinates(new Coordinate[] { this.getOffset() });
|
||||
Coordinate[] relCoords = this.getInstanceOffsets();
|
||||
Coordinate[] absCoords = this.getLocations();
|
||||
for (int instanceNumber = 0; instanceNumber < this.count; instanceNumber++) {
|
||||
Coordinate instanceRelativePosition = relCoords[instanceNumber];
|
||||
|
@ -102,16 +102,14 @@ public class CenteringRing extends RadiusRingComponent implements LineInstanceab
|
||||
@Override
|
||||
public Coordinate[] getInstanceOffsets(){
|
||||
Coordinate[] toReturn = new Coordinate[this.getInstanceCount()];
|
||||
toReturn[0] = Coordinate.ZERO;
|
||||
|
||||
for ( int index=1 ; index < this.getInstanceCount(); index++){
|
||||
toReturn[index] = new Coordinate(index*this.instanceSeparation,0,0,0);
|
||||
|
||||
for ( int index=0 ; index < this.getInstanceCount(); index++){
|
||||
toReturn[index] = this.position.setX( this.position.x + index*this.instanceSeparation );
|
||||
}
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getInstanceCount(){
|
||||
return this.instanceCount;
|
||||
|
@ -7,6 +7,7 @@ import net.sf.openrocket.material.Material;
|
||||
import net.sf.openrocket.preset.ComponentPreset;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.unit.UnitGroup;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
|
||||
/**
|
||||
* Class of components with well-defined physical appearance and which have an effect on
|
||||
@ -155,7 +156,6 @@ public abstract class ExternalComponent extends RocketComponent {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected List<RocketComponent> copyFrom(RocketComponent c) {
|
||||
ExternalComponent src = (ExternalComponent) c;
|
||||
|
@ -217,47 +217,73 @@ public class InnerTube extends ThicknessRingComponent implements Clusterable, Ra
|
||||
|
||||
@Override
|
||||
public Coordinate[] getInstanceOffsets(){
|
||||
return this.shiftCoordinates(new Coordinate[]{Coordinate.ZERO});
|
||||
}
|
||||
|
||||
@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
|
||||
protected Coordinate[] shiftCoordinates(Coordinate[] array) {
|
||||
array = super.shiftCoordinates(array);
|
||||
|
||||
int count = getClusterCount();
|
||||
if (count == 1)
|
||||
return array;
|
||||
int instanceCount = getClusterCount();
|
||||
if (instanceCount == 1)
|
||||
return super.getInstanceOffsets();
|
||||
|
||||
List<Coordinate> points = getClusterPoints();
|
||||
if (points.size() != count) {
|
||||
throw new BugException("Inconsistent cluster configuration, cluster count=" + count +
|
||||
" point count=" + points.size());
|
||||
if (points.size() != instanceCount) {
|
||||
throw new BugException("Inconsistent cluster configuration, cluster count(" + instanceCount +
|
||||
") != point count(" + points.size()+")");
|
||||
}
|
||||
Coordinate[] newArray = new Coordinate[array.length * count];
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
for (int j = 0; j < count; j++) {
|
||||
newArray[i * count + j] = array[i].add(points.get(j));
|
||||
}
|
||||
|
||||
|
||||
Coordinate[] newArray = new Coordinate[ instanceCount];
|
||||
for (int instanceNumber = 0; instanceNumber < instanceCount; instanceNumber++) {
|
||||
newArray[ instanceNumber] = this.position.add( points.get(instanceNumber));
|
||||
}
|
||||
|
||||
return newArray;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public Coordinate[] getLocations(){
|
||||
// if (null == this.parent) {
|
||||
// throw new BugException(" Attempted to get absolute position Vector of a Stage without a parent. ");
|
||||
// }
|
||||
//
|
||||
// final Coordinate center = parentInstances[0].add( this.position);
|
||||
// Coordinate[] instanceLocations = this.getInstanceOffsets();
|
||||
// Coordinate[] toReturn = new Coordinate[ instanceLocations.length];
|
||||
// for( int i = 0; i < toReturn.length; i++){
|
||||
// toReturn[i] = center.add( instanceLocations[i]);
|
||||
// }
|
||||
//
|
||||
// return toReturn;
|
||||
//
|
||||
// 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
|
||||
// protected Coordinate[] shiftCoordinates(Coordinate[] array) {
|
||||
// array = super.shiftCoordinates(array);
|
||||
//
|
||||
// int count = getClusterCount();
|
||||
// if (count == 1)
|
||||
// return array;
|
||||
//
|
||||
// List<Coordinate> points = getClusterPoints();
|
||||
// if (points.size() != count) {
|
||||
// throw new BugException("Inconsistent cluster configuration, cluster count=" + count +
|
||||
// " point count=" + points.size());
|
||||
// }
|
||||
// Coordinate[] newArray = new Coordinate[array.length * count];
|
||||
// for (int i = 0; i < array.length; i++) {
|
||||
// for (int j = 0; j < count; j++) {
|
||||
// newArray[i * count + j] = array[i].add(points.get(j));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return newArray;
|
||||
// }
|
||||
|
||||
//////////////// Motor mount /////////////////
|
||||
|
||||
@Override
|
||||
@ -388,19 +414,19 @@ public class InnerTube extends ThicknessRingComponent implements Clusterable, Ra
|
||||
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[] { this.getOffset() });
|
||||
Coordinate[] relCoords = this.getInstanceOffsets();
|
||||
Coordinate[] absCoords = this.getLocations();
|
||||
FlightConfigurationID curId = this.getRocket().getDefaultConfiguration().getFlightConfigurationID();
|
||||
int count = this.getInstanceCount();
|
||||
final int intanceCount = this.getInstanceCount();
|
||||
MotorInstance curInstance = this.motors.get(curId);
|
||||
//if( curInstance.isEmpty() ){
|
||||
{
|
||||
// print just the tube locations
|
||||
|
||||
for (int instanceNumber = 0; instanceNumber < count; instanceNumber++) {
|
||||
for (int instanceNumber = 0; instanceNumber < intanceCount; instanceNumber++) {
|
||||
Coordinate tubeRelativePosition = relCoords[instanceNumber];
|
||||
Coordinate tubeAbsolutePosition = absCoords[instanceNumber];
|
||||
buffer.append(String.format("%s [%2d/%2d]; %28s; %28s;\n", prefix, instanceNumber, count,
|
||||
buffer.append(String.format("%s [%2d/%2d]; %28s; %28s;\n", prefix, instanceNumber+1, intanceCount,
|
||||
tubeRelativePosition, tubeAbsolutePosition));
|
||||
}
|
||||
}
|
||||
@ -410,15 +436,15 @@ public class InnerTube extends ThicknessRingComponent implements Clusterable, Ra
|
||||
}else{
|
||||
// curInstance has a motor ...
|
||||
Motor curMotor = curInstance.getMotor();
|
||||
double motorOffset = this.getLength() - curMotor.getLength();
|
||||
final double motorOffset = this.getLength() - curMotor.getLength();
|
||||
|
||||
buffer.append(String.format("%s %-24s Thrust: %f N; (Length: %f); \n",
|
||||
prefix, curMotor.getDesignation(), curMotor.getMaxThrustEstimate(), curMotor.getLength() ));
|
||||
for (int instanceNumber = 0; instanceNumber < count; instanceNumber++) {
|
||||
for (int instanceNumber = 0; instanceNumber < intanceCount; instanceNumber++) {
|
||||
Coordinate motorRelativePosition = new Coordinate(motorOffset, 0, 0);
|
||||
Coordinate tubeAbs = absCoords[instanceNumber];
|
||||
Coordinate motorAbsolutePosition = new Coordinate(tubeAbs.x+motorOffset,tubeAbs.y,tubeAbs.z);
|
||||
buffer.append(String.format("%s [%2d/%2d]; %28s; %28s;\n", prefix, instanceNumber, count,
|
||||
buffer.append(String.format("%s [%2d/%2d]; %28s; %28s;\n", prefix, instanceNumber+1, intanceCount,
|
||||
motorRelativePosition, motorAbsolutePosition));
|
||||
}
|
||||
|
||||
|
@ -20,15 +20,12 @@ public class LaunchLug extends ExternalComponent implements Coaxial, LineInstanc
|
||||
private double thickness;
|
||||
|
||||
private double radialDirection = 0;
|
||||
protected double radialDistance = 0;
|
||||
|
||||
private int instanceCount = 1;
|
||||
private double instanceSeparation = 0; // front-front along the positive rocket axis. i.e. [1,0,0];
|
||||
|
||||
/* These are calculated when the component is first attached to any Rocket */
|
||||
private double shiftY, shiftZ;
|
||||
|
||||
|
||||
|
||||
public LaunchLug() {
|
||||
super(Position.MIDDLE);
|
||||
radius = 0.01 / 2;
|
||||
@ -113,6 +110,7 @@ public class LaunchLug extends ExternalComponent implements Coaxial, LineInstanc
|
||||
|
||||
@Override
|
||||
public void setPositionValue(double value) {
|
||||
System.err.println(" positioning "+getName()+" to: "+value);
|
||||
super.setPositionValue(value);
|
||||
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
|
||||
}
|
||||
@ -145,25 +143,29 @@ public class LaunchLug extends ExternalComponent implements Coaxial, LineInstanc
|
||||
@Override
|
||||
public Coordinate[] getInstanceOffsets(){
|
||||
Coordinate[] toReturn = new Coordinate[this.getInstanceCount()];
|
||||
toReturn[0] = Coordinate.ZERO;
|
||||
|
||||
for ( int index=1 ; index < this.getInstanceCount(); index++){
|
||||
toReturn[index] = new Coordinate(index*this.instanceSeparation,0,0,0);
|
||||
final double xOffset = this.position.x;
|
||||
final double yOffset = Math.cos(radialDirection) * (radialDistance);
|
||||
final double zOffset = Math.sin(radialDirection) * (radialDistance);
|
||||
|
||||
for ( int index=0; index < this.getInstanceCount(); index++){
|
||||
toReturn[index] = new Coordinate(xOffset + index*this.instanceSeparation, yOffset, zOffset);
|
||||
}
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Coordinate[] shiftCoordinates(Coordinate[] array) {
|
||||
array = super.shiftCoordinates(array);
|
||||
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
array[i] = array[i].add(0, shiftY, shiftZ);
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
// @Override
|
||||
// protected Coordinate[] shiftCoordinates(Coordinate[] array) {
|
||||
// array = super.shiftCoordinates(array);
|
||||
//
|
||||
// for (int i = 0; i < array.length; i++) {
|
||||
// array[i] = new Coordinate(xOffset + index*this.instanceSeparation, yOffset, zOffset);
|
||||
// array[i] = array[i].add(0, shiftY, shiftZ);
|
||||
// }
|
||||
//
|
||||
// return array;
|
||||
// }
|
||||
|
||||
|
||||
@Override
|
||||
@ -194,10 +196,7 @@ public class LaunchLug extends ExternalComponent implements Coaxial, LineInstanc
|
||||
parentRadius = Math.max(s.getRadius(x1), s.getRadius(x2));
|
||||
}
|
||||
|
||||
shiftY = Math.cos(radialDirection) * (parentRadius + radius);
|
||||
shiftZ = Math.sin(radialDirection) * (parentRadius + radius);
|
||||
|
||||
// System.out.println("Computed shift: y="+shiftY+" z="+shiftZ);
|
||||
this.radialDistance = parentRadius + radius;
|
||||
}
|
||||
|
||||
|
||||
|
@ -109,14 +109,14 @@ public abstract class MassObject extends InternalComponent {
|
||||
/**
|
||||
* Shift the coordinates according to the radial position and direction.
|
||||
*/
|
||||
@Override
|
||||
protected
|
||||
final Coordinate[] shiftCoordinates(Coordinate[] array) {
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
array[i] = array[i].add(0, shiftY, shiftZ);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
// @Override
|
||||
// protected
|
||||
// final Coordinate[] shiftCoordinates(Coordinate[] array) {
|
||||
// for (int i = 0; i < array.length; i++) {
|
||||
// array[i] = array[i].add(0, shiftY, shiftZ);
|
||||
// }
|
||||
// return array;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public final Coordinate getComponentCG() {
|
||||
|
@ -78,8 +78,26 @@ public class PodSet extends ComponentAssembly implements RingInstanceable {
|
||||
|
||||
@Override
|
||||
public Coordinate[] getInstanceOffsets(){
|
||||
return shiftCoordinates(new Coordinate[]{Coordinate.ZERO});
|
||||
checkState();
|
||||
|
||||
final double radius = this.radialPosition_m;
|
||||
final double startAngle = this.angularPosition_rad;
|
||||
final double angleIncr = this.angularSeparation;
|
||||
Coordinate center = Coordinate.ZERO;
|
||||
|
||||
double curAngle = startAngle;
|
||||
Coordinate[] toReturn = new Coordinate[this.count];
|
||||
for (int instanceNumber = 0; instanceNumber < this.count; instanceNumber++) {
|
||||
final double curY = radius * Math.cos(curAngle);
|
||||
final double curZ = radius * Math.sin(curAngle);
|
||||
toReturn[instanceNumber] = center.add(0, curY, curZ );
|
||||
|
||||
curAngle += angleIncr;
|
||||
}
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Coordinate[] getLocations() {
|
||||
@ -96,7 +114,12 @@ public class PodSet extends ComponentAssembly implements RingInstanceable {
|
||||
"(assumed reason for getting multiple parent locations into an external stage.)");
|
||||
}
|
||||
|
||||
Coordinate[] toReturn = this.shiftCoordinates(parentInstances);
|
||||
final Coordinate center = parentInstances[0].add( this.position);
|
||||
Coordinate[] instanceLocations = this.getInstanceOffsets();
|
||||
Coordinate[] toReturn = new Coordinate[ instanceLocations.length];
|
||||
for( int i = 0; i < toReturn.length; i++){
|
||||
toReturn[i] = center.add( instanceLocations[i]);
|
||||
}
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
@ -186,31 +209,6 @@ public class PodSet extends ComponentAssembly implements RingInstanceable {
|
||||
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Coordinate[] shiftCoordinates(Coordinate[] c) {
|
||||
checkState();
|
||||
|
||||
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! ");
|
||||
}
|
||||
|
||||
double radius = this.radialPosition_m;
|
||||
double angle0 = this.angularPosition_rad;
|
||||
double angleIncr = this.angularSeparation;
|
||||
Coordinate center = this.position;
|
||||
Coordinate[] toReturn = new Coordinate[this.count];
|
||||
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] = thisOffset.add(c[0]);
|
||||
thisAngle += angleIncr;
|
||||
}
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StringBuilder toDebugDetail() {
|
||||
StringBuilder buf = super.toDebugDetail();
|
||||
|
@ -5,10 +5,7 @@ import net.sf.openrocket.util.Coordinate;
|
||||
import net.sf.openrocket.util.MathUtil;
|
||||
|
||||
/**
|
||||
* An inner component that consists of a hollow cylindrical component. This can be
|
||||
* an inner tube, tube coupler, centering ring, bulkhead etc.
|
||||
*
|
||||
* The properties include the inner and outer radii, length and radial position.
|
||||
* ???
|
||||
*
|
||||
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
|
||||
*/
|
||||
|
@ -15,7 +15,7 @@ import net.sf.openrocket.util.MathUtil;
|
||||
* @author widget (Daniel Williams)
|
||||
*
|
||||
*/
|
||||
public abstract class LaunchButton extends ExternalComponent implements LineInstanceable {
|
||||
public abstract class RailButton extends ExternalComponent implements LineInstanceable {
|
||||
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
@ -32,7 +32,7 @@ public abstract class LaunchButton extends ExternalComponent implements LineInst
|
||||
|
||||
|
||||
|
||||
public LaunchButton() {
|
||||
public RailButton() {
|
||||
super(Position.MIDDLE);
|
||||
radius = 0.01 / 2;
|
||||
thickness = 0.001;
|
||||
@ -154,16 +154,16 @@ public abstract class LaunchButton extends ExternalComponent implements LineInst
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Coordinate[] shiftCoordinates(Coordinate[] array) {
|
||||
array = super.shiftCoordinates(array);
|
||||
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
array[i] = array[i].add(0, shiftY, shiftZ);
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
// @Override
|
||||
// protected Coordinate[] shiftCoordinates(Coordinate[] array) {
|
||||
// array = super.shiftCoordinates(array);
|
||||
//
|
||||
// for (int i = 0; i < array.length; i++) {
|
||||
// array[i] = array[i].add(0, shiftY, shiftZ);
|
||||
// }
|
||||
//
|
||||
// return array;
|
||||
// }
|
||||
|
||||
|
||||
@Override
|
@ -171,20 +171,7 @@ public abstract class RingComponent extends StructuralComponent implements Coaxi
|
||||
return ((Clusterable) this).getClusterConfiguration().getClusterCount();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Shift the coordinates according to the radial position and direction.
|
||||
*/
|
||||
@Override
|
||||
protected Coordinate[] shiftCoordinates(Coordinate[] array) {
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
array[i] = array[i].add(0, shiftY, shiftZ);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Collection<Coordinate> getComponentBounds() {
|
||||
List<Coordinate> bounds = new ArrayList<Coordinate>();
|
||||
|
@ -276,7 +276,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
||||
* @return indicates if a component is positioned via AFTER
|
||||
*/
|
||||
public boolean isAfter(){
|
||||
return (Position.AFTER == this.getRelativePositionMethod());
|
||||
return (Position.AFTER == this.relativePosition);
|
||||
}
|
||||
|
||||
|
||||
@ -292,10 +292,10 @@ 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.
|
||||
*/
|
||||
protected Coordinate[] shiftCoordinates(Coordinate[] c) {
|
||||
checkState();
|
||||
return c;
|
||||
}
|
||||
// protected Coordinate[] shiftCoordinates(Coordinate[] c) {
|
||||
// checkState();
|
||||
// return c;
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
@ -943,12 +943,6 @@ 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;
|
||||
}
|
||||
|
||||
@ -997,10 +991,6 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
||||
setAxialOffset(value);
|
||||
}
|
||||
|
||||
public void setAxialOffset(double _value) {
|
||||
this.setAxialOffset(this.relativePosition, _value);
|
||||
this.fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
|
||||
}
|
||||
|
||||
protected void setAfter(RocketComponent referenceComponent) {
|
||||
checkState();
|
||||
@ -1028,23 +1018,29 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
||||
this.position = new Coordinate(newAxialPosition, this.position.y, this.position.z);
|
||||
}
|
||||
|
||||
protected void setAxialOffset(Position positionMethod, double newOffset) {
|
||||
// if this is the root of a hierarchy, constrain the position to zero.
|
||||
if (null == this.parent) {
|
||||
return;
|
||||
} else if ( this.isAfter()){
|
||||
positionMethod = Position.AFTER;
|
||||
}
|
||||
public void setAxialOffset(double _value) {
|
||||
this.setAxialOffset(this.relativePosition, _value);
|
||||
this.fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
|
||||
}
|
||||
|
||||
protected void setAxialOffset(final Position positionMethod, final double newOffset) {
|
||||
checkState();
|
||||
|
||||
this.relativePosition = positionMethod;
|
||||
this.offset = newOffset;
|
||||
|
||||
if ( this.isAfter()){
|
||||
relativePosition = Position.AFTER;
|
||||
}else{
|
||||
this.relativePosition = positionMethod;
|
||||
}
|
||||
if (null == this.parent) {
|
||||
// if this is the root of a hierarchy, constrain the position to zero.
|
||||
this.offset = newOffset;
|
||||
this.position= Coordinate.ZERO;
|
||||
return;
|
||||
}
|
||||
|
||||
final double EPSILON = 0.000001;
|
||||
double newAxialPosition = Double.NaN;
|
||||
double refLength = this.parent.getLength();
|
||||
|
||||
switch (positionMethod) {
|
||||
final double refLength = this.parent.getLength();
|
||||
switch (this.relativePosition) {
|
||||
case ABSOLUTE:
|
||||
newAxialPosition = newOffset - this.parent.position.x;
|
||||
break;
|
||||
@ -1062,7 +1058,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
||||
newAxialPosition = (refLength - this.length) + newOffset;
|
||||
break;
|
||||
default:
|
||||
throw new BugException("Unknown position type: " + positionMethod);
|
||||
throw new BugException("Unknown position type: " + this.relativePosition);
|
||||
}
|
||||
|
||||
// snap to zero if less than the threshold 'EPSILON'
|
||||
@ -1072,7 +1068,19 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
||||
if (Double.NaN == newAxialPosition) {
|
||||
throw new BugException("setAxialOffset is broken -- attempted to update as NaN: " + this.toDebugDetail());
|
||||
}
|
||||
this.offset = newOffset;
|
||||
this.position = new Coordinate(newAxialPosition, this.position.y, this.position.z);
|
||||
|
||||
// if( this instanceof CenteringRing ){
|
||||
// System.err.println("Moving "+this.getName()+"("+this.getID().substring(0, 8)+") to:"+newOffset+" via:"+positionMethod.name());
|
||||
// System.err.println(" new Position = "+this.position);
|
||||
// if( positionMethod == Position.BOTTOM){
|
||||
// StackTraceElement[] stack = Thread.currentThread().getStackTrace();
|
||||
// for( int i = 0; i < 12 ; i++){
|
||||
// System.err.println( stack[i]);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
protected void update() {
|
||||
@ -1081,12 +1089,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
||||
|
||||
public Coordinate getOffset() {
|
||||
return this.position;
|
||||
}
|
||||
|
||||
// public Coordinate[] getOffset() {
|
||||
// return new Coordinate[]{this.position};
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated kept around as example code. instead use getLocations
|
||||
@ -1101,17 +1104,50 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns coordinates of this component's instances in relation to this.parent.
|
||||
* <p>
|
||||
* For example, the absolute position of any given instance is the parent's position
|
||||
* plus the instance position returned by this method
|
||||
* <p>
|
||||
* NOTE: this default implementation simply returns this.position
|
||||
* NOTE: the length of this array returned always equals this.getInstanceCount()
|
||||
*
|
||||
* @param c an array of coordinates to shift.
|
||||
* @return an array of shifted coordinates. The method may modify the contents
|
||||
* of the passed array and return the array itself.
|
||||
*/
|
||||
// @Override Me !
|
||||
public Coordinate[] getInstanceOffsets(){
|
||||
return new Coordinate[]{this.position};
|
||||
}
|
||||
|
||||
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.getLocations();
|
||||
int instCount = parentPositions.length;
|
||||
Coordinate[] thesePositions = new Coordinate[instCount];
|
||||
int parentCount = parentPositions.length;
|
||||
|
||||
for (int pi = 0; pi < instCount; pi++) {
|
||||
thesePositions[pi] = parentPositions[pi].add(this.getOffset());
|
||||
// override <instance>.getInstanceOffsets() in the subclass you want to fix.
|
||||
Coordinate[] instanceOffsets = this.getInstanceOffsets();
|
||||
int instanceCount = instanceOffsets.length;
|
||||
|
||||
// usual case optimization
|
||||
if((1 == parentCount)&&(1 == instanceCount)){
|
||||
return new Coordinate[]{parentPositions[0].add(instanceOffsets[0])};
|
||||
}
|
||||
|
||||
int thisCount = instanceCount*parentCount;
|
||||
Coordinate[] thesePositions = new Coordinate[thisCount];
|
||||
for (int pi = 0; pi < parentCount; pi++) {
|
||||
for( int ii = 0; ii < instanceCount; ii++ ){
|
||||
// System.err.println(" #"+pi+", "+ii+" = "+(pi + parentCount*ii));
|
||||
// System.err.println(" "+parentPositions[pi]+" + "+instanceOffsets[ii]);
|
||||
thesePositions[pi + parentCount*ii] = parentPositions[pi].add(instanceOffsets[ii]);
|
||||
// System.err.println(" ="+thesePositions[pi+parentCount*ii]);
|
||||
}
|
||||
}
|
||||
return thesePositions;
|
||||
}
|
||||
@ -1190,15 +1226,15 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
protected static final Coordinate[] rebase(final Coordinate toMove[], final Coordinate source, final Coordinate dest) {
|
||||
final Coordinate delta = source.sub(dest);
|
||||
Coordinate[] toReturn = new Coordinate[toMove.length];
|
||||
for (int coordIndex = 0; coordIndex < toMove.length; coordIndex++) {
|
||||
toReturn[coordIndex] = toMove[coordIndex].add(delta);
|
||||
}
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
// protected static final Coordinate[] rebase(final Coordinate toMove[], final Coordinate source, final Coordinate dest) {
|
||||
// final Coordinate delta = source.sub(dest);
|
||||
// Coordinate[] toReturn = new Coordinate[toMove.length];
|
||||
// for (int coordIndex = 0; coordIndex < toMove.length; coordIndex++) {
|
||||
// toReturn[coordIndex] = toMove[coordIndex].add(delta);
|
||||
// }
|
||||
//
|
||||
// return toReturn;
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
@ -2085,8 +2121,8 @@ 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.getLocations()[0]));
|
||||
buffer.append(String.format("%-42s; %5.3f; %24s; %24s;\n", prefix+" "+this.getName(),
|
||||
this.getLength(), this.getOffset(), this.getLocations()[0]));
|
||||
}
|
||||
|
||||
public void dumpTreeHelper(StringBuilder buffer, final String prefix) {
|
||||
|
@ -27,6 +27,7 @@ import net.sf.openrocket.rocketcomponent.CenteringRing;
|
||||
import net.sf.openrocket.rocketcomponent.ClusterConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.DeploymentConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.DeploymentConfiguration.DeployEvent;
|
||||
import net.sf.openrocket.rocketcomponent.EngineBlock;
|
||||
import net.sf.openrocket.rocketcomponent.ExternalComponent;
|
||||
import net.sf.openrocket.rocketcomponent.ExternalComponent.Finish;
|
||||
import net.sf.openrocket.rocketcomponent.FinSet.CrossSection;
|
||||
@ -316,8 +317,9 @@ public class TestRockets {
|
||||
public static final Rocket makeEstesAlphaIII(){
|
||||
|
||||
Rocket rocket = new Rocket();
|
||||
rocket.setName("Estes Alpha III / Code Verification Rocket");
|
||||
AxialStage stage = new AxialStage();
|
||||
stage.setName("Stage1");
|
||||
stage.setName("Stage");
|
||||
rocket.addChild(stage);
|
||||
|
||||
double noseconeLength = 0.06985;
|
||||
@ -325,14 +327,31 @@ public class TestRockets {
|
||||
NoseCone nosecone = new NoseCone(Transition.Shape.ELLIPSOID, noseconeLength, noseconeRadius);
|
||||
nosecone.setAftShoulderLength(0.02479);
|
||||
nosecone.setAftShoulderRadius(0.011811);
|
||||
nosecone.setName("Nose Cone");
|
||||
stage.addChild(nosecone);
|
||||
|
||||
double bodytubeLength = 0.19685;
|
||||
double bodytubeRadius = 0.012395;
|
||||
double bodytubeThickness = 0.00033;
|
||||
BodyTube bodytube = new BodyTube(bodytubeLength, bodytubeRadius, bodytubeThickness);
|
||||
bodytube.setName("Body Tube");
|
||||
stage.addChild(bodytube);
|
||||
|
||||
TrapezoidFinSet finset;
|
||||
{
|
||||
int finCount = 3;
|
||||
double finRootChord = .05715;
|
||||
double finTipChord = .03048;
|
||||
double finSweep = 0.06985455;
|
||||
double finHeight = 0.04064;
|
||||
finset = new TrapezoidFinSet(finCount, finRootChord, finTipChord, finSweep, finHeight);
|
||||
finset.setThickness( 0.003175);
|
||||
finset.setRelativePosition(Position.BOTTOM);
|
||||
finset.setName("3 Fin Set");
|
||||
bodytube.addChild(finset);
|
||||
|
||||
LaunchLug lug = new LaunchLug();
|
||||
lug.setName("Launch Lugs");
|
||||
lug.setRelativePosition(Position.TOP);
|
||||
lug.setAxialOffset(0.111125);
|
||||
lug.setLength(0.0508);
|
||||
@ -347,21 +366,40 @@ public class TestRockets {
|
||||
inner.setOuterRadius(0.009347);
|
||||
inner.setThickness(0.00033);
|
||||
inner.setMotorMount(true);
|
||||
inner.setName("Motor Mount Tube");
|
||||
bodytube.addChild(inner);
|
||||
|
||||
// omit other internal components... this method does not return a flyable version of the Mk 2
|
||||
}
|
||||
stage.addChild(bodytube);
|
||||
{
|
||||
// MotorBlock
|
||||
EngineBlock thrustBlock= new EngineBlock();
|
||||
thrustBlock.setRelativePosition(Position.TOP);
|
||||
thrustBlock.setAxialOffset(0.0);
|
||||
thrustBlock.setLength(0.005004);
|
||||
thrustBlock.setOuterRadius(0.0090169);
|
||||
thrustBlock.setThickness(0.00075);
|
||||
thrustBlock.setName("Engine Block");
|
||||
inner.addChild(thrustBlock);
|
||||
}
|
||||
|
||||
int finCount = 3;
|
||||
double finRootChord = .05715;
|
||||
double finTipChord = .03048;
|
||||
double finSweep = 0.06985455;
|
||||
double finHeight = 0.04064;
|
||||
TrapezoidFinSet finset = new TrapezoidFinSet(finCount, finRootChord, finTipChord, finSweep, finHeight);
|
||||
finset.setThickness( 0.003175);
|
||||
finset.setRelativePosition(Position.BOTTOM);
|
||||
bodytube.addChild(finset);
|
||||
// parachute
|
||||
Parachute chute = new Parachute();
|
||||
chute.setRelativePosition(Position.TOP);
|
||||
chute.setName("Parachute");
|
||||
chute.setAxialOffset(0.028575);
|
||||
chute.setOverrideMass(0.002041);
|
||||
chute.setMassOverridden(true);
|
||||
bodytube.addChild(chute);
|
||||
|
||||
// bulkhead x2
|
||||
CenteringRing centerings = new CenteringRing();
|
||||
centerings.setName("Centering Rings");
|
||||
centerings.setRelativePosition(Position.TOP);
|
||||
centerings.setAxialOffset(0.1397);
|
||||
centerings.setLength(0.00635);
|
||||
centerings.setInstanceCount(2);
|
||||
centerings.setInstanceSeparation(0.035);
|
||||
bodytube.addChild(centerings);
|
||||
}
|
||||
|
||||
Material material = Application.getPreferences().getDefaultComponentMaterial(null, Material.Type.BULK);
|
||||
nosecone.setMaterial(material);
|
||||
|
@ -0,0 +1,74 @@
|
||||
package net.sf.openrocket.rocketcomponent;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent.Position;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
import net.sf.openrocket.util.MathUtil;
|
||||
import net.sf.openrocket.util.TestRockets;
|
||||
import net.sf.openrocket.util.BaseTestCase.BaseTestCase;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class LaunchLugTest extends BaseTestCase {
|
||||
protected final double EPSILON = MathUtil.EPSILON;
|
||||
|
||||
@Test
|
||||
public void testLaunchLugLocationZeroAngle() {
|
||||
Rocket rocket = TestRockets.makeEstesAlphaIII();
|
||||
|
||||
BodyTube body= (BodyTube)rocket.getChild(0).getChild(1);
|
||||
LaunchLug lug = (LaunchLug)rocket.getChild(0).getChild(1).getChild(1);
|
||||
lug.setInstanceSeparation(0.05);
|
||||
lug.setInstanceCount(2);
|
||||
|
||||
double expX = 0.111125 + body.getLocations()[0].x;
|
||||
double expR = body.getOuterRadius()+lug.getOuterRadius();
|
||||
Coordinate expPos = new Coordinate( expX, expR, 0, 0);
|
||||
Coordinate actPos[] = lug.getLocations();
|
||||
assertEquals(" LaunchLug has the wrong x value: ", expPos.x, actPos[0].x, EPSILON);
|
||||
assertEquals(" LaunchLug has the wrong y value: ", expPos.y, actPos[0].y, EPSILON);
|
||||
assertEquals(" LaunchLug has the wrong z value: ", expPos.z, actPos[0].z, EPSILON);
|
||||
assertEquals(" LaunchLug has the wrong weight: ", 0, actPos[0].weight, EPSILON);
|
||||
assertEquals(" LaunchLug #1 is in the wrong place: ", expPos, actPos[0]);
|
||||
|
||||
expPos = expPos.setX( expX+0.05 );
|
||||
assertEquals(" LaunchLug #2 is in the wrong place: ", expPos, actPos[1]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLaunchLugLocationAtAngles() {
|
||||
Rocket rocket = TestRockets.makeEstesAlphaIII();
|
||||
|
||||
BodyTube body= (BodyTube)rocket.getChild(0).getChild(1);
|
||||
LaunchLug lug = (LaunchLug)rocket.getChild(0).getChild(1).getChild(1);
|
||||
double startAngle = Math.PI/2;
|
||||
lug.setRadialDirection( startAngle );
|
||||
lug.setInstanceSeparation(0.05);
|
||||
lug.setInstanceCount(2);
|
||||
System.err.println("..created lug: at : " + lug.getInstanceOffsets()[0]);
|
||||
System.err.println(" angle: "+startAngle/Math.PI*180+" deg ");
|
||||
|
||||
//String treeDump = rocket.toDebugTree();
|
||||
//System.err.println(treeDump);
|
||||
|
||||
|
||||
double expX = 0.111125 + body.getLocations()[0].x;
|
||||
double expR = 0.015376;
|
||||
double expY = Math.cos(startAngle)*expR ;
|
||||
double expZ = Math.sin(startAngle)*expR ;
|
||||
Coordinate expPos = new Coordinate( expX, expY, expZ, 0);
|
||||
Coordinate actPos[] = lug.getLocations();
|
||||
assertEquals(" LaunchLug has the wrong x value: ", expPos.x, actPos[0].x, EPSILON);
|
||||
assertEquals(" LaunchLug has the wrong y value: ", expPos.y, actPos[0].y, EPSILON);
|
||||
assertEquals(" LaunchLug has the wrong z value: ", expPos.z, actPos[0].z, EPSILON);
|
||||
assertEquals(" LaunchLug has the wrong weight: ", 0, actPos[0].weight, EPSILON);
|
||||
assertEquals(" LaunchLug is in the wrong place: ", expPos, actPos[0]);
|
||||
|
||||
if( 1 < actPos.length){
|
||||
expPos = expPos.setX( expX+0.05 );
|
||||
assertEquals(" LaunchLug #2 is in the wrong place: ", expPos, actPos[1]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,15 @@
|
||||
package net.sf.openrocket.rocketcomponent;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
import net.sf.openrocket.material.Material;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent.Position;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
import net.sf.openrocket.util.MathUtil;
|
||||
import net.sf.openrocket.util.TestRockets;
|
||||
import net.sf.openrocket.util.BaseTestCase.BaseTestCase;
|
||||
|
||||
import org.junit.Test;
|
||||
@ -8,16 +18,115 @@ public class RocketTest extends BaseTestCase {
|
||||
|
||||
@Test
|
||||
public void testCopyFrom() {
|
||||
Rocket r1 = net.sf.openrocket.util.TestRockets.makeIsoHaisu();
|
||||
Rocket r2 = net.sf.openrocket.util.TestRockets.makeBigBlue();
|
||||
// Rocket r1 = net.sf.openrocket.util.TestRockets.makeIsoHaisu();
|
||||
// Rocket r2 = net.sf.openrocket.util.TestRockets.makeBigBlue();
|
||||
//
|
||||
// Rocket copy = (Rocket) r2.copy();
|
||||
//
|
||||
// ComponentCompare.assertDeepEquality(r2, copy);
|
||||
//
|
||||
// r1.copyFrom(copy);
|
||||
//
|
||||
// ComponentCompare.assertDeepEquality(r1, r2);
|
||||
fail("NYI");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEstesAlphaIII(){
|
||||
final double EPSILON = MathUtil.EPSILON;
|
||||
Rocket rocket = TestRockets.makeEstesAlphaIII();
|
||||
|
||||
// String treeDump = rocket.toDebugTree();
|
||||
// System.err.println(treeDump);
|
||||
|
||||
Rocket copy = (Rocket) r2.copy();
|
||||
AxialStage stage= (AxialStage)rocket.getChild(0);
|
||||
|
||||
ComponentCompare.assertDeepEquality(r2, copy);
|
||||
NoseCone nose = (NoseCone)stage.getChild(0);
|
||||
BodyTube body = (BodyTube)stage.getChild(1);
|
||||
FinSet fins = (FinSet)body.getChild(0);
|
||||
LaunchLug lug = (LaunchLug)body.getChild(1);
|
||||
InnerTube mmt = (InnerTube)body.getChild(2);
|
||||
EngineBlock block = (EngineBlock)mmt.getChild(0);
|
||||
Parachute chute = (Parachute)body.getChild(3);
|
||||
CenteringRing center = (CenteringRing)body.getChild(4);
|
||||
|
||||
r1.copyFrom(copy);
|
||||
|
||||
ComponentCompare.assertDeepEquality(r1, r2);
|
||||
RocketComponent cc;
|
||||
Coordinate expLoc;
|
||||
Coordinate actLoc;
|
||||
{
|
||||
cc = nose;
|
||||
expLoc = new Coordinate(0,0,0);
|
||||
actLoc = cc.getLocations()[0];
|
||||
assertThat(cc.getName()+" not positioned correctly: ", actLoc, equalTo(expLoc));
|
||||
|
||||
cc = body;
|
||||
expLoc = new Coordinate(0.06985,0,0);
|
||||
actLoc = cc.getLocations()[0];
|
||||
assertThat(cc.getName()+" not positioned correctly: ", actLoc, equalTo(expLoc));
|
||||
|
||||
{
|
||||
cc = fins;
|
||||
expLoc = new Coordinate(0.20955,0,0);
|
||||
actLoc = cc.getLocations()[0];
|
||||
assertThat(cc.getName()+" not positioned correctly: ", actLoc, equalTo(expLoc));
|
||||
|
||||
cc = lug;
|
||||
expLoc = new Coordinate(0.180975, 0.015376, 0);
|
||||
actLoc = cc.getLocations()[0];
|
||||
assertThat(cc.getName()+" not positioned correctly: ", actLoc, equalTo(expLoc));
|
||||
|
||||
cc = mmt;
|
||||
expLoc = new Coordinate(0.2032,0,0);
|
||||
actLoc = cc.getLocations()[0];
|
||||
assertThat(cc.getName()+" not positioned correctly: ", actLoc, equalTo(expLoc));
|
||||
{
|
||||
cc = block;
|
||||
expLoc = new Coordinate(0.2032,0,0);
|
||||
actLoc = cc.getLocations()[0];
|
||||
assertThat(cc.getName()+" not positioned correctly: ", actLoc, equalTo(expLoc));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cc = chute;
|
||||
expLoc = new Coordinate(0.098425,0,0);
|
||||
actLoc = cc.getLocations()[0];
|
||||
assertThat(cc.getName()+" not positioned correctly: ", actLoc, equalTo(expLoc));
|
||||
|
||||
cc = center;
|
||||
assertThat(cc.getName()+" not instanced correctly: ", cc.getInstanceCount(), equalTo(2));
|
||||
// singleton instances follow different code paths
|
||||
center.setInstanceCount(1);
|
||||
expLoc = new Coordinate(0.20955,0,0);
|
||||
actLoc = cc.getLocations()[0];
|
||||
assertEquals(" position x fail: ", expLoc.x, actLoc.x, EPSILON);
|
||||
assertEquals(" position y fail: ", expLoc.y, actLoc.y, EPSILON);
|
||||
assertEquals(" position z fail: ", expLoc.z, actLoc.z, EPSILON);
|
||||
assertThat(cc.getName()+" not positioned correctly: ", actLoc, equalTo(expLoc));
|
||||
|
||||
cc = center;
|
||||
center.setInstanceCount(2);
|
||||
Coordinate actLocs[] = cc.getLocations();
|
||||
expLoc = new Coordinate(0.20955,0,0);
|
||||
actLoc = actLocs[0];
|
||||
// assertEquals(" position x fail: ", expLoc.x, actLoc.x, EPSILON);
|
||||
// assertEquals(" position y fail: ", expLoc.y, actLoc.y, EPSILON);
|
||||
// assertEquals(" position z fail: ", expLoc.z, actLoc.z, EPSILON);
|
||||
assertThat(cc.getName()+" not positioned correctly: ", actLoc, equalTo(expLoc));
|
||||
{ // second instance
|
||||
expLoc = new Coordinate(0.24455, 0, 0);
|
||||
actLoc = actLocs[1];
|
||||
assertThat(cc.getName()+" not positioned correctly: ", actLoc, equalTo(expLoc));
|
||||
}
|
||||
{ // second instance
|
||||
assertThat(cc.getName()+" not instanced correctly: ", cc.getInstanceCount(), equalTo(2));
|
||||
expLoc = new Coordinate(0.24455, 0, 0);
|
||||
actLoc = actLocs[1];
|
||||
assertThat(cc.getName()+" not positioned correctly: ", actLoc, equalTo(expLoc));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user