From c36ce2eae4f420f17a465a3c08a32ca7e4a6ee4e Mon Sep 17 00:00:00 2001 From: Daniel_M_Williams Date: Sat, 16 Sep 2017 11:49:51 -0400 Subject: [PATCH] [resolves #323] Major patch to improve rendering of instanced+rotated components - introduced interfaces for different types of positionable components: -- AnglePositionable -- AxialPositionable -- RadiusPositionable - RingInstanceable now includes these other interfaces, making explicit the expectations of any implementing subclass. - RingInstanceable now indicates its angles as an array instead of returning angles one-at-a-time -- commit includes updates to match this new API - Added getAssembly() method to RocketComponent, to simplify instancing code --- .../sf/openrocket/rocketcomponent/FinSet.java | 182 ++++++++++++------ .../rocketcomponent/ParallelStage.java | 24 ++- .../sf/openrocket/rocketcomponent/PodSet.java | 23 ++- .../rocketcomponent/RingInstanceable.java | 24 ++- .../rocketcomponent/RocketComponent.java | 23 +++ .../position/AnglePositionable.java | 11 ++ .../position/AxialPositionable.java | 14 ++ .../position/RadiusPositionable.java | 9 + .../gui/rocketfigure/FinSetShapes.java | 6 +- 9 files changed, 235 insertions(+), 81 deletions(-) create mode 100644 core/src/net/sf/openrocket/rocketcomponent/position/AnglePositionable.java create mode 100644 core/src/net/sf/openrocket/rocketcomponent/position/AxialPositionable.java create mode 100644 core/src/net/sf/openrocket/rocketcomponent/position/RadiusPositionable.java diff --git a/core/src/net/sf/openrocket/rocketcomponent/FinSet.java b/core/src/net/sf/openrocket/rocketcomponent/FinSet.java index 234a77284..ffd691746 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/FinSet.java +++ b/core/src/net/sf/openrocket/rocketcomponent/FinSet.java @@ -4,8 +4,12 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.material.Material; +import net.sf.openrocket.rocketcomponent.position.AxialPositionable; import net.sf.openrocket.startup.Application; import net.sf.openrocket.util.ArrayUtils; import net.sf.openrocket.util.Coordinate; @@ -13,8 +17,9 @@ import net.sf.openrocket.util.MathUtil; import net.sf.openrocket.util.Transformation; -public abstract class FinSet extends ExternalComponent { +public abstract class FinSet extends ExternalComponent implements RingInstanceable, AxialPositionable { private static final Translator trans = Application.getTranslator(); + private static final Logger log = LoggerFactory.getLogger(FinSet.class); /** @@ -77,18 +82,12 @@ public abstract class FinSet extends ExternalComponent { /** * Rotation about the x-axis by 2*PI/fins. */ - protected Transformation finRotation = Transformation.rotate_x(2 * Math.PI / fins); + protected Transformation finRotation = Transformation.IDENTITY; /** * Rotation angle of the first fin. Zero corresponds to the positive y-axis. */ - protected double rotation = 0; - - /** - * Rotation about the x-axis by angle this.rotation. - */ - protected Transformation baseRotation = Transformation.rotate_x(rotation); - + protected double baseRotationValue = 0; /** * Cant angle of fins. @@ -182,7 +181,7 @@ public abstract class FinSet extends ExternalComponent { * @return The base rotation amount. */ public double getBaseRotation() { - return rotation; + return getAngularOffset(); } /** @@ -190,20 +189,9 @@ public abstract class FinSet extends ExternalComponent { * @param r The base rotation amount. */ public void setBaseRotation(double r) { - r = MathUtil.reduce180(r); - if (MathUtil.equals(r, rotation)) - return; - rotation = r; - baseRotation = Transformation.rotate_x(rotation); - fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + setAngularOffset(r); } - public Transformation getBaseRotationTransformation() { - return baseRotation; - } - - - public double getCantAngle() { return cantAngle; } @@ -230,7 +218,7 @@ public abstract class FinSet extends ExternalComponent { } return cantRotation; } - + public double getThickness() { @@ -431,16 +419,10 @@ public abstract class FinSet extends ExternalComponent { double mass = getFinMass(); double filletMass = getFilletMass(); - double filletCenter = length / 2; - - double newCGx = (filletCenter * filletMass + finCGx * mass) / (filletMass + mass); - - // FilletRadius/5 is a good estimate for where the vertical centroid of the fillet - // is. Finding the actual position is very involved and won't make a huge difference. - double newCGy = (filletRadius / 5 * filletMass + finCGy * mass) / (filletMass + mass); if (fins == 1) { - return baseRotation.transform( + Transformation rotation = Transformation.rotate_x( getAngularOffset()); + return rotation.transform( new Coordinate(finCGx, finCGy + getBodyRadius(), 0, (filletMass + mass))); } else { return new Coordinate(finCGx, 0, 0, (filletMass + mass)); @@ -640,32 +622,32 @@ public abstract class FinSet extends ExternalComponent { return bounds; } - /** - * Adds the 2d-coordinate bound (x,y) to the collection for both z-components and for - * all fin rotations. - */ - private void addFinBound(Collection set, double x, double y) { - Coordinate c; - int i; - - c = new Coordinate(x, y, thickness / 2); - c = baseRotation.transform(c); - set.add(c); - for (i = 1; i < fins; i++) { - c = finRotation.transform(c); - set.add(c); - } - - c = new Coordinate(x, y, -thickness / 2); - c = baseRotation.transform(c); - set.add(c); - for (i = 1; i < fins; i++) { - c = finRotation.transform(c); - set.add(c); - } - } - - +// /** +// * Adds the 2d-coordinate bound (x,y) to the collection for both z-components and for +// * all fin rotations. +// */ +// private void addFinBound(Collection set, double x, double y) { +// Coordinate c; +// int i; +// +// c = new Coordinate(x, y, thickness / 2); +// c = baseRotation.transform(c); +// set.add(c); +// for (i = 1; i < fins; i++) { +// c = finRotation.transform(c); +// set.add(c); +// } +// +// c = new Coordinate(x, y, -thickness / 2); +// c = baseRotation.transform(c); +// set.add(c); +// for (i = 1; i < fins; i++) { +// c = finRotation.transform(c); +// set.add(c); +// } +// } +// +// @Override public void componentChanged(ComponentChangeEvent e) { @@ -763,6 +745,89 @@ public abstract class FinSet extends ExternalComponent { return points; } + @Override + public double getAngularOffset() { + ComponentAssembly stage = this.getAssembly(); + if( PodSet.class.isAssignableFrom( stage.getClass() )){ + PodSet assembly= (PodSet)stage; + return assembly.getAngularOffset() + baseRotationValue; + }else if( ParallelStage.class.isAssignableFrom( stage.getClass())){ + ParallelStage assembly = (ParallelStage)stage; + log.debug("detected p-stage with position: "+assembly.getAngularOffset()); + return assembly.getAngularOffset() + baseRotationValue; + } + + return baseRotationValue; + } + + + @Override + public void setAngularOffset(double angle) { + angle = MathUtil.reduce180(angle); + if (MathUtil.equals(angle, baseRotationValue)) + return; + baseRotationValue = angle; + fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + } + + @Override + public double getInstanceAngleIncrement(){ + return ( 2*Math.PI / getFinCount()); + } + + @Override + public double[] getInstanceAngles(){ + final double baseAngle = getAngularOffset(); + final double incrAngle = getInstanceAngleIncrement(); + + double[] result = new double[ getFinCount()]; + for( int i=0; ithis + */ + public final ComponentAssembly getAssembly() { + checkState(); + + RocketComponent curComponent = this; + while ( null != curComponent ) { + if( ComponentAssembly.class.isAssignableFrom( curComponent.getClass())) + return (ComponentAssembly) curComponent; + curComponent = curComponent.parent; + } + throw new IllegalStateException("getAssembly() called on hierarchy without a ComponentAssembly."); + } + + /** * Return the stage number of the stage this component belongs to. The stages * are numbered from zero upwards. diff --git a/core/src/net/sf/openrocket/rocketcomponent/position/AnglePositionable.java b/core/src/net/sf/openrocket/rocketcomponent/position/AnglePositionable.java new file mode 100644 index 000000000..032b70211 --- /dev/null +++ b/core/src/net/sf/openrocket/rocketcomponent/position/AnglePositionable.java @@ -0,0 +1,11 @@ +package net.sf.openrocket.rocketcomponent.position; + +public interface AnglePositionable { + + public double getAngularOffset(); + + public void setAngularOffset(final double angle); + +// public Position getAnglePositionMethod( ); +// public void setAnglePositionMethod( Position newMethod ); +} diff --git a/core/src/net/sf/openrocket/rocketcomponent/position/AxialPositionable.java b/core/src/net/sf/openrocket/rocketcomponent/position/AxialPositionable.java new file mode 100644 index 000000000..38b1e7652 --- /dev/null +++ b/core/src/net/sf/openrocket/rocketcomponent/position/AxialPositionable.java @@ -0,0 +1,14 @@ +package net.sf.openrocket.rocketcomponent.position; + +import net.sf.openrocket.rocketcomponent.RocketComponent.Position; + +public interface AxialPositionable { + + public double getAxialOffset(); + + public void setAxialOffset(final double newAxialOffset); + + public Position getAxialPositionMethod( ); + + public void setAxialPositionMethod( Position newMethod ); +} diff --git a/core/src/net/sf/openrocket/rocketcomponent/position/RadiusPositionable.java b/core/src/net/sf/openrocket/rocketcomponent/position/RadiusPositionable.java new file mode 100644 index 000000000..8b783c9c3 --- /dev/null +++ b/core/src/net/sf/openrocket/rocketcomponent/position/RadiusPositionable.java @@ -0,0 +1,9 @@ +package net.sf.openrocket.rocketcomponent.position; + +public interface RadiusPositionable { + + public double getRadialOffset(); + public boolean getAutoRadialOffset(); + public void setRadialOffset(final double radius); + +} diff --git a/swing/src/net/sf/openrocket/gui/rocketfigure/FinSetShapes.java b/swing/src/net/sf/openrocket/gui/rocketfigure/FinSetShapes.java index 2166b5410..d6c81ce32 100644 --- a/swing/src/net/sf/openrocket/gui/rocketfigure/FinSetShapes.java +++ b/swing/src/net/sf/openrocket/gui/rocketfigure/FinSetShapes.java @@ -21,7 +21,7 @@ public class FinSetShapes extends RocketComponentShape { int finCount = finset.getFinCount(); Transformation cantRotation = finset.getCantRotation(); - Transformation baseRotation = finset.getBaseRotationTransformation(); // rotation about x-axis + Transformation baseRotation = Transformation.rotate_x(finset.getAngularOffset()); // rotation about x-axis Transformation finRotation = finset.getFinRotationTransformation(); Coordinate finSetFront = componentAbsoluteLocation; @@ -96,7 +96,7 @@ public class FinSetShapes extends RocketComponentShape { double thickness = finset.getThickness(); double height = finset.getSpan(); Coordinate compCenter = location; - Transformation baseRotation = finset.getBaseRotationTransformation(); + Transformation baseRotation = Transformation.rotate_x( finset.getAngularOffset()); Transformation finRotation = finset.getFinRotationTransformation(); @@ -146,7 +146,7 @@ public class FinSetShapes extends RocketComponentShape { double radius = finset.getBodyRadius(); double thickness = finset.getThickness(); - Transformation baseRotation = finset.getBaseRotationTransformation(); + Transformation baseRotation = Transformation.rotate_x( finset.getAngularOffset()); Transformation finRotation = finset.getFinRotationTransformation(); Transformation cantRotation = finset.getCantRotation();