[refactor] added code to tests for negative inertia / intersection case
This commit is contained in:
parent
cf4a935302
commit
01fd20ebcc
@ -439,17 +439,25 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
|
||||
* 5. Return twice that since there is a fillet on each side of the fin.
|
||||
*/
|
||||
protected Coordinate calculateFilletVolumeCentroid() {
|
||||
if((null == this.parent) || (!SymmetricComponent.class.isAssignableFrom(this.parent.getClass()))){
|
||||
return Coordinate.ZERO;
|
||||
}
|
||||
Coordinate[] mountPoints = this.getRootPoints();
|
||||
if( null == mountPoints ){
|
||||
// if( null == mountPoints ){
|
||||
// return Coordinate.ZERO;
|
||||
// }
|
||||
|
||||
final SymmetricComponent sym = (SymmetricComponent) this.parent;
|
||||
|
||||
final Coordinate finLead = getFinFront();
|
||||
final double xFinEnd = finLead.x + getLength();
|
||||
final Coordinate[] rootPoints = getMountPoints( finLead.x, xFinEnd, -finLead.x, -finLead.y);
|
||||
if (0 == rootPoints.length) {
|
||||
return Coordinate.ZERO;
|
||||
}
|
||||
|
||||
final SymmetricComponent sym = (SymmetricComponent) this.parent;
|
||||
if (!SymmetricComponent.class.isInstance(this.parent)) {
|
||||
return Coordinate.ZERO;
|
||||
}
|
||||
|
||||
Coordinate filletVolumeCentroid = Coordinate.ZERO;
|
||||
|
||||
Coordinate prev = mountPoints[0];
|
||||
for (int index = 1; index < mountPoints.length; index++) {
|
||||
final Coordinate cur = mountPoints[index];
|
||||
@ -470,7 +478,7 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
|
||||
|
||||
prev = cur;
|
||||
}
|
||||
|
||||
|
||||
if (finCount == 1) {
|
||||
Transformation rotation = Transformation.rotate_x( getAngleOffset());
|
||||
return rotation.transform(filletVolumeCentroid);
|
||||
@ -496,10 +504,9 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
|
||||
for( int index = 1; index < points.length; index++){
|
||||
Coordinate cur = points[index];
|
||||
|
||||
// calculate marginal area
|
||||
final double delta_x = (cur.x - prev.x);
|
||||
final double y_avg = (cur.y + prev.y)*0.5;
|
||||
|
||||
// calculate marginal area
|
||||
double area_increment = delta_x*y_avg;
|
||||
if( MathUtil.equals( 0, area_increment)){
|
||||
prev = cur;
|
||||
@ -534,20 +541,17 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
|
||||
// relto: fin
|
||||
final double xTabFront_fin = getTabFrontEdge();
|
||||
final double xTabTrail_fin = getTabTrailingEdge();
|
||||
|
||||
final double xFinFront_body = this.getAxialFront();
|
||||
|
||||
final Coordinate finFront = getFinFront();
|
||||
final double xFinFront_body = finFront.x;
|
||||
final double xTabFront_body = xFinFront_body + xTabFront_fin;
|
||||
final double xTabTrail_body = xFinFront_body + xTabTrail_fin;
|
||||
|
||||
// always returns x coordinates relTo fin front:
|
||||
Coordinate[] upperCurve = getMountInterval( xTabFront_body, xTabTrail_body );
|
||||
// locate relative to fin/body centerline
|
||||
upperCurve = translatePoints( upperCurve, -xFinFront_body, 0.0);
|
||||
|
||||
Coordinate[] lowerCurve = translateToCenterline( getTabPoints());
|
||||
|
||||
// get body points, relTo fin front / centerline);
|
||||
final Coordinate[] upperCurve = getMountPoints( xTabFront_body, xTabTrail_body, -xFinFront_body, 0);
|
||||
final Coordinate[] lowerCurve = translateToCenterline( getTabPoints());
|
||||
final Coordinate[] tabPoints = combineCurves( upperCurve, lowerCurve);
|
||||
|
||||
|
||||
return calculateCurveIntegral( tabPoints );
|
||||
}
|
||||
|
||||
@ -559,27 +563,23 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
|
||||
}
|
||||
|
||||
/**
|
||||
* calculates the 2-dimensional area-centroid of a single fin.
|
||||
*
|
||||
* Located from the leading end of the fin root.
|
||||
* The coordinate contains an x,y coordinate of the centroid, relative to the parent-body-centerline
|
||||
* The weight contains the area of the fin.
|
||||
*
|
||||
* @return area centroid coordinates (weight is the area)
|
||||
*/
|
||||
|
||||
/*
|
||||
* The coordinate contains an x,y coordinate of the centroid, relative to the parent-body-centerline
|
||||
*/
|
||||
private Coordinate calculateSinglePlanformCentroid(){
|
||||
final Coordinate finFront = getFinFront();
|
||||
|
||||
final Coordinate[] upperCurve = getFinPoints();
|
||||
final Coordinate[] lowerCurve = getRootPoints();
|
||||
final Coordinate finLead = getFinFront();
|
||||
final double xFinTrail = finLead.x+getLength();
|
||||
|
||||
final Coordinate[] upperCurve = translatePoints(getFinPoints(), 0, finLead.y);
|
||||
final Coordinate[] lowerCurve = getMountPoints( finLead.x, xFinTrail, -finLead.x, 0);
|
||||
final Coordinate[] totalCurve = combineCurves( upperCurve, lowerCurve);
|
||||
|
||||
Coordinate planformCentroid = calculateCurveIntegral( totalCurve );
|
||||
|
||||
final Coordinate planformCentroid = calculateCurveIntegral( totalCurve );
|
||||
|
||||
// return as a position relative to fin-root
|
||||
return planformCentroid.add(0., finFront.y, 0);
|
||||
return planformCentroid;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -592,15 +592,15 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
|
||||
* @return combined curve
|
||||
*/
|
||||
private Coordinate[] combineCurves( final Coordinate[] c1, final Coordinate[] c2){
|
||||
Coordinate[] combined = new Coordinate[ c1.length + c2.length - 1];
|
||||
Coordinate[] combined = new Coordinate[ c1.length + c2.length];
|
||||
|
||||
// copy the first array to the start of the return array...
|
||||
System.arraycopy(c1, 0, combined, 0, c1.length);
|
||||
|
||||
Coordinate[] revCurve = reverse( c2);
|
||||
int writeIndex = c1.length; // start directly after previous array
|
||||
int writeCount = revCurve.length - 1; // write all-but-first
|
||||
System.arraycopy(revCurve, 1, combined, writeIndex, writeCount);
|
||||
int writeCount = revCurve.length;
|
||||
System.arraycopy(revCurve, 0, combined, writeIndex, writeCount);
|
||||
|
||||
return combined;
|
||||
}
|
||||
@ -813,7 +813,12 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
|
||||
// by default, assume a flat base
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a copied list of the given input, translated by the delta
|
||||
*
|
||||
* @return List of XY-coordinates.
|
||||
*/
|
||||
protected static Coordinate[] translatePoints( final Coordinate[] inp, final double x_delta , final double y_delta){
|
||||
Coordinate[] returnPoints = new Coordinate[inp.length];
|
||||
for( int index=0; index < inp.length; ++index){
|
||||
@ -823,8 +828,23 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
|
||||
}
|
||||
return returnPoints;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return a copied list of the given input, translated by the delta
|
||||
*
|
||||
* @return List of XY-coordinates.
|
||||
*/
|
||||
protected static ArrayList<Coordinate> translatePoints( final ArrayList<Coordinate> inp, final Coordinate delta){
|
||||
final ArrayList<Coordinate> returnPoints = new ArrayList<>();
|
||||
returnPoints.ensureCapacity(inp.size());
|
||||
|
||||
for( Coordinate c: inp ){
|
||||
returnPoints.add(c.add(delta));
|
||||
}
|
||||
|
||||
return returnPoints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of X,Y coordinates defining the geometry of a single fin tab.
|
||||
* The origin is the leading root edge, and the tab height (or 'depth') is
|
||||
@ -1037,22 +1057,23 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
|
||||
}
|
||||
|
||||
/**
|
||||
<<<<<<< HEAD
|
||||
* use this for calculating physical properties, and routine drawing
|
||||
*
|
||||
*
|
||||
* @return points representing the fin-root points, relative to ( x: fin-front, y: centerline ) i.e. relto: fin Component reference point
|
||||
*/
|
||||
public Coordinate[] getMountPoints() {
|
||||
if( null == parent){
|
||||
return null;
|
||||
}
|
||||
|
||||
return getMountInterval(0., parent.getLength());
|
||||
|
||||
return getMountPoints(0., parent.getLength(), 0,0);
|
||||
}
|
||||
|
||||
/**
|
||||
* used to get body points for the profile design view
|
||||
*
|
||||
* @return points representing the fin-root points, relative to ( x: fin-front, y: fin-root-radius )
|
||||
* @return points representing the fin-root points, relative to ( x: fin-front, y: centerline ) i.e. relto: fin Component reference point
|
||||
*/
|
||||
public Coordinate[] getRootPoints(){
|
||||
if( null == parent){
|
||||
@ -1060,16 +1081,25 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
|
||||
}
|
||||
|
||||
final Coordinate finLead = getFinFront();
|
||||
final double finTailX = finLead.x + getLength();
|
||||
final double xFinEnd = finLead.x + getLength();
|
||||
|
||||
final Coordinate[] bodyPoints = getMountInterval( finLead.x, finTailX);
|
||||
|
||||
return translatePoints(bodyPoints, -finLead.x, -finLead.y);
|
||||
return getMountPoints( finLead.x, xFinEnd, -finLead.x, -finLead.y);
|
||||
}
|
||||
|
||||
|
||||
private Coordinate[] getMountInterval( final double xStart, final double xEnd ) {
|
||||
// System.err.println(String.format(" .... >> mount interval/x: ( %g, %g)]", xStart, xEnd));
|
||||
/**
|
||||
* used to get calculate body profile points:
|
||||
*
|
||||
* @param xStart - xStart, in Mount-frame
|
||||
* @param xEnd - xEnd, in Mount-frame
|
||||
* @param xOffset - x-Offset to apply to returned points
|
||||
* @param yOffset - y-Offset to apply to returned points
|
||||
*
|
||||
* @return points representing the mount's points
|
||||
*/
|
||||
private Coordinate[] getMountPoints(final double xStart, final double xEnd, final double xOffset, final double yOffset) {
|
||||
if( null == parent){
|
||||
return new Coordinate[]{Coordinate.ZERO};
|
||||
}
|
||||
|
||||
// for a simple bodies, one increment is perfectly accurate.
|
||||
int divisionCount = 1;
|
||||
@ -1104,15 +1134,24 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
|
||||
if( body.getLength()-0.000001 < points[lastIndex].x) {
|
||||
points[lastIndex] = points[lastIndex].setX(body.getLength()).setY(body.getAftRadius());
|
||||
}
|
||||
|
||||
|
||||
if( 0.0000001 < (Math.abs(xOffset) + Math.abs(yOffset))){
|
||||
points = translatePoints(points, xOffset, yOffset);
|
||||
}
|
||||
|
||||
return points;
|
||||
}
|
||||
|
||||
// for debugging. You can safely delete this method
|
||||
public static String getPointDescr( final Coordinate[] points, final String name, final String indent){
|
||||
StringBuilder buf = new StringBuilder();
|
||||
|
||||
buf.append(String.format("%s >> %s: %d points\n", indent, name, points.length));
|
||||
return getPointDescr(Arrays.asList(points), name, indent);
|
||||
}
|
||||
|
||||
// for debugging. You can safely delete this method
|
||||
public static String getPointDescr( final List<Coordinate> points, final String name, final String indent){
|
||||
StringBuilder buf = new StringBuilder();
|
||||
|
||||
buf.append(String.format("%s >> %s: %d points\n", indent, name, points.size()));
|
||||
int index =0;
|
||||
for( Coordinate c : points ){
|
||||
buf.append( String.format( indent+" ....[%2d] (%6.4g, %6.4g)\n", index, c.x, c.y));
|
||||
@ -1128,8 +1167,8 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
|
||||
buf.append( getPointDescr( this.getFinPoints(), "Fin Points", ""));
|
||||
|
||||
if (null != parent) {
|
||||
buf.append( getPointDescr( this.getMountPoints(0, parent.getLength(), 0, 0), "Body Points", ""));
|
||||
buf.append( getPointDescr( this.getRootPoints(), "Root Points", ""));
|
||||
buf.append( getPointDescr( this.getMountPoints(), "Mount Points", ""));
|
||||
}
|
||||
|
||||
if( ! this.isTabTrivial() ) {
|
||||
|
@ -22,7 +22,7 @@ public class FreeformFinSet extends FinSet {
|
||||
// this class uses certain features of 'ArrayList' which are not implemented in other 'List' implementations.
|
||||
private ArrayList<Coordinate> points = new ArrayList<>();
|
||||
|
||||
private static final double SNAP_SMALLER_THAN = 1e-6;
|
||||
private static final double SNAP_SMALLER_THAN = 5e-3;
|
||||
private static final double IGNORE_SMALLER_THAN = 1e-12;
|
||||
|
||||
public FreeformFinSet() {
|
||||
@ -133,7 +133,7 @@ public class FreeformFinSet extends FinSet {
|
||||
ArrayList<Coordinate> copy = new ArrayList<>(this.points);
|
||||
|
||||
this.points.remove(index);
|
||||
if (!validate()) {
|
||||
if (intersects()) {
|
||||
// if error, rollback.
|
||||
this.points = copy;
|
||||
}
|
||||
@ -149,12 +149,6 @@ public class FreeformFinSet extends FinSet {
|
||||
/** maintained just for backwards compatibility:
|
||||
*/
|
||||
public void setPoints(Coordinate[] newPoints) {
|
||||
// move to zero, if applicable
|
||||
if( ! Coordinate.ZERO.equals(newPoints[0])) {
|
||||
final Coordinate p0 = newPoints[0];
|
||||
newPoints = translatePoints( newPoints, -p0.x, -p0.y);
|
||||
}
|
||||
|
||||
setPoints(new ArrayList<>(Arrays.asList(newPoints)));
|
||||
}
|
||||
|
||||
@ -164,43 +158,29 @@ public class FreeformFinSet extends FinSet {
|
||||
* @param newPoints New points to set as the exposed edges of the fin
|
||||
*/
|
||||
public void setPoints( ArrayList<Coordinate> newPoints) {
|
||||
|
||||
final Coordinate delta = newPoints.get(0).multiply(-1);
|
||||
if( IGNORE_SMALLER_THAN < delta.length2()){
|
||||
newPoints = translatePoints( newPoints, delta);
|
||||
}
|
||||
|
||||
// copy the old points, in case validation fails
|
||||
ArrayList<Coordinate> copy = new ArrayList<>(this.points);
|
||||
final ArrayList<Coordinate> pointsCopy = new ArrayList<>(this.points);
|
||||
final double lengthCopy = this.length;
|
||||
|
||||
this.points = newPoints;
|
||||
this.length = newPoints.get(newPoints.size() -1).x;
|
||||
|
||||
|
||||
update();
|
||||
|
||||
//StackTraceElement[] stacktrack = Thread.currentThread().getStackTrace();
|
||||
if("Canard fins, mounted to transition".equals(this.getName())) {
|
||||
log.error(String.format("starting to set %d points @ %s", newPoints.size(), this.getName()), new NullPointerException());
|
||||
System.err.println( toDebugDetail());
|
||||
}
|
||||
|
||||
if( ! validate()){
|
||||
|
||||
if( intersects()){
|
||||
// on error, reset to the old points
|
||||
this.points = copy;
|
||||
this.points = pointsCopy;
|
||||
this.length = lengthCopy;
|
||||
}
|
||||
|
||||
|
||||
fireComponentChangeEvent(ComponentChangeEvent.AEROMASS_CHANGE);
|
||||
}
|
||||
|
||||
private double y_body(final double x) {
|
||||
return y_body(x, 0.0);
|
||||
}
|
||||
|
||||
private double y_body(final double x_target, final double x_ref) {
|
||||
final SymmetricComponent sym = (SymmetricComponent) getParent();
|
||||
return (sym.getRadius(x_target) - sym.getRadius(x_ref));
|
||||
}
|
||||
|
||||
public void setPointRelToFin(final int index, final double x_request_fin, final double y_request_fin) throws IllegalFinPointException {
|
||||
final double x_finStart_body = getAxialFront(); // x @ fin start, body frame
|
||||
final double y_finStart_body = y_body(x_finStart_body);
|
||||
|
||||
setPoint(index, x_request_fin + x_finStart_body, y_request_fin + y_finStart_body);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the point at position <code>i</code> to coordinates (x,y).
|
||||
* <p>
|
||||
@ -225,19 +205,16 @@ public class FreeformFinSet extends FinSet {
|
||||
public void setPoint(final int index, final double xRequest, final double yRequest) {
|
||||
|
||||
if(null != this.getParent()) {
|
||||
if (0 == index) {
|
||||
clampFirstPoint(new Coordinate(xRequest, yRequest));
|
||||
} else if ((this.points.size() - 1) == index) {
|
||||
Coordinate priorPoint = points.get(index);
|
||||
points.set(index, new Coordinate(xRequest, yRequest));
|
||||
clampLastPoint(priorPoint);
|
||||
} else {
|
||||
// interior points can never change the
|
||||
points.set(index, new Coordinate(xRequest, yRequest));
|
||||
clampInteriorPoint(index);
|
||||
final Coordinate prior = points.get(index);
|
||||
points.set(index, new Coordinate(xRequest, yRequest));
|
||||
|
||||
if((points.size() - 1) == index){
|
||||
clampLastPoint(xRequest-prior.x);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
update();
|
||||
|
||||
// this maps the last index and the next-to-last-index to the same 'testIndex'
|
||||
int testIndex = Math.min(index, (points.size() - 2));
|
||||
if (intersects(testIndex)) {
|
||||
@ -245,24 +222,24 @@ public class FreeformFinSet extends FinSet {
|
||||
log.error(String.format("ERROR: found an intersection while setting fin point #%d to [%6.4g, %6.4g] <body frame> : ABORTING setPoint(..) !! ", index, xRequest, yRequest));
|
||||
return;
|
||||
}
|
||||
|
||||
fireComponentChangeEvent(ComponentChangeEvent.AEROMASS_CHANGE);
|
||||
}
|
||||
|
||||
private void movePoints(final double delta_x, final double delta_y) {
|
||||
// skip 0th index -- it's the local origin and is always (0,0)
|
||||
// zero-out 0th index -- it's the local origin and is always (0,0)
|
||||
points.set(0, Coordinate.ZERO);
|
||||
|
||||
for (int index = 1; index < points.size(); ++index) {
|
||||
final Coordinate oldPoint = this.points.get(index);
|
||||
final Coordinate newPoint = oldPoint.add(delta_x, delta_y, 0.0f);
|
||||
points.set(index, newPoint);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Coordinate[] getFinPoints() {
|
||||
return points.toArray(new Coordinate[0]);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public double getSpan() {
|
||||
double max = 0;
|
||||
@ -287,237 +264,114 @@ public class FreeformFinSet extends FinSet {
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAxialOffset(final AxialMethod newAxialMethod, final double newOffsetRequest) {
|
||||
super.setAxialOffset(newAxialMethod, newOffsetRequest);
|
||||
|
||||
if (null != parent) {
|
||||
// if the new position would cause fin overhang, only allow movement up to the end of the parent component.
|
||||
// N.B. if you want a fin to overhang, add & adjust interior points.
|
||||
final double backOverhang = getAxialOffset(AxialMethod.BOTTOM);
|
||||
if (0 < backOverhang) {
|
||||
final double newOffset = newOffsetRequest - backOverhang;
|
||||
super.setAxialOffset(newAxialMethod, newOffset);
|
||||
}
|
||||
final double frontOverhang = getAxialFront();
|
||||
if (0 > frontOverhang) {
|
||||
final double newOffset = newOffsetRequest - frontOverhang;
|
||||
super.setAxialOffset(newAxialMethod, newOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
this.length = points.get(points.size() -1).x - points.get(0).x;
|
||||
this.setAxialOffset(this.axialMethod, this.axialOffset);
|
||||
|
||||
|
||||
if(null != this.getParent()) {
|
||||
clampFirstPoint(points.get(0));
|
||||
clampFirstPoint();
|
||||
|
||||
for(int i=1; i < points.size()-1; i++) {
|
||||
clampInteriorPoint(i);
|
||||
}
|
||||
|
||||
clampLastPoint(null);
|
||||
clampLastPoint();
|
||||
|
||||
validateFinTab();
|
||||
}
|
||||
}
|
||||
|
||||
private void clampFirstPoint(final Coordinate newPoint) {
|
||||
|
||||
private void clampFirstPoint() {
|
||||
final SymmetricComponent body = (SymmetricComponent) getParent();
|
||||
|
||||
|
||||
final Coordinate finFront = getFinFront();
|
||||
final double xFinFront = finFront.x; // x of fin start, body-frame
|
||||
final double yFinFront = finFront.y; // y of fin start, body-frame
|
||||
final double xBodyStart = -getAxialFront(); // x-offset from start-to-start; fin-frame
|
||||
|
||||
final Coordinate p0 = points.get(0);
|
||||
|
||||
double xDelta;
|
||||
double yDelta;
|
||||
if( ! Coordinate.ZERO.equals(p0)){
|
||||
double xDelta = p0.x;
|
||||
double xTrail = points.get(points.size() - 1).x;
|
||||
if(xDelta > xTrail){
|
||||
xDelta = xTrail;
|
||||
}
|
||||
double yDelta = body.getRadius(xFinFront + xDelta) - yFinFront;
|
||||
|
||||
if(IGNORE_SMALLER_THAN > Math.abs(newPoint.x)){
|
||||
return;
|
||||
}else if (xBodyStart > newPoint.x) {
|
||||
// attempt to place point in front of the start of the body
|
||||
|
||||
// delta for new zeroth point
|
||||
xDelta = xBodyStart;
|
||||
yDelta = body.getForeRadius() - yFinFront;
|
||||
points.set(0, newPoint);
|
||||
points.add(0, Coordinate.ZERO);
|
||||
movePoints(-xDelta, -yDelta);
|
||||
|
||||
//System.err.println(String.format(".... @[0]//A: delta= %f, %f", xDelta, yDelta));
|
||||
|
||||
}else if (xFinFront > body.getLength()) {
|
||||
final double xNew = body.getLength();
|
||||
final double yNew = yFinFront - body.getAftRadius();
|
||||
points.set(0, points.set(0, new Coordinate(xNew, yNew)));
|
||||
|
||||
xDelta = xNew - xFinFront;
|
||||
yDelta = yNew - yFinFront;
|
||||
movePoints(-xDelta, -yDelta);
|
||||
//System.err.println(String.format(".... @[0]//B: delta= %f, %f", xDelta, yDelta));
|
||||
|
||||
}else {
|
||||
// distance to move the entire fin by:
|
||||
xDelta = newPoint.x;
|
||||
yDelta = body.getRadius(xFinFront + xDelta) - yFinFront;
|
||||
movePoints(-xDelta, -yDelta);
|
||||
|
||||
//System.err.println(String.format(".... @[0]//C: delta= %f, %f", xDelta, yDelta));
|
||||
if(AxialMethod.TOP == getAxialMethod()) {
|
||||
this.axialOffset = axialOffset + xDelta;
|
||||
this.position = this.position.add(xDelta, 0, 0);
|
||||
} else if (AxialMethod.MIDDLE == getAxialMethod()) {
|
||||
this.axialOffset = axialOffset + xDelta / 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
final int lastIndex = points.size()-1;
|
||||
this.length = points.get(lastIndex).x;
|
||||
|
||||
if (AxialMethod.TOP == getAxialMethod()) {
|
||||
setAxialOffset(AxialMethod.TOP, getAxialOffset() + xDelta);
|
||||
} else if (AxialMethod.MIDDLE == getAxialMethod()) {
|
||||
setAxialOffset(AxialMethod.MIDDLE, getAxialOffset() + xDelta / 2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void clampInteriorPoint(final int index) {
|
||||
final SymmetricComponent sym = (SymmetricComponent) this.getParent();
|
||||
|
||||
final double xPrior = points.get(index).x;
|
||||
final double yPrior = points.get(index).y;
|
||||
|
||||
final Coordinate finFront = getFinFront();
|
||||
final double xFinFront = finFront.x; // x of fin start, body-frame
|
||||
final double yFinFront = finFront.y; // y of fin start, body-frame
|
||||
|
||||
final double yBody = sym.getRadius(xPrior + xFinFront) - yFinFront;
|
||||
|
||||
// ensure that an interior point is outside of its mounting body:
|
||||
if (yBody > yPrior) {
|
||||
points.set(index, points.get(index).setY(yBody));
|
||||
|
||||
final double xBodyFront = -xFinFront;
|
||||
final double xBodyBack = xBodyFront + sym.getLength();
|
||||
|
||||
final double xPrior = points.get(index).x;
|
||||
final double yPrior = points.get(index).y;
|
||||
|
||||
if((xBodyFront <= xPrior ) && ( xPrior <= xBodyBack )) {
|
||||
final double yBody = sym.getRadius(xPrior + xFinFront) - yFinFront;
|
||||
|
||||
// ensure that an interior point is outside of its mounting body:
|
||||
if (yBody > yPrior) {
|
||||
points.set(index, points.get(index).setY(yBody));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void clampLastPoint(final Coordinate prior) {
|
||||
private void clampLastPoint() {
|
||||
clampLastPoint(0);
|
||||
}
|
||||
|
||||
private void clampLastPoint(final double xDelta) {
|
||||
final SymmetricComponent body = (SymmetricComponent) getParent();
|
||||
|
||||
final double xFinStart = getAxialFront(); // x of fin start, body-frame
|
||||
final double yFinStart = body.getRadius(xFinStart); // y of fin start, body-frame
|
||||
|
||||
final double xBodyStart = -getAxialFront(); // x-offset from start-to-start; fin-frame
|
||||
final double xBodyEnd = xBodyStart + body.getLength(); /// x-offset from start-to-body; fin-frame
|
||||
|
||||
|
||||
final Coordinate finFront = getFinFront();
|
||||
final double xFinStart = finFront.x; // x of fin start, body-frame
|
||||
final double yFinStart = finFront.y; // y of fin start, body-frame
|
||||
|
||||
int lastIndex = points.size() - 1;
|
||||
final Coordinate cur = points.get(lastIndex);
|
||||
final Coordinate last = points.get(lastIndex);
|
||||
|
||||
double xDelta=0;
|
||||
double yBody = body.getRadius(xFinStart + last.x) - yFinStart;
|
||||
double yDelta = yBody - last.y;
|
||||
if( IGNORE_SMALLER_THAN < Math.abs(yDelta)){
|
||||
// i.e. if it delta is close enough above OR is inside the body. In either case, snap it to the body.
|
||||
|
||||
if (xBodyEnd < cur.x) {
|
||||
if(SNAP_SMALLER_THAN > Math.abs(xBodyEnd - cur.x)){
|
||||
points.set( lastIndex, new Coordinate(xBodyEnd, body.getAftRadius() - yFinStart));
|
||||
}else {
|
||||
// the last point is placed after the end of the mount-body
|
||||
points.add(new Coordinate(xBodyEnd, body.getAftRadius() - yFinStart));
|
||||
}
|
||||
|
||||
if(null != prior) {
|
||||
xDelta = xBodyEnd - prior.x;
|
||||
}else{
|
||||
xDelta = xBodyEnd - cur.x;
|
||||
}
|
||||
//System.err.println(String.format(".... @[-1]//A: delta= %f", xDelta));
|
||||
|
||||
}else if (cur.x < 0) {
|
||||
// the last point is positioned ahead of the first point.
|
||||
points.set(lastIndex, Coordinate.ZERO);
|
||||
|
||||
xDelta = cur.x;
|
||||
|
||||
//System.err.println(String.format(".... @[-1]//B: delta= %f", xDelta));
|
||||
|
||||
} else {
|
||||
if(null != prior) {
|
||||
xDelta = cur.x - prior.x;
|
||||
}
|
||||
double yBody = body.getRadius(xFinStart + cur.x) - yFinStart;
|
||||
if(IGNORE_SMALLER_THAN < Math.abs(yBody - cur.y)) {
|
||||
// for the first and last points: set y-value to *exactly* match parent body:
|
||||
points.set(lastIndex, new Coordinate(cur.x, yBody));
|
||||
|
||||
}
|
||||
|
||||
|
||||
//System.err.println(String.format(".... @[-1]//C: delta = %f", xDelta));
|
||||
// => set y-value to *exactly* match parent body:
|
||||
points.set(lastIndex, new Coordinate(last.x, yBody));
|
||||
}
|
||||
|
||||
if(IGNORE_SMALLER_THAN < Math.abs(xDelta)) {
|
||||
lastIndex = points.size()-1;
|
||||
|
||||
if( IGNORE_SMALLER_THAN < Math.abs(xDelta)) {
|
||||
this.length = points.get(lastIndex).x;
|
||||
|
||||
if (AxialMethod.MIDDLE == getAxialMethod()) {
|
||||
setAxialOffset(AxialMethod.MIDDLE, getAxialOffset() + xDelta / 2);
|
||||
this.axialOffset = axialOffset + xDelta/2;
|
||||
} else if (AxialMethod.BOTTOM == getAxialMethod()) {
|
||||
setAxialOffset(AxialMethod.BOTTOM, getAxialOffset() + xDelta);
|
||||
this.axialOffset = axialOffset + xDelta;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean validate() {
|
||||
final Coordinate firstPoint = this.points.get(0);
|
||||
if (firstPoint.x != 0 || firstPoint.y != 0) {
|
||||
log.error("Start point illegal -- not located at (0,0): " + firstPoint + " (" + getName() + ")");
|
||||
return false;
|
||||
}
|
||||
|
||||
final Coordinate lastPoint = this.points.get(points.size() - 1);
|
||||
if (lastPoint.x < 0) {
|
||||
log.error("End point illegal: end point starts in front of start point: " + lastPoint.x);
|
||||
return false;
|
||||
}
|
||||
|
||||
// the last point *is* restricted to be on the surface of its owning component:
|
||||
SymmetricComponent symBody = (SymmetricComponent) this.getParent();
|
||||
if (null != symBody) {
|
||||
final double startOffset = this.getAxialFront();
|
||||
final Coordinate finStart = new Coordinate(startOffset, symBody.getRadius(startOffset));
|
||||
|
||||
// campare x-values
|
||||
final Coordinate finAtLast = lastPoint.add(finStart);
|
||||
if (symBody.getLength() < finAtLast.x) {
|
||||
log.error("End point falls after parent body ends: [" + symBody.getName() + "]. Exception: ",
|
||||
new IllegalFinPointException("Fin ends after its parent body \"" + symBody.getName() + "\". Ignoring."));
|
||||
log.error(String.format(" ..fin position: (x: %12.10f via: %s)", this.axialOffset, this.axialMethod.name()));
|
||||
log.error(String.format(" ..Body Length: %12.10f finLength: %12.10f", symBody.getLength(), this.getLength()));
|
||||
log.error(String.format(" ..fin endpoint: (x: %12.10f, y: %12.10f)", finAtLast.x, finAtLast.y));
|
||||
return false;
|
||||
}
|
||||
|
||||
// compare the y-values
|
||||
final Coordinate bodyAtLast = finAtLast.setY(symBody.getRadius(finAtLast.x));
|
||||
if (0.0001 < Math.abs(finAtLast.y - bodyAtLast.y)) {
|
||||
String numbers = String.format("finStart=(%6.2g,%6.2g) // fin_end=(%6.2g,%6.2g) // body=(%6.2g,%6.2g)", finStart.x, finStart.y, finAtLast.x, finAtLast.y, bodyAtLast.x, bodyAtLast.y);
|
||||
log.error("End point does not touch its parent body [" + symBody.getName() + "]. exception: ",
|
||||
new IllegalFinPointException("End point does not touch its parent body! Expected: " + numbers));
|
||||
log.error(" .." + numbers);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (intersects()) {
|
||||
log.error("found intersection in finset points!");
|
||||
return false;
|
||||
}
|
||||
|
||||
final int lastIndex = points.size() - 1;
|
||||
final List<Coordinate> pts = this.points;
|
||||
for (int i = 0; i < lastIndex; i++) {
|
||||
if (pts.get(i).z != 0) {
|
||||
log.error("z-coordinate not zero");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if *any* of the fin-point line segments intersects with another.
|
||||
*
|
||||
@ -541,7 +395,7 @@ public class FreeformFinSet extends FinSet {
|
||||
if ((points.size() - 2) < targetIndex) {
|
||||
throw new IndexOutOfBoundsException("request validate of non-existent fin edge segment: " + targetIndex + "/" + points.size());
|
||||
}
|
||||
|
||||
|
||||
// (pre-check the indices above.)
|
||||
final Point2D.Double pt1 = new Point2D.Double(points.get(targetIndex).x, points.get(targetIndex).y);
|
||||
final Point2D.Double pt2 = new Point2D.Double(points.get(targetIndex + 1).x, points.get(targetIndex + 1).y);
|
||||
|
@ -348,8 +348,10 @@ public class Transition extends SymmetricComponent {
|
||||
*/
|
||||
@Override
|
||||
public double getRadius(double x) {
|
||||
if (x < 0 || x > length)
|
||||
return 0;
|
||||
if ( x < 0 )
|
||||
return getForeRadius();
|
||||
if ( x > length)
|
||||
return getAftRadius();
|
||||
|
||||
double r1 = getForeRadius();
|
||||
double r2 = getAftRadius();
|
||||
|
@ -318,7 +318,6 @@ public class MassCalculatorTest extends BaseTestCase {
|
||||
FlightConfiguration emptyConfig = rocket.getEmptyConfiguration();
|
||||
rocket.setSelectedConfiguration( emptyConfig.getFlightConfigurationID() );
|
||||
|
||||
|
||||
double expInertia;
|
||||
RocketComponent cc;
|
||||
double compInertia;
|
||||
@ -326,30 +325,24 @@ public class MassCalculatorTest extends BaseTestCase {
|
||||
// ====== Payload Stage ======
|
||||
// ====== ====== ====== ======
|
||||
{
|
||||
expInertia = 3.1698055283e-5;
|
||||
cc= rocket.getChild(0).getChild(0);
|
||||
compInertia = cc.getRotationalInertia();
|
||||
assertEquals(cc.getName()+" Rotational MOI calculated incorrectly: ", expInertia, compInertia, EPSILON);
|
||||
expInertia = 1.79275e-5;
|
||||
compInertia = cc.getLongitudinalInertia();
|
||||
assertEquals(cc.getName()+" Longitudinal MOI calculated incorrectly: ", expInertia, compInertia, EPSILON);
|
||||
|
||||
cc= rocket.getChild(0).getChild(1);
|
||||
expInertia = 7.70416e-5;
|
||||
compInertia = cc.getRotationalInertia();
|
||||
assertEquals(cc.getName()+" Rotational MOI calculated incorrectly: ", expInertia, compInertia, EPSILON);
|
||||
expInertia = 8.06940e-5;
|
||||
compInertia = cc.getLongitudinalInertia();
|
||||
assertEquals(cc.getName()+" Longitudinal MOI calculated incorrectly: ", expInertia, compInertia, EPSILON);
|
||||
|
||||
cc= rocket.getChild(0).getChild(2);
|
||||
expInertia = 1.43691e-5;
|
||||
compInertia = cc.getRotationalInertia();
|
||||
assertEquals(cc.getName()+" Rotational MOI calculated incorrectly: ", expInertia, compInertia, EPSILON);
|
||||
expInertia = 7.30265e-6;
|
||||
compInertia = cc.getLongitudinalInertia();
|
||||
assertEquals(cc.getName()+" Longitudinal MOI calculated incorrectly: ", expInertia, compInertia, EPSILON);
|
||||
final AxialStage payloadStage = (AxialStage) rocket.getChild(0);
|
||||
|
||||
// Component: Nose Cone
|
||||
final NoseCone payloadNose = (NoseCone) payloadStage.getChild(0);
|
||||
assertEquals(payloadNose.getName()+" Rotational MOI calculated incorrectly: ", 3.508155e-5, payloadNose.getRotationalInertia(), EPSILON);
|
||||
assertEquals(payloadNose.getName()+" Longitudinal MOI calculated incorrectly: ", 2.0400578477e-6, payloadNose.getLongitudinalInertia(), EPSILON);
|
||||
|
||||
// Component: Payload BodyTube
|
||||
final BodyTube payloadBody = (BodyTube)payloadStage.getChild(1);
|
||||
assertEquals(payloadBody.getName()+" Rotational MOI calculated incorrectly: ", 7.70416e-5, payloadBody.getRotationalInertia(), EPSILON);
|
||||
assertEquals(payloadBody.getName()+" Longitudinal MOI calculated incorrectly: ", 8.06940e-5, payloadBody.getLongitudinalInertia(), EPSILON);
|
||||
|
||||
// Component: Payload Trailing Transition
|
||||
final Transition payloadTail = (Transition) payloadStage.getChild(2);
|
||||
assertEquals(payloadTail.getName()+" Rotational MOI calculated incorrectly: ", 1.43691e-5, payloadTail.getRotationalInertia(), EPSILON);
|
||||
assertEquals(payloadTail.getName()+" Longitudinal MOI calculated incorrectly: ", 7.30265e-6, payloadTail.getLongitudinalInertia(), EPSILON);
|
||||
|
||||
// Component: Interstage
|
||||
cc= rocket.getChild(0).getChild(3);
|
||||
expInertia = 4.22073e-5;
|
||||
compInertia = cc.getRotationalInertia();
|
||||
|
@ -108,7 +108,7 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
new Coordinate( 0.0, 0.0),
|
||||
new Coordinate( 0.4, 1.0),
|
||||
new Coordinate( 0.6, 1.0),
|
||||
new Coordinate( 0.8, 0.9) // y-value should be automaticaly adjusted to snap to body
|
||||
new Coordinate( 0.8, 0.788) // y-value should be automatically adjusted to snap to body
|
||||
};
|
||||
fins.setPoints(points);
|
||||
nose.addChild(fins);
|
||||
@ -130,13 +130,12 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
FreeformFinSet fins = new FreeformFinSet();
|
||||
fins.setName("TubeBodyFins");
|
||||
fins.setFinCount(1);
|
||||
Coordinate[] points = new Coordinate[]{
|
||||
fins.setPoints(new Coordinate[]{
|
||||
new Coordinate(0, 0),
|
||||
new Coordinate(0.5, 1),
|
||||
new Coordinate(1, 1),
|
||||
new Coordinate(1, 0)
|
||||
};
|
||||
fins.setPoints(points);
|
||||
});
|
||||
fins.setAxialOffset( AxialMethod.BOTTOM, 0.0);
|
||||
|
||||
body.addChild(fins);
|
||||
@ -318,36 +317,42 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
final NoseCone nose = (NoseCone) rkt.getChild(0).getChild(0);
|
||||
final FinSet fins = createFinOnEllipsoidNose(nose);
|
||||
|
||||
// assert preconditions
|
||||
assertEquals(Shape.ELLIPSOID, nose.getType());
|
||||
assertEquals(1.0, nose.getLength(), EPSILON);
|
||||
|
||||
assertEquals(AxialMethod.TOP, fins.getAxialMethod());
|
||||
assertEquals(0.02, fins.getAxialOffset(), EPSILON);
|
||||
assertEquals(0.8, fins.getLength(), EPSILON);
|
||||
final Coordinate[] finPoints = fins.getFinPoints();
|
||||
assertEquals(4, finPoints.length);
|
||||
assertEquals(finPoints[0], Coordinate.ZERO);
|
||||
assertEquals(finPoints[1], new Coordinate(0.4, 1.0));
|
||||
assertEquals(finPoints[2], new Coordinate(0.6, 1.0));
|
||||
assertEquals(finPoints[3], new Coordinate(0.8, 0.78466912));
|
||||
// [1] [2]
|
||||
// +======+
|
||||
// / \ [3]
|
||||
// / ---+----
|
||||
// / --------
|
||||
// [0] / --------
|
||||
// ---+----
|
||||
//
|
||||
// [0] ( 0.0, 0.0)
|
||||
// [1] ( 0.4, 1.0)
|
||||
// [2] ( 0.6, 1.0)
|
||||
// [3] ( 0.8, 0.7847)
|
||||
{ // assert preconditions::Mount
|
||||
assertEquals(Shape.ELLIPSOID, nose.getType());
|
||||
assertEquals(1.0, nose.getLength(), EPSILON);
|
||||
|
||||
final double expectedWettedArea = 0.13397384;
|
||||
final double actualWettedArea = fins.getPlanformArea();
|
||||
Coordinate wcg = fins.getCG(); // relative to parent
|
||||
assertEquals("Calculated fin area is wrong: ", expectedWettedArea, actualWettedArea, EPSILON);
|
||||
}{ // Assert fin shape
|
||||
// [1] [2]
|
||||
// +======+
|
||||
// / \ [3]
|
||||
// / ---+----
|
||||
// / --------
|
||||
// [0] / --------
|
||||
// ---+----
|
||||
//
|
||||
// [0] ( 0.0, 0.0)
|
||||
// [1] ( 0.4, 1.0)
|
||||
// [2] ( 0.6, 1.0)
|
||||
// [3] ( 0.8, 0.7847)
|
||||
|
||||
assertEquals(AxialMethod.TOP, fins.getAxialMethod());
|
||||
assertEquals(0.02, fins.getAxialOffset(), EPSILON);
|
||||
assertEquals(0.8, fins.getLength(), EPSILON);
|
||||
|
||||
final Coordinate[] finPoints = fins.getFinPoints();
|
||||
assertEquals(4, finPoints.length);
|
||||
assertEquals(Coordinate.ZERO, finPoints[0]);
|
||||
assertEquals(new Coordinate(0.4, 1.0), finPoints[1]);
|
||||
assertEquals(new Coordinate(0.6, 1.0), finPoints[2]);
|
||||
assertEquals(new Coordinate(0.8, 0.78466912), finPoints[3]);
|
||||
}
|
||||
|
||||
final double expectedPlanformArea = 0.13397384;
|
||||
final double actualPlanformArea = fins.getPlanformArea();
|
||||
assertEquals("Calculated fin planform area is wrong: ", expectedPlanformArea, actualPlanformArea, EPSILON);
|
||||
|
||||
Coordinate wcg = fins.getCG(); // relative to parent
|
||||
assertEquals("Calculated fin weight is wrong! ", 0.2733066, wcg.weight, EPSILON);
|
||||
assertEquals("Calculated fin centroid is wrong! ", 0.4793588, wcg.x, EPSILON);
|
||||
assertEquals("Calculated fin centroid is wrong! ", 0.996741, wcg.y, EPSILON);
|
||||
}
|
||||
@ -428,7 +433,7 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetFirstPoint() throws IllegalFinPointException {
|
||||
public void testSetFirstPoint() {
|
||||
// more transitions trigger more complicated positioning math:
|
||||
final Rocket rkt = createTemplateRocket();
|
||||
final Transition tailCone = (Transition) rkt.getChild(0).getChild(2);
|
||||
@ -446,23 +451,29 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
{ // case 1:
|
||||
fins.setAxialOffset( AxialMethod.TOP, 0.1);
|
||||
fins.setPoints(initialPoints);
|
||||
assertEquals(0.1f, fins.getAxialOffset(), EPSILON);
|
||||
|
||||
// vvvv function under test vvvv
|
||||
fins.setPoint( 0, 0.2, 0.1f);
|
||||
// ^^^^ function under test ^^^^
|
||||
|
||||
|
||||
assertEquals(0.3f, fins.getAxialOffset(), EPSILON);
|
||||
assertEquals(0.2f, fins.getLength(), EPSILON);
|
||||
|
||||
assertEquals(0.3, fins.getFinFront().x, EPSILON);
|
||||
assertEquals(0.85, fins.getFinFront().y, EPSILON);
|
||||
|
||||
final Coordinate[] postPoints = fins.getFinPoints();
|
||||
assertEquals(postPoints.length, 3);
|
||||
|
||||
|
||||
// middle point:
|
||||
assertEquals(0.2, postPoints[1].x, EPSILON);
|
||||
assertEquals(0.3, postPoints[1].y, EPSILON);
|
||||
|
||||
assertEquals(0.3f, fins.getAxialOffset(), EPSILON);
|
||||
assertEquals(0.2f, fins.getLength(), EPSILON);
|
||||
|
||||
// final point
|
||||
assertEquals(0.2, postPoints[2].x, EPSILON);
|
||||
assertEquals(-0.1, postPoints[2].y, EPSILON);
|
||||
|
||||
}{ // case 2:
|
||||
fins.setAxialOffset( AxialMethod.TOP, 0.1);
|
||||
fins.setPoints(initialPoints);
|
||||
@ -471,32 +482,35 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
fins.setPoint( 0, -0.2, 0.1f);
|
||||
// ^^^^ function under test ^^^^
|
||||
|
||||
assertEquals(0.0, fins.getFinFront().x, EPSILON);
|
||||
assertEquals(-0.1, fins.getFinFront().x, EPSILON);
|
||||
assertEquals(1.0, fins.getFinFront().y, EPSILON);
|
||||
|
||||
assertEquals(-0.1f, fins.getAxialOffset(), EPSILON);
|
||||
assertEquals(0.6f, fins.getLength(), EPSILON);
|
||||
|
||||
final Coordinate[] postPoints = fins.getFinPoints();
|
||||
assertEquals(postPoints.length, 4);
|
||||
assertEquals(postPoints.length, 3);
|
||||
|
||||
// pseudo-front point
|
||||
assertEquals(-0.1, postPoints[1].x, EPSILON);
|
||||
assertEquals(0.05, postPoints[1].y, EPSILON);
|
||||
assertEquals(0.6, postPoints[1].x, EPSILON);
|
||||
assertEquals(0.15, postPoints[1].y, EPSILON);
|
||||
|
||||
assertEquals(0.5, postPoints[2].x, EPSILON);
|
||||
assertEquals(0.15, postPoints[2].y, EPSILON);
|
||||
assertEquals(0.6, postPoints[2].x, EPSILON);
|
||||
assertEquals(-0.25, postPoints[2].y, EPSILON);
|
||||
|
||||
assertEquals(0.0f, fins.getAxialOffset(), EPSILON);
|
||||
assertEquals(0.5f, fins.getLength(), EPSILON);
|
||||
}{ // case 3:
|
||||
fins.setAxialOffset( AxialMethod.MIDDLE, 0.0);
|
||||
fins.setPoints(initialPoints);
|
||||
assertEquals(0.3, fins.getFinFront().x, EPSILON);
|
||||
|
||||
|
||||
// vvvv function under test vvvv
|
||||
fins.setPoint( 0, 0.1, 0.1f);
|
||||
// ^^^^ function under test ^^^^
|
||||
|
||||
assertEquals(0.4, fins.getFinFront().x, EPSILON);
|
||||
assertEquals(0.8, fins.getFinFront().y, EPSILON);
|
||||
|
||||
assertEquals(0.05, fins.getAxialOffset(), EPSILON);
|
||||
assertEquals(0.3, fins.getLength(), EPSILON);
|
||||
|
||||
assertEquals(0.35, fins.getFinFront().x, EPSILON);
|
||||
assertEquals(0.825, fins.getFinFront().y, EPSILON);
|
||||
|
||||
final Coordinate[] postPoints = fins.getFinPoints();
|
||||
assertEquals(postPoints.length, 3);
|
||||
@ -507,9 +521,6 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
|
||||
assertEquals(0.3, postPoints[2].x, EPSILON);
|
||||
assertEquals(-0.15, postPoints[2].y, EPSILON);
|
||||
|
||||
assertEquals(0.05f, fins.getAxialOffset(), EPSILON);
|
||||
assertEquals(0.3f, fins.getLength(), EPSILON);
|
||||
|
||||
}{ // case 4:
|
||||
fins.setAxialOffset( AxialMethod.MIDDLE, 0.0);
|
||||
@ -519,8 +530,8 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
fins.setPoint( 0, -0.1, 0.1f);
|
||||
// ^^^^ function under test ^^^^
|
||||
|
||||
assertEquals(0.2, fins.getFinFront().x, EPSILON);
|
||||
assertEquals(0.9, fins.getFinFront().y, EPSILON);
|
||||
assertEquals(0.25, fins.getFinFront().x, EPSILON);
|
||||
assertEquals(0.875, fins.getFinFront().y, EPSILON);
|
||||
|
||||
final Coordinate[] postPoints = fins.getFinPoints();
|
||||
assertEquals(postPoints.length, 3);
|
||||
@ -537,13 +548,16 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
}{ // case 5:
|
||||
fins.setAxialOffset( AxialMethod.BOTTOM, 0.0);
|
||||
fins.setPoints(initialPoints);
|
||||
assertEquals(0.6, fins.getFinFront().x, EPSILON);
|
||||
|
||||
// vvvv function under test vvvv
|
||||
fins.setPoint( 0, 0.1, 0.1f);
|
||||
// ^^^^ function under test ^^^^
|
||||
|
||||
|
||||
assertEquals(0.7, fins.getFinFront().x, EPSILON);
|
||||
assertEquals(0.65, fins.getFinFront().y, EPSILON);
|
||||
assertEquals(0.0, fins.getAxialOffset(), EPSILON);
|
||||
assertEquals(0.3, fins.getLength(), EPSILON);
|
||||
|
||||
final Coordinate[] postPoints = fins.getFinPoints();
|
||||
assertEquals(postPoints.length, 3);
|
||||
@ -555,34 +569,28 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
assertEquals(0.3, postPoints[2].x, EPSILON);
|
||||
//assertEquals(0.15, postPoints[2].y, EPSILON);
|
||||
|
||||
assertEquals(0.0f, fins.getAxialOffset(), EPSILON);
|
||||
assertEquals(0.3f, fins.getLength(), EPSILON);
|
||||
}{ // case 6:
|
||||
fins.setAxialOffset( AxialMethod.BOTTOM, 0.0);
|
||||
fins.setPoints(initialPoints);
|
||||
assertEquals(3, fins.getPointCount());
|
||||
|
||||
assertEquals(0.6, fins.getFinFront().x, EPSILON);
|
||||
|
||||
// vvvv function under test vvvv
|
||||
fins.setPoint( 0, -0.1, 0.1f);
|
||||
// ^^^^ function under test ^^^^
|
||||
|
||||
|
||||
assertEquals(0.5, fins.getFinFront().x, EPSILON);
|
||||
assertEquals(0.75, fins.getFinFront().y, EPSILON);
|
||||
assertEquals(0.5, fins.getLength(), EPSILON);
|
||||
|
||||
final Coordinate[] postPoints = fins.getFinPoints();
|
||||
assertEquals(3, postPoints.length);
|
||||
|
||||
// mid-point
|
||||
assertEquals(0.5, postPoints[1].x, EPSILON);
|
||||
assertEquals(0.15, postPoints[1].y, EPSILON);
|
||||
|
||||
assertEquals(0.5, postPoints[2].x, EPSILON);
|
||||
assertEquals(-0.25, postPoints[2].y, EPSILON);
|
||||
|
||||
assertEquals(0.0f, fins.getAxialOffset(), EPSILON);
|
||||
assertEquals(0.5f, fins.getLength(), EPSILON);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -593,6 +601,7 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
final Coordinate[] initialPoints = fins.getFinPoints();
|
||||
final int lastIndex = initialPoints.length - 1;
|
||||
final double xf = initialPoints[lastIndex].x;
|
||||
final double yf = initialPoints[lastIndex].y;
|
||||
|
||||
// assert pre-conditions:
|
||||
assertEquals(0.4, fins.getLength(), EPSILON);
|
||||
@ -607,8 +616,12 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
fins.setPoints(initialPoints);
|
||||
|
||||
// vvvv function under test vvvv
|
||||
fins.setPoint( lastIndex, xf+0.2, -0.3f);
|
||||
fins.setPoint( lastIndex, xf+0.2, yf - 0.3f);
|
||||
// ^^^^ function under test ^^^^
|
||||
|
||||
assertEquals(0.1, fins.getFinFront().x, EPSILON);
|
||||
assertEquals(0.95, fins.getFinFront().y, EPSILON);
|
||||
assertEquals(0.6, fins.getLength(), EPSILON);
|
||||
|
||||
final Coordinate[] postPoints = fins.getFinPoints();
|
||||
assertEquals(postPoints.length, 3);
|
||||
@ -621,19 +634,20 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
assertEquals(0.6, postPoints[2].x, EPSILON);
|
||||
assertEquals(-0.3, postPoints[2].y, EPSILON);
|
||||
|
||||
assertEquals(0.1, fins.getFinFront().x, EPSILON);
|
||||
assertEquals(0.95, fins.getFinFront().y, EPSILON);
|
||||
assertEquals(0.6, fins.getLength(), EPSILON);
|
||||
|
||||
}{ // case 2:
|
||||
fins.setAxialOffset( AxialMethod.TOP, 0.1);
|
||||
fins.setPoints(initialPoints);
|
||||
|
||||
// vvvv function under test vvvv
|
||||
fins.setPoint( lastIndex, xf - 0.2, 0.1f);
|
||||
fins.setPoint( lastIndex, xf - 0.2, yf + 0.1f);
|
||||
// ^^^^ function under test ^^^^
|
||||
|
||||
final Coordinate[] postPoints = fins.getFinPoints();
|
||||
|
||||
assertEquals(0.1, fins.getFinFront().x, EPSILON);
|
||||
assertEquals(0.95, fins.getFinFront().y, EPSILON);
|
||||
assertEquals(0.2, fins.getLength(), EPSILON);
|
||||
|
||||
final Coordinate[] postPoints = fins.getFinPoints();
|
||||
assertEquals(postPoints.length, 3);
|
||||
|
||||
// middle point:
|
||||
@ -643,19 +657,21 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
// last point:
|
||||
assertEquals(0.2, postPoints[2].x, EPSILON);
|
||||
assertEquals(-0.1, postPoints[2].y, EPSILON);
|
||||
|
||||
assertEquals(0.1, fins.getFinFront().x, EPSILON);
|
||||
assertEquals(0.95, fins.getFinFront().y, EPSILON);
|
||||
assertEquals(0.2f, fins.getLength(), EPSILON);
|
||||
|
||||
}{ // case 3:
|
||||
fins.setAxialOffset( AxialMethod.MIDDLE, 0.0);
|
||||
fins.setPoints(initialPoints);
|
||||
assertEquals(0.3, fins.getFinFront().x, EPSILON);
|
||||
|
||||
// vvvv function under test vvvv
|
||||
fins.setPoint( lastIndex, xf + 0.1, 0.1f);
|
||||
fins.setPoint( lastIndex, xf + 0.1, yf + 0.1f);
|
||||
// ^^^^ function under test ^^^^
|
||||
|
||||
|
||||
assertEquals(0.3, fins.getFinFront().x, EPSILON);
|
||||
assertEquals(0.85, fins.getFinFront().y, EPSILON);
|
||||
assertEquals(0.5, fins.getLength(), EPSILON);
|
||||
assertEquals(0.05, fins.getAxialOffset(), EPSILON);
|
||||
|
||||
final Coordinate[] postPoints = fins.getFinPoints();
|
||||
assertEquals(postPoints.length, 3);
|
||||
|
||||
@ -667,19 +683,20 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
assertEquals(0.5, postPoints[2].x, EPSILON);
|
||||
assertEquals(-0.25, postPoints[2].y, EPSILON);
|
||||
|
||||
assertEquals(0.3, fins.getFinFront().x, EPSILON);
|
||||
assertEquals(0.85, fins.getFinFront().y, EPSILON);
|
||||
assertEquals(0.05, fins.getAxialOffset(), EPSILON);
|
||||
assertEquals(0.5, fins.getLength(), EPSILON);
|
||||
|
||||
}{ // case 4:
|
||||
fins.setAxialOffset( AxialMethod.MIDDLE, 0.0);
|
||||
fins.setPoints(initialPoints);
|
||||
assertEquals(0.3, fins.getFinFront().x, EPSILON);
|
||||
|
||||
// vvvv function under test vvvv
|
||||
fins.setPoint( lastIndex, xf - 0.1, 0.1f);
|
||||
fins.setPoint( lastIndex, xf - 0.1, yf + 0.1f);
|
||||
// ^^^^ function under test ^^^^
|
||||
|
||||
assertEquals(0.3, fins.getFinFront().x, EPSILON);
|
||||
assertEquals(0.85, fins.getFinFront().y, EPSILON);
|
||||
assertEquals(0.3, fins.getLength(), EPSILON);
|
||||
assertEquals(-0.05, fins.getAxialOffset(), EPSILON);
|
||||
|
||||
final Coordinate[] postPoints = fins.getFinPoints();
|
||||
assertEquals(postPoints.length, 3);
|
||||
|
||||
@ -691,21 +708,21 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
assertEquals(0.3, postPoints[2].x, EPSILON);
|
||||
assertEquals(-0.15, postPoints[2].y, EPSILON);
|
||||
|
||||
assertEquals(0.3, fins.getFinFront().x, EPSILON);
|
||||
assertEquals(0.85, fins.getFinFront().y, EPSILON);
|
||||
assertEquals(-0.05, fins.getAxialOffset(), EPSILON);
|
||||
assertEquals(0.3, fins.getLength(), EPSILON);
|
||||
|
||||
}{ // case 5:
|
||||
fins.setAxialOffset( AxialMethod.BOTTOM, 0.0);
|
||||
fins.setPoints(initialPoints);
|
||||
|
||||
// vvvv function under test vvvv
|
||||
fins.setPoint( lastIndex, xf + 0.1, 0.1f);
|
||||
fins.setPoint( lastIndex, xf + 0.1, yf + 0.1f);
|
||||
// ^^^^ function under test ^^^^
|
||||
|
||||
|
||||
assertEquals(0.6, fins.getFinFront().x, EPSILON);
|
||||
assertEquals(0.7, fins.getFinFront().y, EPSILON);
|
||||
assertEquals(0.1, fins.getAxialOffset(), EPSILON);
|
||||
assertEquals(0.5f, fins.getLength(), EPSILON);
|
||||
|
||||
final Coordinate[] postPoints = fins.getFinPoints();
|
||||
assertEquals(postPoints.length, 4);
|
||||
assertEquals(postPoints.length, 3);
|
||||
|
||||
// mid-point
|
||||
assertEquals(0.4, postPoints[1].x, EPSILON);
|
||||
@ -713,25 +730,21 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
|
||||
// pseudo last point
|
||||
assertEquals(0.5, postPoints[2].x, EPSILON);
|
||||
assertEquals(0.1, postPoints[2].y, EPSILON);
|
||||
assertEquals(-0.2, postPoints[2].y, EPSILON);
|
||||
|
||||
// last point
|
||||
assertEquals(0.4, postPoints[3].x, EPSILON);
|
||||
assertEquals(-0.2, postPoints[3].y, EPSILON);
|
||||
|
||||
assertEquals(0.6, fins.getFinFront().x, EPSILON);
|
||||
assertEquals(0.7, fins.getFinFront().y, EPSILON);
|
||||
assertEquals(0.0, fins.getAxialOffset(), EPSILON);
|
||||
assertEquals(0.4f, fins.getLength(), EPSILON);
|
||||
|
||||
}{ // case 6:
|
||||
fins.setAxialOffset( AxialMethod.BOTTOM, 0.0);
|
||||
fins.setPoints(initialPoints);
|
||||
|
||||
// vvvv function under test vvvv
|
||||
fins.setPoint( lastIndex, xf - 0.1, 0.1f);
|
||||
fins.setPoint( lastIndex, xf - 0.1, yf + 0.1f);
|
||||
// ^^^^ function under test ^^^^
|
||||
|
||||
assertEquals(0.6, fins.getFinFront().x, EPSILON);
|
||||
assertEquals(0.7, fins.getFinFront().y, EPSILON);
|
||||
assertEquals(-0.1, fins.getAxialOffset(), EPSILON);
|
||||
assertEquals(0.3, fins.getLength(), EPSILON);
|
||||
|
||||
final Coordinate[] postPoints = fins.getFinPoints();
|
||||
assertEquals(postPoints.length, 3);
|
||||
|
||||
@ -743,10 +756,6 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
assertEquals(0.3, postPoints[2].x, EPSILON);
|
||||
assertEquals(-0.15, postPoints[2].y, EPSILON);
|
||||
|
||||
assertEquals(0.6, fins.getFinFront().x, EPSILON);
|
||||
assertEquals(0.7, fins.getFinFront().y, EPSILON);
|
||||
assertEquals(-0.1, fins.getAxialOffset(), EPSILON);
|
||||
assertEquals(0.3, fins.getLength(), EPSILON);
|
||||
}
|
||||
}
|
||||
|
||||
@ -805,54 +814,57 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
assertEquals(0.5, phantomBody.getOuterRadius(), EPSILON);
|
||||
assertEquals(0.0, phantomBody.getLength(), EPSILON);
|
||||
}{
|
||||
// (1)---------(2)
|
||||
// | Fin |
|
||||
// | |
|
||||
// (0)----+----(3)
|
||||
// |
|
||||
// (body)
|
||||
final FreeformFinSet fins = new FreeformFinSet();
|
||||
fins.setFinCount(4);
|
||||
Coordinate[] points = new Coordinate[]{
|
||||
new Coordinate(0.0, 0.0),
|
||||
new Coordinate(-0.0508, 0.007721),
|
||||
new Coordinate(0.0, 0.01544),
|
||||
new Coordinate(0.0254, 0.007721),
|
||||
new Coordinate(1.1e-4, 0.0) // final point is within the testing thresholds :/
|
||||
};
|
||||
fins.setPoints(points);
|
||||
|
||||
fins.setName("SquareFin");
|
||||
phantomBody.addChild(fins);
|
||||
assertEquals(1, phantomBody.getChildCount());
|
||||
fins.setAxialOffset(AxialMethod.MIDDLE, 0.0);
|
||||
fins.setPoints(new Coordinate[]{
|
||||
new Coordinate(-0.5, 0.0),
|
||||
new Coordinate(-0.5, 1.0),
|
||||
new Coordinate(0.5, 1.0),
|
||||
new Coordinate(0.5, 0.0)
|
||||
});
|
||||
|
||||
}{ // postconditions
|
||||
final FreeformFinSet fins = (FreeformFinSet) phantomBody.getChild(0);
|
||||
FreeformFinSet fins = (FreeformFinSet) rkt.getChild(0).getChild(3).getChild(0);
|
||||
|
||||
assertEquals(AxialMethod.MIDDLE, fins.getAxialMethod());
|
||||
assertEquals(0.0, fins.getAxialOffset(), EPSILON);
|
||||
|
||||
assertEquals(-0.5, fins.getFinFront().x, EPSILON);
|
||||
assertEquals(0.5, fins.getFinFront().y, EPSILON);
|
||||
|
||||
final Coordinate[] postPoints = fins.getFinPoints();
|
||||
assertEquals(6, postPoints.length);
|
||||
assertEquals(4, postPoints.length);
|
||||
|
||||
// p1
|
||||
assertEquals(-0.0508, postPoints[1].x, EPSILON);
|
||||
assertEquals(0.007721, postPoints[1].y, EPSILON);
|
||||
// p0
|
||||
assertEquals("p0::x", 0.0, postPoints[0].x, EPSILON);
|
||||
assertEquals("p0::y", 0.0, postPoints[0].y, EPSILON);
|
||||
|
||||
// p2
|
||||
assertEquals(0.0, postPoints[2].x, EPSILON);
|
||||
assertEquals(0.01544, postPoints[2].y, EPSILON);
|
||||
// p1
|
||||
assertEquals("p1::x", 0.0, postPoints[1].x, EPSILON);
|
||||
assertEquals("p1::y", 1.0, postPoints[1].y, EPSILON);
|
||||
|
||||
// p3
|
||||
assertEquals(0.0254, postPoints[3].x, EPSILON);
|
||||
assertEquals(0.007721, postPoints[3].y, EPSILON);
|
||||
// p2
|
||||
assertEquals("p2::x", 1.0, postPoints[2].x, EPSILON);
|
||||
assertEquals("p2::y", 1.0, postPoints[2].y, EPSILON);
|
||||
|
||||
// p4
|
||||
assertEquals(0.00011, postPoints[4].x, EPSILON);
|
||||
assertEquals(0.0, postPoints[4].y, EPSILON);
|
||||
// p3 / last
|
||||
assertEquals("p3::x", 1.0, postPoints[3].x, EPSILON);
|
||||
assertEquals("p3::y", 0.0, postPoints[3].y, EPSILON);
|
||||
|
||||
// p/last: generated by loading code:
|
||||
assertEquals(0.0, postPoints[5].x, EPSILON);
|
||||
assertEquals(0.0, postPoints[5].y, EPSILON);
|
||||
|
||||
assertEquals(0.0, fins.getLength(), EPSILON);
|
||||
assertEquals(0.0, fins.getFinFront().x, EPSILON);
|
||||
assertEquals(0.5, fins.getFinFront().y, EPSILON);
|
||||
assertEquals(1.0, fins.getLength(), EPSILON);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetFirstPoint_testNonIntersection() {
|
||||
public void testSetFirstPoint_clampToLast() {
|
||||
final Rocket rkt = createTemplateRocket();
|
||||
final Transition tailCone = (Transition) rkt.getChild(0).getChild(2);
|
||||
final FreeformFinSet fins = this.createFinOnConicalTransition(tailCone);
|
||||
@ -868,22 +880,22 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
// vv Test Target vv
|
||||
fins.setPoint( 0, 0.6, 0);
|
||||
// ^^ Test Target ^^
|
||||
|
||||
|
||||
assertEquals(fins.getFinPoints()[ 0], Coordinate.ZERO);
|
||||
|
||||
// setting the first point actually offsets the whole fin by that amount:
|
||||
final double expFinOffset = 1.0;
|
||||
final double expFinOffset = 0.8;
|
||||
assertEquals("Resultant fin offset does not match!", expFinOffset, fins.getAxialOffset(), EPSILON);
|
||||
|
||||
assertEquals( 3, fins.getPointCount());
|
||||
Coordinate actualLastPoint = fins.getFinPoints()[2];
|
||||
assertEquals("last point did not adjust correctly: ", 0f, actualLastPoint.x, EPSILON);
|
||||
assertEquals("last point did not adjust correctly: ", 0f, actualLastPoint.y, EPSILON);
|
||||
assertEquals(0, actualLastPoint.x, EPSILON);
|
||||
assertEquals(0, actualLastPoint.y, EPSILON);
|
||||
assertEquals("New fin length is wrong: ", 0.0, fins.getLength(), EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetPoint_otherPoint() throws IllegalFinPointException {
|
||||
public void testSetPoint_otherPoint(){
|
||||
// combine the simple case with the complicated to ensure that the simple case is flagged, tested, and debugged before running the more complicated case...
|
||||
{ // setting points on a Tube Body is the simpler case. Test this first:
|
||||
final Rocket rkt = createTemplateRocket();
|
||||
@ -917,31 +929,66 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetOffset_triggerClampCorrection() {
|
||||
|
||||
@Test
|
||||
public void testSetOffset_triggerLeadingClampCorrection() {
|
||||
// test correction of last point due to moving entire fin:
|
||||
final Rocket rkt = createTemplateRocket();
|
||||
final Transition tailCone = (Transition) rkt.getChild(0).getChild(2);
|
||||
final FreeformFinSet fins = this.createFinOnConicalTransition(tailCone);
|
||||
|
||||
|
||||
final int lastIndex = fins.getPointCount()-1;
|
||||
|
||||
final double initXOffset = fins.getAxialOffset();
|
||||
assertEquals( 0.4, initXOffset, EPSILON); // pre-condition
|
||||
final double newXTop = 0.85;
|
||||
final double expFinOffset = 0.6;
|
||||
final double expLength = tailCone.getLength() - expFinOffset;
|
||||
fins.setAxialOffset( AxialMethod.TOP, newXTop);
|
||||
{ // pre-condition
|
||||
assertEquals(AxialMethod.TOP, fins.getAxialMethod());
|
||||
assertEquals(0.4, fins.getAxialOffset(), EPSILON);
|
||||
assertEquals(0.4, fins.getLength(), EPSILON);
|
||||
}
|
||||
|
||||
// vv Test Target vv
|
||||
fins.setAxialOffset( -0.2);
|
||||
// ^^ Test Target ^^
|
||||
|
||||
// fin start: 0.4 => 0.8 [body]
|
||||
// fin end: 0.8 => 0.99 [body]
|
||||
assertEquals( expFinOffset, fins.getAxialOffset(), EPSILON);
|
||||
assertEquals( expLength, fins.getLength(), EPSILON);
|
||||
|
||||
// SHOULD DEFINITELY CHANGE
|
||||
Coordinate actualLastPoint = fins.getFinPoints()[ lastIndex];
|
||||
// fin end: 0.8 => 1.2 [body]
|
||||
assertEquals( -0.2, fins.getAxialOffset(), EPSILON);
|
||||
assertEquals( 0.4, fins.getLength(), EPSILON);
|
||||
|
||||
// SHOULD DEFINITELY CHANGE
|
||||
Coordinate actualLastPoint = fins.getFinPoints()[ lastIndex];
|
||||
assertEquals( 0.4, actualLastPoint.x, EPSILON);
|
||||
assertEquals( -0.2, actualLastPoint.y, EPSILON);
|
||||
}
|
||||
assertEquals( -0.1, actualLastPoint.y, EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetOffset_triggerTrailingClampCorrection() {
|
||||
// test correction of last point due to moving entire fin:
|
||||
final Rocket rkt = createTemplateRocket();
|
||||
final Transition tailCone = (Transition) rkt.getChild(0).getChild(2);
|
||||
final FreeformFinSet fins = this.createFinOnConicalTransition(tailCone);
|
||||
|
||||
final int lastIndex = fins.getPointCount()-1;
|
||||
|
||||
{ // pre-condition
|
||||
assertEquals(AxialMethod.TOP, fins.getAxialMethod());
|
||||
assertEquals(0.4, fins.getAxialOffset(), EPSILON);
|
||||
assertEquals(0.4, fins.getLength(), EPSILON);
|
||||
}
|
||||
|
||||
// vv Test Target vv
|
||||
fins.setAxialOffset( 0.8);
|
||||
// ^^ Test Target ^^
|
||||
|
||||
// fin start: 0.4 => 0.8 [body]
|
||||
// fin end: 0.8 => 1.2 [body]
|
||||
assertEquals( 0.8, fins.getAxialOffset(), EPSILON);
|
||||
assertEquals( 0.4, fins.getLength(), EPSILON);
|
||||
|
||||
// SHOULD DEFINITELY CHANGE
|
||||
Coordinate actualLastPoint = fins.getFinPoints()[ lastIndex];
|
||||
assertEquals( 0.4, actualLastPoint.x, EPSILON);
|
||||
assertEquals( -0.1, actualLastPoint.y, EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testComputeCM_mountlessFin(){
|
||||
@ -1012,7 +1059,7 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
final double x_delta = fin.getAxialOffset(AxialMethod.TOP);
|
||||
|
||||
final Coordinate[] actualPoints = fin.getFinPoints();
|
||||
|
||||
|
||||
final String rawPointDescr = "\n"+fin.toDebugDetail().toString()+"\n>> axial offset: "+x_delta;
|
||||
|
||||
Coordinate[] displayPoints = FinSet.translatePoints( actualPoints, x_delta, 0);
|
||||
@ -1164,32 +1211,20 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenerateBodyPointsOnBodyTube(){
|
||||
public void testGenerateRootPointsOnBodyTube(){
|
||||
final Rocket rkt = createTemplateRocket();
|
||||
final BodyTube body = (BodyTube) rkt.getChild(0).getChild(1);
|
||||
final FreeformFinSet fins = this.createFinOnTube(body);
|
||||
|
||||
final Coordinate finFront = fins.getFinFront();
|
||||
final Coordinate[] finPoints = fins.getFinPoints();
|
||||
final Coordinate[] finPointsFromBody = FinSet.translatePoints( finPoints, finFront.x, finFront.y);
|
||||
|
||||
{ // body points (relative to body)
|
||||
final Coordinate[] mountPoints = fins.getMountPoints();
|
||||
|
||||
assertEquals("Method should only generate minimal points for a conical transition fin body! ", 2, mountPoints.length );
|
||||
assertEquals("incorrect body points! ", finPointsFromBody[0].x, mountPoints[0].x, EPSILON);
|
||||
assertEquals("incorrect body points! ", finPointsFromBody[0].y, mountPoints[0].y, EPSILON);
|
||||
assertEquals("incorrect body points! ", finPointsFromBody[finPoints.length-1].x, mountPoints[1].x, EPSILON);
|
||||
assertEquals("incorrect body points! ", finPointsFromBody[finPoints.length-1].y, mountPoints[1].y, EPSILON);
|
||||
}
|
||||
{ // root points (relative to fin-front)
|
||||
final Coordinate[] finPoints = fins.getFinPoints();
|
||||
final Coordinate[] rootPoints = fins.getRootPoints();
|
||||
|
||||
|
||||
assertEquals("Method should only generate minimal points for a conical transition fin body! ", 2, rootPoints.length );
|
||||
assertEquals("incorrect body points! ", finPoints[0].x, rootPoints[0].x, EPSILON);
|
||||
assertEquals("incorrect body points! ", finPoints[0].y, rootPoints[0].y, EPSILON);
|
||||
assertEquals("incorrect body points! ", finPoints[finPoints.length-1].x, rootPoints[1].x, EPSILON);
|
||||
assertEquals("incorrect body points! ", finPoints[finPoints.length-1].y, rootPoints[1].y, EPSILON);
|
||||
assertEquals("incorrect body point: 0::x ! ", finPoints[0].x, rootPoints[0].x, EPSILON);
|
||||
assertEquals("incorrect body point: 0::y ! ", finPoints[0].y, rootPoints[0].y, EPSILON);
|
||||
assertEquals("incorrect body point: -1::x !", finPoints[finPoints.length-1].x, rootPoints[1].x, EPSILON);
|
||||
assertEquals("incorrect body point: -1::y !", finPoints[finPoints.length-1].y, rootPoints[1].y, EPSILON);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1199,18 +1234,8 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
final Transition tailCone = (Transition) rkt.getChild(0).getChild(2);
|
||||
final FreeformFinSet fins = this.createFinOnConicalTransition(tailCone);
|
||||
|
||||
final Coordinate[] finPoints = fins.getFinPoints();
|
||||
|
||||
{ // body points (relative to body)
|
||||
final Coordinate[] bodyPoints = fins.getMountPoints();
|
||||
|
||||
assertEquals("Method should only generate minimal points for a conical transition fin body! ", 2, bodyPoints.length );
|
||||
assertEquals("incorrect body points! ", 0.0, bodyPoints[0].x, EPSILON);
|
||||
assertEquals("incorrect body points! ", 1.0, bodyPoints[0].y, EPSILON);
|
||||
assertEquals("incorrect body points! ", 1.0, bodyPoints[1].x, EPSILON);
|
||||
assertEquals("incorrect body points! ", 0.5, bodyPoints[1].y, EPSILON);
|
||||
}
|
||||
{ // body points (relative to root)
|
||||
final Coordinate[] finPoints = fins.getFinPoints();
|
||||
final Coordinate[] rootPoints = fins.getRootPoints();
|
||||
|
||||
assertEquals("Method should only generate minimal points for a conical transition fin body! ", 2, rootPoints.length );
|
||||
@ -1233,17 +1258,14 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
{ // fin points (relative to fin) // preconditions
|
||||
assertEquals(4, finPoints.length);
|
||||
|
||||
assertEquals("incorrect body points! ", 0f, finPoints[0].x, EPSILON);
|
||||
assertEquals("incorrect body points! ", 0f, finPoints[0].y, EPSILON);
|
||||
assertEquals("incorrect fin points! ", 0f, finPoints[0].x, EPSILON);
|
||||
assertEquals("incorrect fin points! ", 0f, finPoints[0].y, EPSILON);
|
||||
|
||||
assertEquals("incorrect body points! ", 0.8, finPoints[3].x, EPSILON);
|
||||
assertEquals("incorrect fin points! ", 0.8, finPoints[3].x, EPSILON);
|
||||
|
||||
// ?? SMOKING GUN:
|
||||
// ?? is this y-value of the fin not getting snapped to the body?
|
||||
|
||||
assertEquals(nose.getRadius(0.8+finFront.x) - finFront.y, finPoints[3].y, EPSILON);
|
||||
|
||||
assertEquals("incorrect body points! ", 0.78466912, finPoints[3].y, EPSILON);
|
||||
assertEquals("incorrect fin points! ", 0.78466912, finPoints[3].y, EPSILON);
|
||||
|
||||
}{ // body points (relative to fin)
|
||||
final Coordinate[] rootPoints = fins.getRootPoints();
|
||||
@ -1273,38 +1295,14 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
nose.getRadius(rootPoints[testIndex].x + finFront.x) - finFront.y, rootPoints[testIndex].y, EPSILON);
|
||||
}
|
||||
}
|
||||
}{ // body points (relative to body)
|
||||
final Coordinate[] mountPoints = fins.getMountPoints();
|
||||
assertEquals(101, mountPoints.length);
|
||||
|
||||
// trivial, and uninteresting:
|
||||
assertEquals("incorrect body points! ", 0.0, mountPoints[0].x, EPSILON);
|
||||
assertEquals("incorrect body points! ", 0.0, mountPoints[0].y, EPSILON);
|
||||
|
||||
// n.b.: This should match EXACTLY the end point of the fin. (in fin coordinates)
|
||||
assertEquals("incorrect body points! ", 1.0, mountPoints[mountPoints.length-1].x, EPSILON);
|
||||
assertEquals("incorrect body points! ", 1.0, mountPoints[mountPoints.length-1].y, EPSILON);
|
||||
|
||||
{// the tests within this scope is are rather fragile, and may break for reasons other than bugs :(
|
||||
// the number of points is somewhat arbitrary, but if this test fails, the rest *definitely* will.
|
||||
assertEquals("Method is generating how many points, in general? ", 101, mountPoints.length );
|
||||
|
||||
final int[] testIndices = { 3, 12, 61, 88};
|
||||
final double[] expectedX = { 0.03, 0.12, 0.61, 0.88};
|
||||
|
||||
for( int testCase = 0; testCase < testIndices.length; testCase++){
|
||||
final int testIndex = testIndices[testCase];
|
||||
assertEquals(String.format("Body points @ %d :: x coordinate mismatch!", testIndex),
|
||||
expectedX[testCase], mountPoints[testIndex].x, EPSILON);
|
||||
assertEquals(String.format("Body points @ %d :: y coordinate mismatch!", testIndex),
|
||||
nose.getRadius(mountPoints[testIndex].x), mountPoints[testIndex].y, EPSILON);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFreeFormCMWithNegativeY() throws Exception {
|
||||
final Rocket rkt = createTemplateRocket();
|
||||
final BodyTube body = (BodyTube) rkt.getChild(0).getChild(1);
|
||||
|
||||
// A user submitted an ork file which could not be simulated.
|
||||
// This Fin set is constructed to have the same problem. It is a square and rectangle
|
||||
// where the two trailing edge corners of the rectangle satisfy y_0 = -y_1
|
||||
@ -1323,33 +1321,99 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
// |
|
||||
// |
|
||||
FreeformFinSet fins = new FreeformFinSet();
|
||||
fins.setAxialOffset( AxialMethod.BOTTOM, -1.0);
|
||||
body.addChild(fins);
|
||||
fins.setAxialOffset( AxialMethod.TOP, 1.0);
|
||||
|
||||
Coordinate[] points = new Coordinate[] {
|
||||
new Coordinate(0, 0),
|
||||
new Coordinate(0, 1),
|
||||
new Coordinate(2, 1),
|
||||
new Coordinate(2, -1),
|
||||
new Coordinate(1, -1),
|
||||
new Coordinate(1, 0)
|
||||
new Coordinate(0.0, 0),
|
||||
new Coordinate(0.0, 1),
|
||||
new Coordinate(2.0, 1),
|
||||
new Coordinate(2.0, -1),
|
||||
new Coordinate(1.0001, -1),
|
||||
new Coordinate(1.0, 0)
|
||||
};
|
||||
fins.setPoints(points);
|
||||
|
||||
System.err.println(fins.toDebugDetail());
|
||||
|
||||
fins.setPoints( points);
|
||||
fins.setFilletRadius( 0.0);
|
||||
fins.setTabHeight( 0.0);
|
||||
fins.setCrossSection( CrossSection.SQUARE ); // to ensure uniform density
|
||||
fins.setMaterial( Material.newMaterial(Type.BULK, "dummy", 1.0, true));
|
||||
|
||||
assertEquals( 3.0, fins.getPlanformArea(), EPSILON);
|
||||
assertEquals( 3.0, fins.getPlanformArea(), 0.0001);
|
||||
|
||||
final Coordinate cg = fins.getCG();
|
||||
assertEquals(3.0, fins.getPlanformArea(), EPSILON);
|
||||
assertEquals(3.5 / 3.0, cg.x, EPSILON);
|
||||
assertEquals(0.5 / 3.0, cg.y, EPSILON);
|
||||
assertEquals(1.1666, cg.x, 0.0001);
|
||||
assertEquals(1.1666, cg.y, 0.0001);
|
||||
assertEquals( 0.0, cg.z, EPSILON);
|
||||
assertEquals( 0.009, cg.weight, EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFreeFormCMWithTooManyPoints() {
|
||||
final Rocket rkt = createTemplateRocket();
|
||||
final BodyTube phantomBody = (BodyTube) rkt.getChild(0).getChild(3);
|
||||
final FreeformFinSet fins = new FreeformFinSet();
|
||||
|
||||
// fins.setAxialOffset( Position.BOTTOM, 1.0); // ERROR: no parent!
|
||||
final Coordinate[] setPoints = new Coordinate[] {
|
||||
new Coordinate(0.006349996571001852, 0.0),
|
||||
new Coordinate(0.00635, 0.022224999999999998),
|
||||
new Coordinate(0.0067056, 0.02716387422039681),
|
||||
new Coordinate(0.007619999999999999, 0.03174998285500926),
|
||||
new Coordinate(0.0093472, 0.036159702695982766),
|
||||
new Coordinate(0.0110998, 0.03951108977512263),
|
||||
new Coordinate(0.028134012585410983, 0.06508746485276898),
|
||||
new Coordinate(0.030427066902717206, 0.06843885193190885),
|
||||
new Coordinate(0.03298470441048184, 0.07170204461422924),
|
||||
new Coordinate(0.0351895643309686, 0.073906904534716),
|
||||
new Coordinate(0.03801178502919164, 0.0756707924711054),
|
||||
new Coordinate(0.04101039452105363, 0.07672912523293904),
|
||||
new Coordinate(0.04409719840973508, 0.07743468040749481),
|
||||
new Coordinate(0.04762497428251389, 0.07787565239159215),
|
||||
new Coordinate(0.0511527501552927, 0.07797799999999999),
|
||||
new Coordinate(0.08021280390730812, 0.07797799999999999),
|
||||
new Coordinate(0.08127113666914176, 0.07796384678841163),
|
||||
new Coordinate(0.08206488624051698, 0.07787565239159215),
|
||||
new Coordinate(0.08281453861348248, 0.07747877760590453),
|
||||
new Coordinate(0.08316731620076037, 0.07681731962975852),
|
||||
new Coordinate(0.08325551059757984, 0.07584718126474434),
|
||||
new Coordinate(0.083312, 0.07487704289973017),
|
||||
new Coordinate(0.08329960779598958, 0.033293384799349984),
|
||||
new Coordinate(0.08325551059757984, 0.03254373242638449),
|
||||
new Coordinate(0.08307912180394089, 0.03174998285500926),
|
||||
new Coordinate(0.08263814981984355, 0.031132622077272968),
|
||||
new Coordinate(0.08180030305005857, 0.030691650093175617),
|
||||
new Coordinate(0.0806978730898152, 0.030479999999999997),
|
||||
new Coordinate(0.06178017497203885, 0.030479999999999997),
|
||||
new Coordinate(0.05635621956764143, 0.030479999999999997),
|
||||
new Coordinate(0.05344580447259892, 0.030225999999999996),
|
||||
new Coordinate(0.051461430544160844, 0.0292862),
|
||||
new Coordinate(0.050006222996639586, 0.027711399999999997),
|
||||
new Coordinate(0.04921247342526435, 0.0261112),
|
||||
new Coordinate(0.048683307044347535, 0.024002999999999997),
|
||||
new Coordinate(0.048768, 0.022098),
|
||||
new Coordinate(0.048768, 0.0)
|
||||
};
|
||||
fins.setPoints( setPoints);
|
||||
phantomBody.addChild(fins);
|
||||
|
||||
{ // fin points (relative to fin) // preconditions
|
||||
final Coordinate[] finPoints = fins.getFinPoints();
|
||||
assertEquals(37, finPoints.length);
|
||||
|
||||
// fin root length:
|
||||
assertEquals(0.04241800, fins.length, EPSILON);
|
||||
|
||||
// p_first
|
||||
assertEquals(0f, finPoints[0].x, EPSILON);
|
||||
assertEquals(0f, finPoints[0].y, EPSILON);
|
||||
|
||||
// p_last
|
||||
assertEquals(0.042418, finPoints[36].x, EPSILON);
|
||||
assertEquals(0., finPoints[36].y, EPSILON);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -426,6 +426,7 @@ public class FreeformFinSetConfig extends FinSetConfig {
|
||||
finset.setPoint(dragIndex, point.x, point.y);
|
||||
|
||||
final double bodyFront = -finset.getAxialFront();
|
||||
|
||||
if(0 == dragIndex && bodyFront > point.x){
|
||||
dragIndex = 1;
|
||||
}
|
||||
@ -447,6 +448,8 @@ public class FreeformFinSetConfig extends FinSetConfig {
|
||||
if ( 0 < clickIndex) {
|
||||
// if ctrl+click, delete point
|
||||
try {
|
||||
Point2D.Double point = getCoordinates(event);
|
||||
System.err.println(String.format("---- Removing Point %d @ %g, %g", clickIndex, point.x, point.y));
|
||||
finset.removePoint(clickIndex);
|
||||
} catch (IllegalFinPointException ignore) {
|
||||
log.error("Ignoring IllegalFinPointException while dragging, dragIndex=" + dragIndex + ". This is likely an internal error.");
|
||||
|
Loading…
x
Reference in New Issue
Block a user