From 71045c6675ba6ca10b273533f87ae51e8567bc84 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Fri, 26 Aug 2022 22:36:34 +0200 Subject: [PATCH 1/8] 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); From f907ff186be8d2ad85aa25bd2f53d36518d303d2 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Fri, 26 Aug 2022 23:07:36 +0200 Subject: [PATCH 2/8] [#1618] Fix fin tab root points --- .../sf/openrocket/rocketcomponent/FinSet.java | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/core/src/net/sf/openrocket/rocketcomponent/FinSet.java b/core/src/net/sf/openrocket/rocketcomponent/FinSet.java index 45b5f35dd..686449c2f 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/FinSet.java +++ b/core/src/net/sf/openrocket/rocketcomponent/FinSet.java @@ -996,16 +996,21 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona return new Coordinate[]{}; } - Coordinate[] rootPoints = getRootPoints(); - - final int pointCount = 5 + rootPoints.length; + final double xTabFront = getTabFrontEdge(); + final double xTabTrail = getTabTrailingEdge(); + + List rootPoints = new ArrayList<>(); + for (Coordinate point : getRootPoints()) { + if (point.x > xTabFront && point.x < xTabTrail) { + rootPoints.add(point); + } + } + + final int pointCount = 5 + rootPoints.size(); Coordinate[] points = new Coordinate[pointCount]; final Coordinate finFront = this.getFinFront(); final SymmetricComponent body = (SymmetricComponent)this.getParent(); - - final double xTabFront = getTabFrontEdge(); - final double xTabTrail = getTabTrailingEdge(); // // limit the new heights to be no greater than the current body radius. double yTabFront = Double.NaN; @@ -1021,8 +1026,8 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona points[1] = new Coordinate(xTabFront, yTabBottom ); points[2] = new Coordinate(xTabTrail, yTabBottom ); points[3] = new Coordinate(xTabTrail, yTabTrail); - for (int i = 0; i < rootPoints.length; i++) { - points[i + 4] = rootPoints[rootPoints.length - 1 -i]; + for (int i = 0; i < rootPoints.size(); i++) { + points[i + 4] = rootPoints.get(rootPoints.size() - 1 - i); } points[pointCount - 1] = new Coordinate(xTabFront, yTabFront); From 5f3cb5a494766b7f07dab473ab36a73f436bee58 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Sat, 27 Aug 2022 01:34:44 +0200 Subject: [PATCH 3/8] Fix fin set template print for curved parent --- .../sf/openrocket/rocketcomponent/FinSet.java | 25 +++++----- .../openrocket/gui/print/PrintableFinSet.java | 47 ++++++++++++++----- 2 files changed, 49 insertions(+), 23 deletions(-) diff --git a/core/src/net/sf/openrocket/rocketcomponent/FinSet.java b/core/src/net/sf/openrocket/rocketcomponent/FinSet.java index 686449c2f..b7a5ffa05 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/FinSet.java +++ b/core/src/net/sf/openrocket/rocketcomponent/FinSet.java @@ -977,6 +977,13 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona return getMountPoints( finLead.x, xFinEnd, -finLead.x, -finLead.y); } + /** + * Return a list of coordinates defining the geometry of a single fin, including the parent's body points . + */ + public Coordinate[] getFinPointsWithRoot() { + return combineCurves(getFinPoints(), getRootPoints()); + } + /** * 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 @@ -1006,8 +1013,7 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona } } - final int pointCount = 5 + rootPoints.size(); - Coordinate[] points = new Coordinate[pointCount]; + Coordinate[] tabPoints = new Coordinate[4]; final Coordinate finFront = this.getFinFront(); final SymmetricComponent body = (SymmetricComponent)this.getParent(); @@ -1022,16 +1028,13 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona yTabBottom = MathUtil.min(yTabFront, yTabTrail) - tabHeight; } - points[0] = new Coordinate(xTabFront, yTabFront); - points[1] = new Coordinate(xTabFront, yTabBottom ); - points[2] = new Coordinate(xTabTrail, yTabBottom ); - points[3] = new Coordinate(xTabTrail, yTabTrail); - for (int i = 0; i < rootPoints.size(); i++) { - points[i + 4] = rootPoints.get(rootPoints.size() - 1 - i); - } - points[pointCount - 1] = new Coordinate(xTabFront, yTabFront); + tabPoints[0] = new Coordinate(xTabFront, yTabFront); + tabPoints[1] = new Coordinate(xTabFront, yTabBottom ); + tabPoints[2] = new Coordinate(xTabTrail, yTabBottom ); + tabPoints[3] = new Coordinate(xTabTrail, yTabTrail); + rootPoints.add(0, new Coordinate(xTabFront, yTabFront)); - return points; + return combineCurves(tabPoints, rootPoints.toArray(new Coordinate[0])); } /* diff --git a/swing/src/net/sf/openrocket/gui/print/PrintableFinSet.java b/swing/src/net/sf/openrocket/gui/print/PrintableFinSet.java index 59719b504..af385c3ff 100644 --- a/swing/src/net/sf/openrocket/gui/print/PrintableFinSet.java +++ b/swing/src/net/sf/openrocket/gui/print/PrintableFinSet.java @@ -19,7 +19,11 @@ public class PrintableFinSet extends AbstractPrintable { /** * The object that represents the shape (outline) of the fin. This gets drawn onto the Swing component. */ - protected GeneralPath polygon; + protected GeneralPath finPolygon; + /** + * The object that represents the tab (outline) of the fin. This gets drawn onto the Swing component. + */ + protected GeneralPath finTabPolygon; /** * The minimum X coordinate. @@ -46,15 +50,17 @@ public class PrintableFinSet extends AbstractPrintable { */ protected void init (FinSet component) { - Coordinate[] points = component.getFinPointsWithTab(); + Coordinate[] points = component.getFinPointsWithRoot(); + Coordinate[] tabPoints = component.getTabPoints(); - polygon = new GeneralPath(GeneralPath.WIND_NON_ZERO, points.length); - polygon.moveTo(0, 0); + finPolygon = new GeneralPath(GeneralPath.WIND_NON_ZERO, points.length); + finTabPolygon = new GeneralPath(GeneralPath.WIND_NON_ZERO, tabPoints.length); + finPolygon.moveTo(0, 0); - minX = 0; - minY = 0; - int maxX = 0; - int maxY = 0; + minX = Integer.MAX_VALUE; + minY = Integer.MAX_VALUE;; + int maxX = Integer.MIN_VALUE;; + int maxY = Integer.MIN_VALUE; for (Coordinate point : points) { final float x = (float) PrintUnit.METERS.toPoints(point.x); @@ -63,9 +69,24 @@ public class PrintableFinSet extends AbstractPrintable { minY = (int) Math.min(y, minY); maxX = (int) Math.max(x, maxX); maxY = (int) Math.max(y, maxY); - polygon.lineTo(x, y); + finPolygon.lineTo(x, y); } - polygon.closePath(); + finPolygon.closePath(); + + for (int i = 0; i < tabPoints.length; i++) { + final float x = (float) PrintUnit.METERS.toPoints(tabPoints[i].x); + final float y = (float) PrintUnit.METERS.toPoints(tabPoints[i].y); + minX = (int) Math.min(x, minX); + minY = (int) Math.min(y, minY); + maxX = (int) Math.max(x, maxX); + maxY = (int) Math.max(y, maxY); + if (i == 0) { + finTabPolygon.moveTo(x, y); + } else { + finTabPolygon.lineTo(x, y); + } + } + finTabPolygon.closePath(); setSize(maxX - minX + 1, maxY - minY + 1); } @@ -94,9 +115,11 @@ public class PrintableFinSet extends AbstractPrintable { // Reset the origin. g2d.translate(x, y); g2d.setPaint(TemplateProperties.getFillColor()); - g2d.fill(polygon); + g2d.fill(finPolygon); + g2d.fill(finTabPolygon); g2d.setPaint(TemplateProperties.getLineColor()); - g2d.draw(polygon); + g2d.draw(finPolygon); + g2d.draw(finTabPolygon); } /** From fe67e8224770a45a82ad45b18e029c63ef935f93 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Sat, 27 Aug 2022 02:01:44 +0200 Subject: [PATCH 4/8] [#1597] Fix 3D issues for fins with tabs --- .../gui/figure3d/geometry/FinRenderer.java | 65 ++++++++++++++++--- 1 file changed, 56 insertions(+), 9 deletions(-) diff --git a/swing/src/net/sf/openrocket/gui/figure3d/geometry/FinRenderer.java b/swing/src/net/sf/openrocket/gui/figure3d/geometry/FinRenderer.java index 311102ceb..f4d828093 100644 --- a/swing/src/net/sf/openrocket/gui/figure3d/geometry/FinRenderer.java +++ b/swing/src/net/sf/openrocket/gui/figure3d/geometry/FinRenderer.java @@ -34,7 +34,8 @@ public class FinRenderer { gl.glTranslated(-bounds.min.x, -bounds.min.y - finSet.getBodyRadius(), 0); gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); - Coordinate finPoints[] = finSet.getFinPointsWithTab(); + Coordinate finPoints[] = finSet.getFinPointsWithRoot(); + Coordinate tabPoints[] = finSet.getTabPoints(); { gl.glPushMatrix(); @@ -69,7 +70,7 @@ public class FinRenderer { GLU.gluTessCallback(tobj, GLU.GLU_TESS_END, cb); // fin side: +z - if (which == Surface.INSIDE) { // Right side + if (finSet.getSpan() > 0 && finSet.getLength() > 0 && which == Surface.INSIDE) { // Right side GLU.gluTessBeginPolygon(tobj, null); GLU.gluTessBeginContour(tobj); gl.glNormal3f(0, 0, 1); @@ -78,19 +79,45 @@ public class FinRenderer { double[] p = new double[]{c.x, c.y + finSet.getBodyRadius(), c.z + finSet.getThickness() / 2.0}; GLU.gluTessVertex(tobj, p, 0, p); - + } + GLU.gluTessEndContour(tobj); + GLU.gluTessEndPolygon(tobj); + } + // tab side: +z + if (finSet.getTabHeight() > 0 && finSet.getTabLength() > 0 && which == Surface.INSIDE) { // Right side + GLU.gluTessBeginPolygon(tobj, null); + GLU.gluTessBeginContour(tobj); + gl.glNormal3f(0, 0, 1); + for (int i = tabPoints.length - 1; i >= 0; i--) { + Coordinate c = tabPoints[i]; + double[] p = new double[]{c.x, c.y + finSet.getBodyRadius(), + c.z + finSet.getThickness() / 2.0}; + GLU.gluTessVertex(tobj, p, 0, p); } GLU.gluTessEndContour(tobj); GLU.gluTessEndPolygon(tobj); } - // fin side: -z - if (which == Surface.OUTSIDE) { // Left side + // fin side: -z + if (finSet.getSpan() > 0 && finSet.getLength() > 0 && which == Surface.OUTSIDE) { // Left side GLU.gluTessBeginPolygon(tobj, null); GLU.gluTessBeginContour(tobj); gl.glNormal3f(0, 0, -1); - for (int i = 0; i < finPoints.length; i++) { - Coordinate c = finPoints[i]; + for (Coordinate c : finPoints) { + double[] p = new double[]{c.x, c.y + finSet.getBodyRadius(), + c.z - finSet.getThickness() / 2.0}; + GLU.gluTessVertex(tobj, p, 0, p); + + } + GLU.gluTessEndContour(tobj); + GLU.gluTessEndPolygon(tobj); + } + // tab side: -z + if (finSet.getTabHeight() > 0 && finSet.getTabLength() > 0 && which == Surface.OUTSIDE) { // Left side + GLU.gluTessBeginPolygon(tobj, null); + GLU.gluTessBeginContour(tobj); + gl.glNormal3f(0, 0, -1); + for (Coordinate c : tabPoints) { double[] p = new double[]{c.x, c.y + finSet.getBodyRadius(), c.z - finSet.getThickness() / 2.0}; GLU.gluTessVertex(tobj, p, 0, p); @@ -100,8 +127,8 @@ public class FinRenderer { GLU.gluTessEndPolygon(tobj); } - // Strip around the edge - if (which == Surface.EDGES) { + // Fin strip around the edge + if (finSet.getSpan() > 0 && finSet.getLength() > 0 && which == Surface.EDGES) { if (!(finSet instanceof EllipticalFinSet)) gl.glShadeModel(GLLightingFunc.GL_FLAT); gl.glBegin(GL.GL_TRIANGLE_STRIP); @@ -120,6 +147,26 @@ public class FinRenderer { } gl.glEnd(); } + // Tab strip around the edge + if (finSet.getTabHeight() > 0 && finSet.getTabLength() > 0 && which == Surface.EDGES) { + if (!(finSet instanceof EllipticalFinSet)) + gl.glShadeModel(GLLightingFunc.GL_FLAT); + gl.glBegin(GL.GL_TRIANGLE_STRIP); + for (int i = 0; i <= tabPoints.length; i++) { + Coordinate c = tabPoints[i % tabPoints.length]; + // if ( i > 1 ){ + Coordinate c2 = tabPoints[(i - 1 + tabPoints.length) + % tabPoints.length]; + gl.glNormal3d(c2.y - c.y, c.x - c2.x, 0); + // } + gl.glTexCoord2d(c.x, c.y + finSet.getBodyRadius()); + gl.glVertex3d(c.x, c.y + finSet.getBodyRadius(), + c.z - finSet.getThickness() / 2.0); + gl.glVertex3d(c.x, c.y + finSet.getBodyRadius(), + c.z + finSet.getThickness() / 2.0); + } + gl.glEnd(); + } if (!(finSet instanceof EllipticalFinSet)) gl.glShadeModel(GLLightingFunc.GL_SMOOTH); From 4446d079027bdbdc7acd40557df708c7a4fb51dd Mon Sep 17 00:00:00 2001 From: SiboVG Date: Sat, 27 Aug 2022 02:03:48 +0200 Subject: [PATCH 5/8] Remove unneeded method --- core/src/net/sf/openrocket/rocketcomponent/FinSet.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/core/src/net/sf/openrocket/rocketcomponent/FinSet.java b/core/src/net/sf/openrocket/rocketcomponent/FinSet.java index b7a5ffa05..98bed2cb5 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/FinSet.java +++ b/core/src/net/sf/openrocket/rocketcomponent/FinSet.java @@ -1037,15 +1037,6 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona return combineCurves(tabPoints, rootPoints.toArray(new Coordinate[0])); } - /* - * 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 * From 589d84b2afaf4f4ce3f4a4fc48c022aabf019741 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Sat, 27 Aug 2022 02:07:39 +0200 Subject: [PATCH 6/8] Change moveTo for normal fin shape --- .../sf/openrocket/gui/print/PrintableFinSet.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/swing/src/net/sf/openrocket/gui/print/PrintableFinSet.java b/swing/src/net/sf/openrocket/gui/print/PrintableFinSet.java index af385c3ff..7f26cac3c 100644 --- a/swing/src/net/sf/openrocket/gui/print/PrintableFinSet.java +++ b/swing/src/net/sf/openrocket/gui/print/PrintableFinSet.java @@ -55,21 +55,24 @@ public class PrintableFinSet extends AbstractPrintable { finPolygon = new GeneralPath(GeneralPath.WIND_NON_ZERO, points.length); finTabPolygon = new GeneralPath(GeneralPath.WIND_NON_ZERO, tabPoints.length); - finPolygon.moveTo(0, 0); minX = Integer.MAX_VALUE; minY = Integer.MAX_VALUE;; int maxX = Integer.MIN_VALUE;; int maxY = Integer.MIN_VALUE; - for (Coordinate point : points) { - final float x = (float) PrintUnit.METERS.toPoints(point.x); - final float y = (float) PrintUnit.METERS.toPoints(point.y); + for (int i = 0; i < points.length; i++) { + final float x = (float) PrintUnit.METERS.toPoints(points[i].x); + final float y = (float) PrintUnit.METERS.toPoints(points[i].y); minX = (int) Math.min(x, minX); minY = (int) Math.min(y, minY); maxX = (int) Math.max(x, maxX); maxY = (int) Math.max(y, maxY); - finPolygon.lineTo(x, y); + if (i == 0) { + finPolygon.moveTo(x, y); + } else { + finPolygon.lineTo(x, y); + } } finPolygon.closePath(); From 406b18be645f93213c749f98e70b66ed945f54ca Mon Sep 17 00:00:00 2001 From: SiboVG Date: Sat, 27 Aug 2022 02:10:25 +0200 Subject: [PATCH 7/8] Fix fin polygon path if no tab --- swing/src/net/sf/openrocket/gui/print/PrintableFinSet.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/swing/src/net/sf/openrocket/gui/print/PrintableFinSet.java b/swing/src/net/sf/openrocket/gui/print/PrintableFinSet.java index 7f26cac3c..6b8f5967d 100644 --- a/swing/src/net/sf/openrocket/gui/print/PrintableFinSet.java +++ b/swing/src/net/sf/openrocket/gui/print/PrintableFinSet.java @@ -89,7 +89,9 @@ public class PrintableFinSet extends AbstractPrintable { finTabPolygon.lineTo(x, y); } } - finTabPolygon.closePath(); + if (tabPoints.length > 0) { + finTabPolygon.closePath(); + } setSize(maxX - minX + 1, maxY - minY + 1); } From 9aa83c1698fefdf9fbdd3d6f9f9caea3dcd64c33 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Sat, 27 Aug 2022 12:42:55 +0200 Subject: [PATCH 8/8] Use MathUtil.EPSILON for FinSet point correction --- core/src/net/sf/openrocket/rocketcomponent/FinSet.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/net/sf/openrocket/rocketcomponent/FinSet.java b/core/src/net/sf/openrocket/rocketcomponent/FinSet.java index 98bed2cb5..107383c16 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/FinSet.java +++ b/core/src/net/sf/openrocket/rocketcomponent/FinSet.java @@ -1096,12 +1096,12 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona // 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) { + if (Math.abs(points[lastIndex].x - body.getLength()) < MathUtil.EPSILON) { points[lastIndex] = points[lastIndex].setX(body.getLength()).setY(body.getAftRadius()); } // translate the points if needed - if ((Math.abs(xOffset) + Math.abs(yOffset)) > 0.0000001) { + if ((Math.abs(xOffset) + Math.abs(yOffset)) > MathUtil.EPSILON) { points = translatePoints(points, xOffset, yOffset); }