[fixes #471] Refactoring FreeformFinSet to accept root points outside of the base. (which generates bridge-points on-load)
This commit is contained in:
parent
151a4d864d
commit
72c6f1d64d
@ -20,10 +20,11 @@ public class FreeformFinSet extends FinSet {
|
||||
private static final Logger log = LoggerFactory.getLogger(FreeformFinSet.class);
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
public static final double MIN_ROOT_CHORD=0.01; // enforce this to prevent erroneous 'intersection' exceptions.
|
||||
|
||||
private List<Coordinate> points = new ArrayList<>();
|
||||
|
||||
private static final double SNAP_SMALLER_THAN = 1e-6;
|
||||
private static final double IGNORE_SMALLER_THAN = 1e-12;
|
||||
|
||||
public FreeformFinSet() {
|
||||
points.add(Coordinate.ZERO);
|
||||
points.add(new Coordinate(0.025, 0.05));
|
||||
@ -33,10 +34,6 @@ public class FreeformFinSet extends FinSet {
|
||||
this.length = 0.05;
|
||||
}
|
||||
|
||||
public FreeformFinSet(Coordinate[] finpoints) {
|
||||
setPoints(finpoints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an existing fin set into a freeform fin set. The specified
|
||||
* fin set is taken out of the rocket tree (if any) and the new component
|
||||
@ -68,8 +65,9 @@ public class FreeformFinSet extends FinSet {
|
||||
}
|
||||
|
||||
// Create the freeform fin set
|
||||
Coordinate[] finpoints = finset.getFinPoints();
|
||||
freeform = new FreeformFinSet(finpoints);
|
||||
Coordinate[] finPoints = finset.getFinPoints();
|
||||
freeform = new FreeformFinSet();
|
||||
freeform.setPoints(Arrays.asList(finPoints));
|
||||
freeform.setAxialOffset(finset.getAxialMethod(), finset.getAxialOffset());
|
||||
|
||||
// Copy component attributes
|
||||
@ -148,22 +146,18 @@ public class FreeformFinSet extends FinSet {
|
||||
return points.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* The first point is assumed to be at the origin. If it isn't, it will be moved there.
|
||||
*
|
||||
* @param newPoints new fin points ; replaces previous fin points
|
||||
/** 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);
|
||||
newPoints = translatePoints( newPoints, -p0.x, -p0.y);
|
||||
}
|
||||
|
||||
ArrayList<Coordinate> newList = new ArrayList<>(Arrays.asList( newPoints));
|
||||
setPoints( newList );
|
||||
setPoints(new ArrayList<>(Arrays.asList(newPoints)));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The first point is assumed to be at the origin. If it isn't, it will be moved there.
|
||||
*
|
||||
@ -172,16 +166,22 @@ public class FreeformFinSet extends FinSet {
|
||||
public void setPoints( List<Coordinate> newPoints) {
|
||||
// copy the old points, in case validation fails
|
||||
List<Coordinate> copy = new ArrayList<>(this.points);
|
||||
|
||||
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()){
|
||||
// on error, reset to the old points
|
||||
this.points = copy;
|
||||
}
|
||||
|
||||
this.length = points.get(points.size() - 1).x;
|
||||
fireComponentChangeEvent(ComponentChangeEvent.AEROMASS_CHANGE);
|
||||
}
|
||||
|
||||
@ -223,62 +223,19 @@ public class FreeformFinSet extends FinSet {
|
||||
* @param yRequest the y-coordinate.
|
||||
*/
|
||||
public void setPoint(final int index, final double xRequest, final double yRequest) {
|
||||
final SymmetricComponent body = (SymmetricComponent)getParent();
|
||||
|
||||
final int lastPointIndex = this.points.size() - 1;
|
||||
final double xFinEnd = points.get(lastPointIndex).x;
|
||||
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 = -xFinStart; // x-offset from fin to body; fin-frame
|
||||
|
||||
// initial guess at these values; further checks follow.
|
||||
double xAgreed = xRequest;
|
||||
double yAgreed = yRequest;
|
||||
|
||||
// clamp x coordinates:
|
||||
// within bounds, and consistent with the rest of the fin (at this time).
|
||||
if(null != this.getParent()) {
|
||||
if (0 == index) {
|
||||
// restrict the first point to be between the parent's start, and the last fin point
|
||||
xAgreed = Math.max( xBodyStart, Math.min( xAgreed, xFinEnd - MIN_ROOT_CHORD ));
|
||||
}else if( lastPointIndex == index ){
|
||||
// restrict the last point to be between the first fin point, and the parent's end length.
|
||||
xAgreed = Math.max( MIN_ROOT_CHORD, Math.min( xAgreed, xBodyStart + body.getLength()));
|
||||
}
|
||||
|
||||
// adjust y-value to be consistent with body
|
||||
final double yBody_atPoint= body.getRadius( xFinStart + xAgreed) - yFinStart;
|
||||
if (index == 0 || index == lastPointIndex) {
|
||||
// for the first and last points: set y-value to *exactly* match parent body:
|
||||
yAgreed = yBody_atPoint;
|
||||
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 {
|
||||
// for all other points, merely insist that the point is outside the body...
|
||||
yAgreed = Math.max( yAgreed, yBody_atPoint);
|
||||
// interior points can never change the
|
||||
points.set(index, new Coordinate(xRequest, yRequest));
|
||||
clampInteriorPoint(index);
|
||||
}
|
||||
|
||||
// if moving either begin or end points, we'll probably have to update the position, as well.
|
||||
final AxialMethod locationMethod = getAxialMethod();
|
||||
final double priorXOffset = getAxialOffset();
|
||||
|
||||
if( 0 == index){
|
||||
movePoints( xAgreed);
|
||||
this.length = points.get( lastPointIndex ).x;
|
||||
|
||||
if( AxialMethod.TOP == locationMethod){
|
||||
setAxialOffset( AxialMethod.TOP, priorXOffset + xAgreed );
|
||||
}else if(AxialMethod.MIDDLE == locationMethod){
|
||||
setAxialOffset( AxialMethod.MIDDLE, priorXOffset + xAgreed/2 );
|
||||
}
|
||||
}else if( lastPointIndex == index ){
|
||||
points.set(index, new Coordinate( xAgreed, yAgreed ));
|
||||
this.length = xAgreed;
|
||||
|
||||
if( AxialMethod.MIDDLE == locationMethod){
|
||||
setAxialOffset( AxialMethod.MIDDLE, priorXOffset + (xAgreed - xFinEnd)/2 );
|
||||
}else if(AxialMethod.BOTTOM== locationMethod){
|
||||
setAxialOffset( AxialMethod.BOTTOM, priorXOffset + (xAgreed - xFinEnd) );
|
||||
}
|
||||
}else{
|
||||
points.set(index, new Coordinate( xAgreed, yAgreed ));
|
||||
}
|
||||
|
||||
// this maps the last index and the next-to-last-index to the same 'testIndex'
|
||||
@ -292,11 +249,11 @@ public class FreeformFinSet extends FinSet {
|
||||
fireComponentChangeEvent(ComponentChangeEvent.AEROMASS_CHANGE);
|
||||
}
|
||||
|
||||
private void movePoints( final double delta_x){
|
||||
private void movePoints(final double delta_x, final double delta_y) {
|
||||
// skip 0th index -- it's the local origin and is always (0,0)
|
||||
for (int index = 1; index < points.size(); ++index) {
|
||||
final Coordinate oldPoint = this.points.get(index);
|
||||
final Coordinate newPoint = oldPoint.sub( delta_x, 0.0f, 0.0f);
|
||||
final Coordinate newPoint = oldPoint.add(delta_x, delta_y, 0.0f);
|
||||
points.set(index, newPoint);
|
||||
}
|
||||
}
|
||||
@ -322,7 +279,6 @@ public class FreeformFinSet extends FinSet {
|
||||
return trans.get("FreeformFinSet.FreeformFinSet");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected RocketComponent copyWithOriginalID() {
|
||||
RocketComponent c = super.copyWithOriginalID();
|
||||
@ -354,70 +310,154 @@ public class FreeformFinSet extends FinSet {
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
final int lastPointIndex = this.points.size() - 1;
|
||||
this.length = points.get(lastPointIndex).x;
|
||||
|
||||
this.setAxialOffset(this.axialMethod, this.axialOffset);
|
||||
|
||||
clampFirstPoint();
|
||||
clampInteriorPoints();
|
||||
clampLastPoint();
|
||||
if(null != this.getParent()) {
|
||||
clampFirstPoint(points.get(0));
|
||||
for(int i=1; i < points.size()-1; i++) {
|
||||
clampInteriorPoint(i);
|
||||
}
|
||||
|
||||
clampLastPoint(null);
|
||||
|
||||
validateFinTab();
|
||||
}
|
||||
|
||||
// if we translate the points, correct the first point, because it may be inconsistent
|
||||
private void clampFirstPoint(){
|
||||
double xFinStart = getAxialFront(); // x @ fin start, body frame
|
||||
final double xFinOffset = getAxialOffset();
|
||||
if( 0 > xFinStart ){
|
||||
setAxialOffset( xFinOffset - xFinStart);
|
||||
}
|
||||
}
|
||||
|
||||
private void clampInteriorPoints(){
|
||||
if( null == this.parent ){
|
||||
// this is bad, but seems to only occur during unit tests.
|
||||
return;
|
||||
}
|
||||
final SymmetricComponent symmetricParent = (SymmetricComponent)this.getParent();
|
||||
private void clampFirstPoint(final Coordinate newPoint) {
|
||||
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
|
||||
|
||||
// omit end points index
|
||||
for( int index=1; index < (points.size()-1); ++index){
|
||||
final Coordinate oldPoint = this.points.get( index);
|
||||
double xDelta;
|
||||
double yDelta;
|
||||
|
||||
final double yBody = symmetricParent.getRadius( oldPoint.x + finFront.x);
|
||||
final double yFinPoint = finFront.y+ oldPoint.y;
|
||||
|
||||
if( yBody > yFinPoint ){
|
||||
final Coordinate newPoint = oldPoint.setY( yBody - finFront.y );
|
||||
points.set( index, newPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if we translate the points, the final point may become inconsistent
|
||||
private void clampLastPoint(){
|
||||
if( null == this.parent ){
|
||||
// this is bad, but seems to only occur during unit tests.
|
||||
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));
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
private void clampLastPoint(final Coordinate prior) {
|
||||
final SymmetricComponent body = (SymmetricComponent) getParent();
|
||||
// clamp the final x coord to the end of the parent body.
|
||||
final int lastPointIndex = points.size() - 1;
|
||||
final Coordinate oldPoint = points.get( lastPointIndex);
|
||||
|
||||
final double xFinStart_body = getAxialFront(); // x @ fin start, body frame
|
||||
final double xBodyEnd_fin = body.getLength() - xFinStart_body;
|
||||
final double xFinStart = getAxialFront(); // x of fin start, body-frame
|
||||
final double yFinStart = body.getRadius(xFinStart); // y of fin start, body-frame
|
||||
|
||||
double x_clamped = Math.min( oldPoint.x, xBodyEnd_fin);
|
||||
double y_clamped = body.getRadius( x_clamped+xFinStart_body) - body.getRadius( xFinStart_body);
|
||||
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
|
||||
|
||||
int lastIndex = points.size() - 1;
|
||||
final Coordinate cur = points.get(lastIndex);
|
||||
|
||||
double xDelta=0;
|
||||
|
||||
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));
|
||||
|
||||
}
|
||||
|
||||
|
||||
points.set( lastPointIndex, new Coordinate( x_clamped, y_clamped, 0));
|
||||
//System.err.println(String.format(".... @[-1]//C: delta = %f", xDelta));
|
||||
}
|
||||
|
||||
if(IGNORE_SMALLER_THAN < Math.abs(xDelta)) {
|
||||
lastIndex = points.size()-1;
|
||||
this.length = points.get(lastIndex).x;
|
||||
|
||||
if (AxialMethod.MIDDLE == getAxialMethod()) {
|
||||
setAxialOffset(AxialMethod.MIDDLE, getAxialOffset() + xDelta / 2);
|
||||
} else if (AxialMethod.BOTTOM == getAxialMethod()) {
|
||||
setAxialOffset(AxialMethod.BOTTOM, getAxialOffset() + xDelta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean validate() {
|
||||
@ -442,7 +482,8 @@ public class FreeformFinSet extends FinSet {
|
||||
// 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("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));
|
||||
@ -453,7 +494,8 @@ public class FreeformFinSet extends FinSet {
|
||||
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("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;
|
||||
}
|
||||
@ -493,8 +535,6 @@ public class FreeformFinSet extends FinSet {
|
||||
/**
|
||||
* Check if the line segment from targetIndex to targetIndex+1 intersects with any other part of the fin.
|
||||
*
|
||||
*
|
||||
*
|
||||
* @return true if an intersection was found
|
||||
*/
|
||||
private boolean intersects(final int targetIndex) {
|
||||
@ -503,21 +543,29 @@ public class FreeformFinSet extends FinSet {
|
||||
}
|
||||
|
||||
// (pre-check the indices above.)
|
||||
Point2D.Double p1 = new Point2D.Double( points.get(targetIndex).x, points.get(targetIndex).y);
|
||||
Point2D.Double p2 = new Point2D.Double( points.get(targetIndex+1).x, points.get(targetIndex+1).y);
|
||||
Line2D.Double targetLine = new Line2D.Double( p1, p2);
|
||||
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);
|
||||
final Line2D.Double targetLine = new Line2D.Double(pt1, pt2);
|
||||
|
||||
for (int comparisonIndex = 0; comparisonIndex < (points.size()-1); ++comparisonIndex ) {
|
||||
for (int comparisonIndex = targetIndex+1; comparisonIndex < (points.size() - 1); ++comparisonIndex) {
|
||||
if (2 > Math.abs(targetIndex - comparisonIndex)) {
|
||||
// a line segment will trivially not intersect with itself
|
||||
// nor can adjacent line segments intersect with each other, because they share a common endpoint.
|
||||
continue;
|
||||
}
|
||||
final Point2D.Double pc1 = new Point2D.Double(points.get(comparisonIndex).x, points.get(comparisonIndex).y); // p1
|
||||
final Point2D.Double pc2 = new Point2D.Double(points.get(comparisonIndex + 1).x, points.get(comparisonIndex + 1).y); // p2
|
||||
|
||||
Line2D.Double comparisonLine = new Line2D.Double( points.get(comparisonIndex).x, points.get(comparisonIndex).y, // p1
|
||||
points.get(comparisonIndex+1).x, points.get(comparisonIndex+1).y); // p2
|
||||
// special case for when the first and last points are co-located.
|
||||
if((0==targetIndex)&&(points.size()==comparisonIndex+2)&&(IGNORE_SMALLER_THAN > Math.abs(pt1.distance(pc2)))){
|
||||
continue;
|
||||
}
|
||||
|
||||
final Line2D.Double comparisonLine = new Line2D.Double(pc1, pc2);
|
||||
if (targetLine.intersectsLine(comparisonLine)) {
|
||||
log.error(String.format("Found intersection at %d-%d and %d-%d", targetIndex, targetIndex+1, comparisonIndex, comparisonIndex+1));
|
||||
log.error(String.format(" between (%g, %g) => (%g, %g)", pt1.x, pt1.y, pt2.x, pt2.y));
|
||||
log.error(String.format(" and (%g, %g) => (%g, %g)", pc1.x, pc1.y, pc2.x, pc2.y));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,7 +117,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)
|
||||
new Coordinate( 0.8, 0.9) // y-value should be automaticaly adjusted to snap to body
|
||||
};
|
||||
fins.setPoints(points);
|
||||
|
||||
@ -325,6 +325,8 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
assertEquals(Shape.ELLIPSOID, body.getType());
|
||||
assertEquals(1.0, body.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);
|
||||
@ -425,30 +427,6 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
assertEquals(0.8, added.y, 0.1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetPoint_firstPoint_boundsCheck() throws IllegalFinPointException {
|
||||
// more transitions trigger more complicated positioning math:
|
||||
Rocket rkt = createTemplateRocket();
|
||||
FreeformFinSet fins = (FreeformFinSet) rkt.getChild(0).getChild(0).getChild(0);
|
||||
final int startIndex = 0;
|
||||
final int lastIndex = fins.getPointCount()-1;
|
||||
// assert pre-conditions
|
||||
assertEquals( 1, fins.getFinCount());
|
||||
assertEquals( 3, lastIndex);
|
||||
|
||||
fins.setPoint( startIndex, -1, -1);
|
||||
final Coordinate act_p_0 = fins.getFinPoints()[0];
|
||||
{ // first point x is restricted to the front of the parent body:
|
||||
assertEquals( 0.0, act_p_0.x, EPSILON);
|
||||
assertEquals( AxialMethod.TOP, fins.getAxialMethod() );
|
||||
assertEquals( 0.0, fins.getAxialOffset(), EPSILON);
|
||||
}
|
||||
|
||||
{// first point y is restricted to the body
|
||||
assertEquals( 0.0, act_p_0.y, EPSILON);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetFirstPoint() throws IllegalFinPointException {
|
||||
// more transitions trigger more complicated positioning math:
|
||||
@ -458,7 +436,6 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
final Coordinate[] initialPoints = fins.getFinPoints();
|
||||
|
||||
// assert pre-conditions:
|
||||
assertEquals(0.4, fins.getAxialFront(), EPSILON);
|
||||
assertEquals(0.4, fins.getLength(), EPSILON);
|
||||
assertEquals(initialPoints[0], Coordinate.ZERO);
|
||||
assertEquals(initialPoints[1], new Coordinate(0.4, 0.2));
|
||||
@ -466,48 +443,146 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
assertEquals(1.0, finMount.getLength(), EPSILON);
|
||||
assertEquals(0.8, finMount.getRadius(fins.getAxialFront()), EPSILON);
|
||||
|
||||
// for a fin at these positions:
|
||||
final AxialMethod[] inputMethods = { AxialMethod.TOP, AxialMethod.TOP, AxialMethod.MIDDLE, AxialMethod.MIDDLE, AxialMethod.BOTTOM, AxialMethod.BOTTOM};
|
||||
final double[] inputOffsets = { 0.1, 0.1, 0.0, 0.0, 0.0, 0.0};
|
||||
|
||||
// move first by this delta...
|
||||
final double[] xDelta = { 0.2, -0.2, 0.1, -0.1, 0.1, -0.1};
|
||||
|
||||
// and check against these expected values:
|
||||
final double[] expectedFinStartx = { 0.3, 0.0, 0.4, 0.2, 0.7, 0.5};
|
||||
final double[] expectedFinStarty = { 0.85, 1.0, 0.8, 0.9, 0.65, 0.75};
|
||||
final double[] expectedFinLength = { 0.2, 0.5, 0.3, 0.5, 0.3, 0.5};
|
||||
final double[] expectedFinOffset = { 0.3, 0.0, 0.05, -0.05, 0.0, 0.0};
|
||||
final double[] expectedMidpointOffset = { 0.2, 0.5, 0.3, 0.5, 0.3, 0.5};
|
||||
final double[] expectedFinalPointOffset = { 0.2, 0.5, 0.3, 0.5, 0.3, 0.5};
|
||||
|
||||
for( int caseIndex=0; caseIndex < inputMethods.length; ++caseIndex ){
|
||||
// this builds a string to describe this particular iteration, and provide useful output, should it fail.
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(String.format("\n## For Case #%d: [%s]@%4.2f \n", caseIndex, inputMethods[caseIndex].name(), inputOffsets[caseIndex]));
|
||||
buf.append(String.format(" >> setting initial point to: ( %6.4f, %6.4f) \n", xDelta[caseIndex], 0.0f));
|
||||
final String dump = buf.toString();
|
||||
|
||||
fins.setAxialOffset( inputMethods[caseIndex], inputOffsets[caseIndex]);
|
||||
{ // case 1:
|
||||
fins.setAxialOffset( AxialMethod.TOP, 0.1);
|
||||
fins.setPoints(initialPoints);
|
||||
|
||||
// vvvv function under test vvvv
|
||||
fins.setPoint( 0, xDelta[caseIndex], 0.1f);
|
||||
fins.setPoint( 0, 0.2, 0.1f);
|
||||
// ^^^^ function under test ^^^^
|
||||
|
||||
//System.err.println(String.format("@[%d]:", caseIndex));
|
||||
//System.err.println(fins.toDebugDetail());
|
||||
|
||||
assertEquals("Fin front not updated as expected..."+dump, expectedFinStartx[caseIndex], fins.getAxialFront(), EPSILON);
|
||||
assertEquals("Fin front not updated as expected..."+dump, expectedFinStarty[caseIndex], fins.getFinFront().y, EPSILON);
|
||||
assertEquals(0.3, fins.getFinFront().x, EPSILON);
|
||||
assertEquals(0.85, fins.getFinFront().y, EPSILON);
|
||||
|
||||
final Coordinate[] postPoints = fins.getFinPoints();
|
||||
assertEquals("Middle fin point has moved!: "+dump, expectedMidpointOffset[caseIndex], postPoints[1].x, EPSILON);
|
||||
assertEquals("Final fin point has moved!: "+dump, expectedFinalPointOffset[caseIndex], postPoints[2].x, EPSILON);
|
||||
assertEquals(postPoints.length, 3);
|
||||
|
||||
assertEquals("Fin offset not updated as expected..."+dump, expectedFinOffset[caseIndex], fins.getAxialOffset(), EPSILON);
|
||||
assertEquals("Fin length not updated as expected..."+dump, expectedFinLength[caseIndex], fins.getLength(), EPSILON);
|
||||
// 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);
|
||||
}{ // case 2:
|
||||
fins.setAxialOffset( AxialMethod.TOP, 0.1);
|
||||
fins.setPoints(initialPoints);
|
||||
|
||||
// vvvv function under test vvvv
|
||||
fins.setPoint( 0, -0.2, 0.1f);
|
||||
// ^^^^ function under test ^^^^
|
||||
|
||||
assertEquals(0.0, fins.getFinFront().x, EPSILON);
|
||||
assertEquals(1.0, fins.getFinFront().y, EPSILON);
|
||||
|
||||
final Coordinate[] postPoints = fins.getFinPoints();
|
||||
assertEquals(postPoints.length, 4);
|
||||
|
||||
// pseudo-front point
|
||||
assertEquals(-0.1, postPoints[1].x, EPSILON);
|
||||
assertEquals(0.05, postPoints[1].y, EPSILON);
|
||||
|
||||
assertEquals(0.5, postPoints[2].x, EPSILON);
|
||||
assertEquals(0.15, 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);
|
||||
|
||||
final Coordinate[] postPoints = fins.getFinPoints();
|
||||
assertEquals(postPoints.length, 3);
|
||||
|
||||
// mid-point
|
||||
assertEquals(0.3, postPoints[1].x, EPSILON);
|
||||
assertEquals(0.25, postPoints[1].y, EPSILON);
|
||||
|
||||
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);
|
||||
fins.setPoints(initialPoints);
|
||||
|
||||
// vvvv function under test vvvv
|
||||
fins.setPoint( 0, -0.1, 0.1f);
|
||||
// ^^^^ function under test ^^^^
|
||||
|
||||
assertEquals(0.2, fins.getFinFront().x, EPSILON);
|
||||
assertEquals(0.9, fins.getFinFront().y, EPSILON);
|
||||
|
||||
final Coordinate[] postPoints = fins.getFinPoints();
|
||||
assertEquals(postPoints.length, 3);
|
||||
|
||||
// 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.15, postPoints[2].y, EPSILON);
|
||||
|
||||
assertEquals(-0.05f, fins.getAxialOffset(), EPSILON);
|
||||
assertEquals(0.5f, fins.getLength(), EPSILON);
|
||||
}{ // case 5:
|
||||
fins.setAxialOffset( AxialMethod.BOTTOM, 0.0);
|
||||
fins.setPoints(initialPoints);
|
||||
|
||||
// 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);
|
||||
|
||||
final Coordinate[] postPoints = fins.getFinPoints();
|
||||
assertEquals(postPoints.length, 3);
|
||||
|
||||
// mid-point
|
||||
assertEquals(0.3, postPoints[1].x, EPSILON);
|
||||
//assertEquals(0.05, postPoints[1].y, EPSILON);
|
||||
|
||||
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());
|
||||
|
||||
// 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);
|
||||
|
||||
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
|
||||
@ -516,140 +591,297 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
Transition finMount = (Transition) rkt.getChild(0).getChild(2);
|
||||
FreeformFinSet fins = (FreeformFinSet) rkt.getChild(0).getChild(2).getChild(0);
|
||||
final Coordinate[] initialPoints = fins.getFinPoints();
|
||||
final int lastIndex = initialPoints.length - 1;
|
||||
final double xf = initialPoints[lastIndex].x;
|
||||
|
||||
// assert pre-conditions:
|
||||
assertEquals(0.4, fins.getLength(), EPSILON);
|
||||
assertEquals(0.4, fins.getAxialFront(), EPSILON);
|
||||
assertEquals(initialPoints[0], Coordinate.ZERO);
|
||||
assertEquals(initialPoints[1], new Coordinate(0.4, 0.2));
|
||||
assertEquals(initialPoints[2], new Coordinate(0.4, -0.2));
|
||||
assertEquals(1.0, finMount.getLength(), EPSILON);
|
||||
assertEquals(0.8, finMount.getRadius(fins.getAxialFront()), EPSILON);
|
||||
|
||||
final int lastIndex = initialPoints.length - 1;
|
||||
|
||||
// set to these positions
|
||||
final AxialMethod[] inputMethods = {AxialMethod.TOP, AxialMethod.TOP, AxialMethod.MIDDLE, AxialMethod.MIDDLE, AxialMethod.BOTTOM, AxialMethod.BOTTOM};
|
||||
final double[] inputOffsets = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
|
||||
|
||||
// set first point to this location...
|
||||
final double[] xDelta= { 0.1, -0.1, 0.1, -0.1, 0.1, -0.1};
|
||||
|
||||
// and check against these expected values:
|
||||
final double[] expectedFinStartx = { 0.0, 0.0, 0.3, 0.3, 0.6, 0.6};
|
||||
final double[] expectedFinStarty = { 1.0, 1.0, 0.85, 0.85, 0.7, 0.7};
|
||||
final double[] expectedFinOffset = { 0.0, 0.0, 0.05, -0.05, 0.0, -0.1};
|
||||
final double[] expectedFinalPointOffset = { 0.5, 0.3, 0.5, 0.3, 0.4, 0.3};
|
||||
|
||||
for( int caseIndex=0; caseIndex < inputMethods.length; ++caseIndex ){
|
||||
final double xRequest = initialPoints[lastIndex].x + xDelta[caseIndex];
|
||||
final double yRequest = Double.NaN; // irrelevant; will be clamped to the body regardless
|
||||
|
||||
// this builds a string to describe this particular iteration, and provide useful output, should it fail.
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(String.format("\n## For Case #%d: [%s]@%4.2f \n", caseIndex, inputMethods[caseIndex].name(), inputOffsets[caseIndex]));
|
||||
buf.append(String.format(" >> setting last point to: ( %6.4f, %6.4f) \n", xRequest, yRequest));
|
||||
final String dump = buf.toString();
|
||||
|
||||
fins.setAxialOffset( inputMethods[caseIndex], inputOffsets[caseIndex]);
|
||||
{ // case 1:
|
||||
fins.setAxialOffset( AxialMethod.TOP, 0.1);
|
||||
fins.setPoints(initialPoints);
|
||||
|
||||
// vvvv function under test vvvv
|
||||
fins.setPoint( lastIndex, xRequest, yRequest);
|
||||
fins.setPoint( lastIndex, xf+0.2, -0.3f);
|
||||
// ^^^^ function under test ^^^^
|
||||
|
||||
// System.err.println(String.format("@[%d]:", caseIndex));
|
||||
// System.err.println(fins.toDebugDetail());
|
||||
final Coordinate[] postPoints = fins.getFinPoints();
|
||||
assertEquals(postPoints.length, 3);
|
||||
|
||||
assertEquals("Fin offset not updated as expected..."+dump, expectedFinOffset[caseIndex], fins.getAxialOffset(), EPSILON);
|
||||
assertEquals("Fin front not updated as expected..."+dump, expectedFinStartx[caseIndex], fins.getAxialFront(), EPSILON);
|
||||
assertEquals("Fin front not updated as expected..."+dump, expectedFinStarty[caseIndex], fins.getFinFront().y, EPSILON);
|
||||
// middle point:
|
||||
assertEquals(0.4, postPoints[1].x, EPSILON);
|
||||
assertEquals(0.2, postPoints[1].y, EPSILON);
|
||||
|
||||
// last point:
|
||||
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);
|
||||
// ^^^^ function under test ^^^^
|
||||
|
||||
final Coordinate[] postPoints = fins.getFinPoints();
|
||||
assertEquals("Middle fin point has moved!: "+dump, initialPoints[1].x, postPoints[1].x, EPSILON);
|
||||
assertEquals("Final fin point has moved!: "+dump, expectedFinalPointOffset[caseIndex], postPoints[2].x, EPSILON);
|
||||
assertEquals("Fin length not updated as expected..."+dump, expectedFinalPointOffset[caseIndex], fins.getLength(), EPSILON);
|
||||
assertEquals(postPoints.length, 3);
|
||||
|
||||
// middle point:
|
||||
assertEquals(0.4, postPoints[1].x, EPSILON);
|
||||
assertEquals(0.2, postPoints[1].y, EPSILON);
|
||||
|
||||
// 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);
|
||||
|
||||
// vvvv function under test vvvv
|
||||
fins.setPoint( lastIndex, xf + 0.1, 0.1f);
|
||||
// ^^^^ function under test ^^^^
|
||||
|
||||
final Coordinate[] postPoints = fins.getFinPoints();
|
||||
assertEquals(postPoints.length, 3);
|
||||
|
||||
// mid-point
|
||||
assertEquals(0.4, postPoints[1].x, EPSILON);
|
||||
assertEquals(0.2, postPoints[1].y, EPSILON);
|
||||
|
||||
// last point
|
||||
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);
|
||||
|
||||
// vvvv function under test vvvv
|
||||
fins.setPoint( lastIndex, xf - 0.1, 0.1f);
|
||||
// ^^^^ function under test ^^^^
|
||||
|
||||
final Coordinate[] postPoints = fins.getFinPoints();
|
||||
assertEquals(postPoints.length, 3);
|
||||
|
||||
// mid point
|
||||
assertEquals(0.4, postPoints[1].x, EPSILON);
|
||||
assertEquals(0.2, postPoints[1].y, EPSILON);
|
||||
|
||||
// last point
|
||||
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);
|
||||
// ^^^^ function under test ^^^^
|
||||
|
||||
final Coordinate[] postPoints = fins.getFinPoints();
|
||||
assertEquals(postPoints.length, 4);
|
||||
|
||||
// mid-point
|
||||
assertEquals(0.4, postPoints[1].x, EPSILON);
|
||||
assertEquals(0.2, postPoints[1].y, EPSILON);
|
||||
|
||||
// pseudo last point
|
||||
assertEquals(0.5, postPoints[2].x, EPSILON);
|
||||
assertEquals(0.1, 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);
|
||||
// ^^^^ function under test ^^^^
|
||||
|
||||
final Coordinate[] postPoints = fins.getFinPoints();
|
||||
assertEquals(postPoints.length, 3);
|
||||
|
||||
// mid-point
|
||||
assertEquals(0.4, postPoints[1].x, EPSILON);
|
||||
assertEquals(0.2, postPoints[1].y, EPSILON);
|
||||
|
||||
// last point
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetInteriorPoint() {
|
||||
final Rocket rkt = createTemplateRocket();
|
||||
FreeformFinSet fins = (FreeformFinSet) rkt.getChild(0).getChild(2).getChild(0);
|
||||
|
||||
{ // preconditions // initial points
|
||||
final Coordinate[] initialPoints = fins.getFinPoints();
|
||||
assertEquals(initialPoints[0], Coordinate.ZERO);
|
||||
assertEquals(initialPoints[1], new Coordinate(0.4, 0.2));
|
||||
assertEquals(initialPoints[2], new Coordinate(0.4, -0.2));
|
||||
assertEquals(0.4, fins.getLength(), EPSILON);
|
||||
}{ // preconditions // mount
|
||||
Transition finMount = (Transition) rkt.getChild(0).getChild(2);
|
||||
assertEquals(0.4, fins.getFinFront().x, EPSILON);
|
||||
assertEquals(0.8, fins.getFinFront().y, EPSILON);
|
||||
assertEquals(0.8, finMount.getRadius(fins.getAxialFront()), EPSILON);
|
||||
|
||||
assertEquals(AxialMethod.TOP, fins.getAxialMethod());
|
||||
assertEquals(0.4, fins.getAxialOffset(), EPSILON);
|
||||
|
||||
}{ // test target
|
||||
final Coordinate p1 = fins.getFinPoints()[1];
|
||||
|
||||
// vvvv function under test vvvv
|
||||
fins.setPoint( 1, p1.x + 0.1, p1.y + 0.1f);
|
||||
// ^^^^ function under test ^^^^
|
||||
|
||||
}{ // postconditions
|
||||
final Coordinate[] postPoints = fins.getFinPoints();
|
||||
assertEquals(postPoints.length, 3);
|
||||
|
||||
// middle point:
|
||||
assertEquals(0.5, postPoints[1].x, EPSILON);
|
||||
assertEquals(0.3, postPoints[1].y, EPSILON);
|
||||
|
||||
// last point:
|
||||
assertEquals(0.4, postPoints[2].x, EPSILON);
|
||||
assertEquals(-0.2, postPoints[2].y, EPSILON);
|
||||
|
||||
assertEquals(0.4, fins.getLength(), EPSILON);
|
||||
assertEquals(0.4, fins.getFinFront().x, EPSILON);
|
||||
assertEquals(0.8, fins.getFinFront().y, EPSILON);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetAllPoints() {
|
||||
final Rocket rkt = createTemplateRocket();
|
||||
final AxialStage stage = (AxialStage) rkt.getChild(0);
|
||||
|
||||
{ // setup // mount
|
||||
BodyTube body = new BodyTube(0.0, 1.0, 0.002);
|
||||
body.setName("Phantom Body Tube");
|
||||
body.setOuterRadiusAutomatic(true);
|
||||
stage.addChild(body, 2);
|
||||
assertEquals(1.0, body.getOuterRadius(), EPSILON);
|
||||
assertEquals(0.0, body.getLength(), EPSILON);
|
||||
|
||||
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);
|
||||
|
||||
body.addChild(fins);
|
||||
|
||||
}{ // postconditions
|
||||
FreeformFinSet fins = (FreeformFinSet) rkt.getChild(0).getChild(2).getChild(0);
|
||||
|
||||
final Coordinate[] postPoints = fins.getFinPoints();
|
||||
assertEquals(6, postPoints.length);
|
||||
|
||||
// p1
|
||||
assertEquals(-0.0508, postPoints[1].x, EPSILON);
|
||||
assertEquals(0.007721, postPoints[1].y, EPSILON);
|
||||
|
||||
// p2
|
||||
assertEquals(0.0, postPoints[2].x, EPSILON);
|
||||
assertEquals(0.01544, postPoints[2].y, EPSILON);
|
||||
|
||||
// p3
|
||||
assertEquals(0.0254, postPoints[3].x, EPSILON);
|
||||
assertEquals(0.007721, postPoints[3].y, EPSILON);
|
||||
|
||||
// p4
|
||||
assertEquals(0.00011, postPoints[4].x, EPSILON);
|
||||
assertEquals(0.0, postPoints[4].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(1.0, fins.getFinFront().y, EPSILON);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetFirstPoint_testNonIntersection() {
|
||||
final Rocket rkt = createTemplateRocket();
|
||||
FreeformFinSet fins = (FreeformFinSet) rkt.getChild(0).getChild(2).getChild(0);
|
||||
final FreeformFinSet fins = (FreeformFinSet) rkt.getChild(0).getChild(2).getChild(0);
|
||||
final Transition mount = (Transition) rkt.getChild(0).getChild(2);
|
||||
|
||||
assertEquals( 1, fins.getFinCount());
|
||||
final int lastIndex = fins.getPointCount()-1;
|
||||
assertEquals( 2, lastIndex);
|
||||
final double initialOffset = fins.getAxialOffset();
|
||||
assertEquals( 0.4, initialOffset, EPSILON); // pre-condition
|
||||
assertEquals( 3, fins.getPointCount());
|
||||
assertEquals( AxialMethod.TOP, fins.getAxialMethod());
|
||||
assertEquals( 0.4, fins.getAxialOffset(), EPSILON); // pre-condition
|
||||
assertEquals( 1.0, mount.getLength(), EPSILON);
|
||||
|
||||
final double attemptedDelta = 0.6;
|
||||
fins.setPoint( 0, attemptedDelta, 0);
|
||||
// fin offset: 0.4 -> 0.59 (just short of prev fin end)
|
||||
// fin end: 0.4 ~> min root chord
|
||||
// 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 = 0.79;
|
||||
final double expFinOffset = 1.0;
|
||||
assertEquals("Resultant fin offset does not match!", expFinOffset, fins.getAxialOffset(), EPSILON);
|
||||
|
||||
// SHOULD NOT CHANGE (in this case):
|
||||
Coordinate actualLastPoint = fins.getFinPoints()[ lastIndex];
|
||||
assertEquals("last point did not adjust correctly: ", FreeformFinSet.MIN_ROOT_CHORD, actualLastPoint.x, EPSILON);
|
||||
assertEquals("last point did not adjust correctly: ", -0.005, actualLastPoint.y, EPSILON); // magic number
|
||||
assertEquals("New fin length is wrong: ", FreeformFinSet.MIN_ROOT_CHORD, fins.getLength(), EPSILON);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSetLastPoint_TubeBody() throws IllegalFinPointException {
|
||||
Rocket rkt = createTemplateRocket();
|
||||
|
||||
// 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:
|
||||
FreeformFinSet fins = (FreeformFinSet) rkt.getChild(0).getChild(1).getChild(0);
|
||||
|
||||
// verify preconditions
|
||||
assertEquals(AxialMethod.BOTTOM, fins.getAxialMethod());
|
||||
assertEquals(0.0, fins.getAxialOffset(), EPSILON);
|
||||
|
||||
// last point is restricted to the body
|
||||
final int lastIndex = fins.getPointCount()-1;
|
||||
final Coordinate expectedFinalPoint = new Coordinate( 1.0, 0.0, 0.0);
|
||||
|
||||
// vvvv function under test vvvv
|
||||
fins.setPoint( lastIndex, 10.0, Double.NaN);
|
||||
// ^^^^ function under test ^^^^
|
||||
|
||||
Coordinate actualFinalPoint = fins.getFinPoints()[lastIndex];
|
||||
assertEquals( expectedFinalPoint.x, actualFinalPoint.x, EPSILON);
|
||||
assertEquals( expectedFinalPoint.y, actualFinalPoint.y, EPSILON);
|
||||
}
|
||||
|
||||
{ // a transitions will trigger more complicated positioning math:
|
||||
FreeformFinSet fins = (FreeformFinSet) rkt.getChild(0).getChild(2).getChild(0);
|
||||
final int lastIndex = fins.getPointCount()-1;
|
||||
|
||||
Coordinate expectedLastPoint;
|
||||
Coordinate actualLastPoint;
|
||||
{ // this is where the point starts off at:
|
||||
actualLastPoint = fins.getFinPoints()[lastIndex];
|
||||
assertEquals( 0.4, actualLastPoint.x, EPSILON);
|
||||
assertEquals( -0.2, actualLastPoint.y, EPSILON);
|
||||
}
|
||||
|
||||
{ // (1): move point within bounds
|
||||
// move last point, and verify that its y-value is still clamped to the body ( at the new location)
|
||||
expectedLastPoint = new Coordinate( 0.6, -0.3, 0.0);
|
||||
fins.setPoint(lastIndex, 0.6, 0.0); // w/ incorrect y-val. The function should correct the y-value as above.
|
||||
|
||||
actualLastPoint = fins.getFinPoints()[lastIndex];
|
||||
assertEquals( expectedLastPoint.x, actualLastPoint.x, EPSILON);
|
||||
assertEquals( expectedLastPoint.y, actualLastPoint.y, 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("New fin length is wrong: ", 0.0, fins.getLength(), EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -785,7 +1017,7 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForNonIntersection() {
|
||||
public void testForIntersection_false() {
|
||||
final Rocket rkt = new Rocket();
|
||||
final AxialStage stg = new AxialStage();
|
||||
rkt.addChild(stg);
|
||||
@ -814,7 +1046,7 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForIntersection() {
|
||||
public void testForIntersection_true() {
|
||||
final Rocket rkt = new Rocket();
|
||||
final AxialStage stg = new AxialStage();
|
||||
rkt.addChild(stg);
|
||||
@ -849,6 +1081,53 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
assertThat( "Fin Set failed to detect an intersection! ", p1.y, not(equalTo(initPoints[1].y)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForIntersectionAtFirstLast() {
|
||||
final Rocket rkt = new Rocket();
|
||||
final AxialStage stg = new AxialStage();
|
||||
rkt.addChild(stg);
|
||||
BodyTube body = new BodyTube(2.0, 0.01);
|
||||
stg.addChild(body);
|
||||
//
|
||||
// An obviously intersecting fin:
|
||||
// [2] +---+ [1]
|
||||
// | /
|
||||
// | /
|
||||
// [0]|/ [3]
|
||||
// +---+-----+---+
|
||||
// = +x =>
|
||||
FreeformFinSet fins = new FreeformFinSet();
|
||||
fins.setFinCount(1);
|
||||
Coordinate[] initPoints = new Coordinate[] {
|
||||
new Coordinate(0, 0),
|
||||
new Coordinate(0, 1),
|
||||
new Coordinate(1, 1),
|
||||
new Coordinate(0, 0)
|
||||
};
|
||||
// this line throws an exception?
|
||||
fins.setPoints(initPoints);
|
||||
body.addChild(fins);
|
||||
|
||||
final Coordinate[] finPoints = fins.getFinPoints();
|
||||
|
||||
// p0
|
||||
assertEquals("incorrect body points! ", 0., finPoints[0].x, EPSILON);
|
||||
assertEquals("incorrect body points! ", 0., finPoints[0].y, EPSILON);
|
||||
|
||||
// p1
|
||||
assertEquals("incorrect body points! ", 0., finPoints[1].x, EPSILON);
|
||||
assertEquals("incorrect body points! ", 1., finPoints[1].y, EPSILON);
|
||||
|
||||
// p2
|
||||
assertEquals("incorrect body points! ", 1., finPoints[2].x, EPSILON);
|
||||
assertEquals("incorrect body points! ", 1., finPoints[2].y, EPSILON);
|
||||
|
||||
// pf
|
||||
assertEquals("incorrect body points! ", 0., finPoints[3].x, EPSILON);
|
||||
assertEquals("incorrect body points! ", 0., finPoints[3].y, EPSILON);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testWildmanVindicatorShape() throws Exception {
|
||||
@ -956,17 +1235,63 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
|
||||
final Coordinate finFront = fins.getFinFront();
|
||||
final Coordinate[] finPoints = fins.getFinPoints();
|
||||
// translate from fin-frame to body-frame
|
||||
final Coordinate[] finPointsFromBody = FinSet.translatePoints( fins.getFinPoints(), finFront.x, finFront.y );
|
||||
final Coordinate expectedStartPoint = finPointsFromBody[0];
|
||||
final Coordinate expectedEndPoint = finPointsFromBody[ finPoints.length-1];
|
||||
|
||||
{ // body points (relative to body)
|
||||
final Coordinate[] bodyPoints = fins.getBodyPoints();
|
||||
|
||||
{ // 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 body points! ", 0.8, finPoints[3].x, EPSILON);
|
||||
|
||||
// ?? SMOKING GUN:
|
||||
// ?? is this y-value of the fin not getting snapped to the body?
|
||||
|
||||
assertEquals(body.getRadius(0.8+finFront.x) - finFront.y, finPoints[3].y, EPSILON);
|
||||
|
||||
assertEquals("incorrect body points! ", 0.78466912, finPoints[3].y, EPSILON);
|
||||
|
||||
}{ // body points (relative to fin)
|
||||
final Coordinate[] rootPoints = fins.getRootPoints();
|
||||
assertEquals(101, rootPoints.length);
|
||||
final int lastIndex = 100;
|
||||
|
||||
// trivial, and uninteresting:
|
||||
assertEquals("incorrect body points! ", expectedStartPoint.x, bodyPoints[0].x, EPSILON);
|
||||
assertEquals("incorrect body points! ", expectedStartPoint.y, bodyPoints[0].y, EPSILON);
|
||||
assertEquals("incorrect body points! ", finPoints[0].x, rootPoints[0].x, EPSILON);
|
||||
assertEquals("incorrect body points! ", finPoints[0].y, rootPoints[0].y, EPSILON);
|
||||
|
||||
// n.b.: This should match EXACTLY the end point of the fin. (in fin coordinates)
|
||||
assertEquals("incorrect body points! ", finPoints[finPoints.length -1].x, rootPoints[lastIndex].x, EPSILON);
|
||||
assertEquals("incorrect body points! ", finPoints[finPoints.length -1].y, rootPoints[lastIndex].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? ", 101, rootPoints.length );
|
||||
|
||||
final int[] testIndices = { 2, 5, 61, 88};
|
||||
final double[] expectedX = { 0.016, 0.04, 0.488, 0.704};
|
||||
|
||||
for( int testCase = 0; testCase < testIndices.length; testCase++){
|
||||
final int testIndex = testIndices[testCase];
|
||||
assertEquals(String.format("Root points @ %d :: x coordinate mismatch!", testIndex),
|
||||
expectedX[testCase], rootPoints[testIndex].x, EPSILON);
|
||||
assertEquals(String.format("Root points @ %d :: y coordinate mismatch!", testIndex),
|
||||
body.getRadius(rootPoints[testIndex].x + finFront.x) - finFront.y, rootPoints[testIndex].y, EPSILON);
|
||||
}
|
||||
}
|
||||
}{ // body points (relative to body)
|
||||
// translate from fin-frame to body-frame
|
||||
final Coordinate[] finPointsFromBody = FinSet.translatePoints( fins.getFinPoints(), finFront.x, finFront.y );
|
||||
|
||||
final Coordinate[] bodyPoints = fins.getBodyPoints();
|
||||
assertEquals(101, bodyPoints.length);
|
||||
|
||||
final Coordinate expectedEndPoint = finPointsFromBody[ finPoints.length-1];
|
||||
|
||||
// trivial, and uninteresting:
|
||||
assertEquals("incorrect body points! ", finPointsFromBody[0].x, bodyPoints[0].x, EPSILON);
|
||||
assertEquals("incorrect body points! ", finPointsFromBody[0].y, bodyPoints[0].y, EPSILON);
|
||||
|
||||
// n.b.: This should match EXACTLY the end point of the fin. (in fin coordinates)
|
||||
assertEquals("incorrect body points! ", expectedEndPoint.x, bodyPoints[bodyPoints.length-1].x, EPSILON);
|
||||
@ -988,33 +1313,6 @@ public class FreeformFinSetTest extends BaseTestCase {
|
||||
}
|
||||
}
|
||||
}
|
||||
{ // body points (relative to fin)
|
||||
final Coordinate[] rootPoints = fins.getRootPoints();
|
||||
|
||||
// trivial, and uninteresting:
|
||||
assertEquals("incorrect body points! ", finPoints[0].x, rootPoints[0].x, EPSILON);
|
||||
assertEquals("incorrect body points! ", finPoints[0].y, rootPoints[0].y, EPSILON);
|
||||
|
||||
// n.b.: This should match EXACTLY the end point of the fin. (in fin coordinates)
|
||||
assertEquals("incorrect body points! ", finPoints[finPoints.length-1].x, rootPoints[rootPoints.length-1].x, EPSILON);
|
||||
assertEquals("incorrect body points! ", finPoints[finPoints.length-1].y, rootPoints[rootPoints.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? ", 101, rootPoints.length );
|
||||
|
||||
final int[] testIndices = { 2, 5, 61, 88};
|
||||
final double[] expectedX = { 0.016, 0.04, 0.488, 0.704};
|
||||
|
||||
for( int testCase = 0; testCase < testIndices.length; testCase++){
|
||||
final int testIndex = testIndices[testCase];
|
||||
assertEquals(String.format("Root points @ %d :: x coordinate mismatch!", testIndex),
|
||||
expectedX[testCase], rootPoints[testIndex].x, EPSILON);
|
||||
assertEquals(String.format("Root points @ %d :: y coordinate mismatch!", testIndex),
|
||||
body.getRadius(rootPoints[testIndex].x + finFront.x) - finFront.y, rootPoints[testIndex].y, EPSILON);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user