From 71045c6675ba6ca10b273533f87ae51e8567bc84 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Fri, 26 Aug 2022 22:36:34 +0200 Subject: [PATCH] Refactor --- .../sf/openrocket/rocketcomponent/FinSet.java | 221 +++++++++--------- 1 file changed, 110 insertions(+), 111 deletions(-) diff --git a/core/src/net/sf/openrocket/rocketcomponent/FinSet.java b/core/src/net/sf/openrocket/rocketcomponent/FinSet.java index 2cc1598ef..45b5f35dd 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/FinSet.java +++ b/core/src/net/sf/openrocket/rocketcomponent/FinSet.java @@ -880,6 +880,17 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona public double getBodyRadius() { return getFinFront().y; } + + public Coordinate getFinFront() { + final double xFinFront = this.getAxialFront(); + final SymmetricComponent symmetricParent = (SymmetricComponent)this.getParent(); + if( null == symmetricParent){ + return new Coordinate( 0, 0); + }else{ + final double yFinFront = symmetricParent.getRadius( xFinFront ); + return new Coordinate(xFinFront, yFinFront); + } + } @Override public boolean allowsChildren() { @@ -895,16 +906,6 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona public boolean isCompatible(Class type) { return false; } - - /** - * Return a list of coordinates defining the geometry of a single fin. - * The coordinates are the XY-coordinates of points defining the shape of a single fin, - * where the origin is the leading root edge. Therefore, the first point must be (0,0,0). - * All Z-coordinates must be zero. - * - * @return List of XY-coordinates. - */ - public abstract Coordinate[] getFinPoints(); public boolean isTabTrivial(){ return ( FinSet.minimumTabArea > (getTabLength()*getTabHeight())); @@ -950,6 +951,32 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona return returnPoints; } + /** + * Return a list of coordinates defining the geometry of a single fin. + * The coordinates are the XY-coordinates of points defining the shape of a single fin, + * where the origin is the leading root edge. Therefore, the first point must be (0,0,0). + * All Z-coordinates must be zero. + * + * @return List of XY-coordinates. + */ + public abstract Coordinate[] getFinPoints(); + + /** + * used to get body points for the profile design view + * + * @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){ + return new Coordinate[]{Coordinate.ZERO}; + } + + final Coordinate finLead = getFinFront(); + final double xFinEnd = finLead.x + getLength(); + + return getMountPoints( finLead.x, xFinEnd, -finLead.x, -finLead.y); + } + /** * 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 @@ -1002,26 +1029,85 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona return points; } - public Coordinate getFinFront() { - final double xFinFront = this.getAxialFront(); - final SymmetricComponent symmetricParent = (SymmetricComponent)this.getParent(); - if( null == symmetricParent){ - return new Coordinate( 0, 0); - }else{ - final double yFinFront = symmetricParent.getRadius( xFinFront ); - return new Coordinate(xFinFront, yFinFront); - } - } - - - /* - * yes, this may over-count points between the fin and fin tabs, + /* + * yes, this may over-count points between the fin and fin tabs, * but the minor performance hit is not worth the code complexity of dealing with. */ public Coordinate[] getFinPointsWithTab() { Coordinate[] temp = combineCurves(getFinPoints(), getRootPoints()); return combineCurves(temp, getTabPoints()); } + + /** + * 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 getMountPoints(0., parent.getLength(), 0,0); + } + + /** + * 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 (parent == null) { + return new Coordinate[]{Coordinate.ZERO}; + } + + // for a simple body, one increment is perfectly accurate. + int divisionCount = 1; + final SymmetricComponent body = (SymmetricComponent) getParent(); + final double intervalLength = xEnd - xStart; + + // for anything more complicated, increase the count: + if ((body instanceof Transition) && (((Transition)body).getType() != Shape.CONICAL)) { + // the maximum precision to enforce when calculating the areas of fins (especially on curved parent bodies) + final double xWidth = 0.0025; // width (in meters) of each individual iteration + divisionCount = (int) Math.ceil(intervalLength / xWidth); + + // When creating body curves, don't create more than this many divisions. -- only relevant on very large components + final int maximumBodyDivisionCount = 100; + divisionCount = Math.min(maximumBodyDivisionCount, divisionCount); + } + + // Recalculate the x step increment, now with the (rounded) division count. + double xIncrement = intervalLength / divisionCount; + + // Create the points: step through the radius of the parent + double xCur = xStart; + Coordinate[] points = new Coordinate[divisionCount+1]; + for (int index = 0; index < points.length; index++) { + double yCur = body.getRadius(xCur); + points[index] = new Coordinate(xCur, yCur); + + xCur += xIncrement; + } + + // correct last point, if beyond a rounding error from body's end. + final int lastIndex = points.length - 1; + if (Math.abs(points[lastIndex].x - body.getLength()) < 0.000001) { + points[lastIndex] = points[lastIndex].setX(body.getLength()).setY(body.getAftRadius()); + } + + // translate the points if needed + if ((Math.abs(xOffset) + Math.abs(yOffset)) > 0.0000001) { + points = translatePoints(points, xOffset, yOffset); + } + + return points; + } @Override public double getAngleOffset() { @@ -1197,93 +1283,6 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); } - /** - * 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 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: centerline ) i.e. relto: fin Component reference point - */ - public Coordinate[] getRootPoints(){ - if( null == parent){ - return new Coordinate[]{Coordinate.ZERO}; - } - - final Coordinate finLead = getFinFront(); - final double xFinEnd = finLead.x + getLength(); - - return getMountPoints( finLead.x, xFinEnd, -finLead.x, -finLead.y); - } - - /** - * 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 (parent == null) { - return new Coordinate[]{Coordinate.ZERO}; - } - - // for a simple body, one increment is perfectly accurate. - int divisionCount = 1; - final SymmetricComponent body = (SymmetricComponent) getParent(); - final double intervalLength = xEnd - xStart; - - // for anything more complicated, increase the count: - if ((body instanceof Transition) && (((Transition)body).getType() != Shape.CONICAL)) { - // the maximum precision to enforce when calculating the areas of fins (especially on curved parent bodies) - final double xWidth = 0.0025; // width (in meters) of each individual iteration - divisionCount = (int) Math.ceil(intervalLength / xWidth); - - // When creating body curves, don't create more than this many divisions. -- only relevant on very large components - final int maximumBodyDivisionCount = 100; - divisionCount = Math.min(maximumBodyDivisionCount, divisionCount); - } - - // Recalculate the x step increment, now with the (rounded) division count. - double xIncrement = intervalLength / divisionCount; - - // Create the points: step through the radius of the parent - double xCur = xStart; - Coordinate[] points = new Coordinate[divisionCount+1]; - for (int index = 0; index < points.length; index++) { - double yCur = body.getRadius(xCur); - points[index] = new Coordinate(xCur, yCur); - - xCur += xIncrement; - } - - // correct last point, if beyond a rounding error from body's end. - final int lastIndex = points.length - 1; - if (Math.abs(points[lastIndex].x - body.getLength()) < 0.000001) { - points[lastIndex] = points[lastIndex].setX(body.getLength()).setY(body.getAftRadius()); - } - - // translate the points if needed - if ((Math.abs(xOffset) + Math.abs(yOffset)) > 0.0000001) { - 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){ return getPointDescr(Arrays.asList(points), name, indent);