Merge pull request #506 from teyrana/fix_498_neg_inertia

Fixes #498 - Refactor of FreeformFinSet[Test]
This commit is contained in:
Wes Cravens 2019-01-26 07:13:31 -06:00 committed by GitHub
commit 090caed29e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 665 additions and 728 deletions

View File

@ -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() ) {

View File

@ -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);

View File

@ -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();

View File

@ -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();

View File

@ -424,12 +424,7 @@ public class FreeformFinSetConfig extends FinSetConfig {
Point2D.Double point = getCoordinates(event);
finset.setPoint(dragIndex, point.x, point.y);
final double bodyFront = -finset.getAxialFront();
if(0 == dragIndex && bodyFront > point.x){
dragIndex = 1;
}
updateFields();
}
@ -447,6 +442,7 @@ public class FreeformFinSetConfig extends FinSetConfig {
if ( 0 < clickIndex) {
// if ctrl+click, delete point
try {
Point2D.Double point = getCoordinates(event);
finset.removePoint(clickIndex);
} catch (IllegalFinPointException ignore) {
log.error("Ignoring IllegalFinPointException while dragging, dragIndex=" + dragIndex + ". This is likely an internal error.");