[fix] Fixes error when loading FinSet angles

This commit is contained in:
Daniel_M_Williams 2020-02-16 13:17:49 -05:00
parent af3d226b2b
commit d23d25ed15
9 changed files with 69 additions and 38 deletions

View File

@ -20,9 +20,9 @@ class AnglePositionSetter implements Setter {
double pos; double pos;
try { try {
pos = Double.parseDouble(value) * Math.PI / 180.0 ; pos = Math.toRadians(Double.parseDouble(value));
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
warnings.add(String.format("Warning: invalid value radius position. value=%s class: %s", value, c.getClass().getCanonicalName() )); warnings.add(String.format("Warning: invalid angle position. value=%s (degrees) class: %s", value, c.getClass().getCanonicalName() ));
return; return;
} }

View File

@ -20,7 +20,7 @@ public class FinSetSaver extends ExternalComponentSaver {
elements.add("<thickness>" + fins.getThickness() + "</thickness>"); elements.add("<thickness>" + fins.getThickness() + "</thickness>");
elements.add("<crosssection>" + fins.getCrossSection().name().toLowerCase(Locale.ENGLISH) elements.add("<crosssection>" + fins.getCrossSection().name().toLowerCase(Locale.ENGLISH)
+ "</crosssection>"); + "</crosssection>");
elements.add("<cant>" + (fins.getCantAngle() * 180.0 / Math.PI) + "</cant>"); elements.add("<cant>" + Math.toDegrees(fins.getCantAngle()) + "</cant>");
// Save fin tabs only if they exist (compatibility with file version < 1.1) // Save fin tabs only if they exist (compatibility with file version < 1.1)
if (!MathUtil.equals(fins.getTabHeight(), 0) && if (!MathUtil.equals(fins.getTabHeight(), 0) &&

View File

@ -35,7 +35,7 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
/** /**
* Maximum allowed cant of fins. * Maximum allowed cant of fins.
*/ */
public static final double MAX_CANT = (15.0 * Math.PI / 180); public static final double MAX_CANT_RADIANS = (15.0 * Math.PI / 180);
public enum CrossSection { public enum CrossSection {
//// Square //// Square
@ -78,13 +78,13 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
* Rotation angle of the first fin. Zero corresponds to the positive y-axis. * Rotation angle of the first fin. Zero corresponds to the positive y-axis.
*/ */
private AngleMethod angleMethod = AngleMethod.RELATIVE; private AngleMethod angleMethod = AngleMethod.RELATIVE;
private double firstFinOffset = 0; private double firstFinOffsetRadians = 0;
private Transformation baseRotation = Transformation.IDENTITY; // initially, rotate by 0 degrees. private Transformation baseRotation = Transformation.IDENTITY; // initially, rotate by 0 degrees.
/** /**
* Cant angle of fins. * Cant angle of fins.
*/ */
private double cantAngle = 0; private double cantRadians = 0;
/* Cached value: */ /* Cached value: */
private Transformation cantRotation = null; private Transformation cantRotation = null;
@ -194,26 +194,33 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
setAngleOffset(r); setAngleOffset(r);
} }
/**
* @return angle current cant angle, in radians
*/
public double getCantAngle() { public double getCantAngle() {
return cantAngle; return cantRadians;
} }
public void setCantAngle(double cant) { /**
cant = MathUtil.clamp(cant, -MAX_CANT, MAX_CANT); *
if (MathUtil.equals(cant, cantAngle)) * @param cant -- new cant angle, in radians
*/
public void setCantAngle(final double newCantRadians) {
final double clampedCant = MathUtil.clamp(newCantRadians, -MAX_CANT_RADIANS, MAX_CANT_RADIANS);
if (MathUtil.equals(clampedCant, this.cantRadians))
return; return;
this.cantAngle = cant; this.cantRadians = clampedCant;
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
} }
public Transformation getCantRotation() { public Transformation getCantRotation() {
if (cantRotation == null) { if (cantRotation == null) {
if (MathUtil.equals(cantAngle, 0)) { if (MathUtil.equals(this.cantRadians, 0)) {
cantRotation = Transformation.IDENTITY; cantRotation = Transformation.IDENTITY;
} else { } else {
Transformation t = new Transformation(-length / 2, 0, 0); Transformation t = new Transformation(-length / 2, 0, 0);
t = Transformation.rotate_y(cantAngle).applyTransformation(t); t = Transformation.rotate_y(cantRadians).applyTransformation(t);
t = new Transformation(length / 2, 0, 0).applyTransformation(t); t = new Transformation(length / 2, 0, 0).applyTransformation(t);
cantRotation = t; cantRotation = t;
} }
@ -928,16 +935,15 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
@Override @Override
public double getAngleOffset() { public double getAngleOffset() {
return firstFinOffset; return firstFinOffsetRadians;
} }
@Override @Override
public void setAngleOffset(double angle) { public void setAngleOffset(final double angleRadians) {
angle = MathUtil.reduce180(angle); final double reducedAngle = MathUtil.reducePI(angleRadians);
if (MathUtil.equals(angle, firstFinOffset)) if (MathUtil.equals(reducedAngle, firstFinOffsetRadians))
return; return;
firstFinOffset = angle; firstFinOffsetRadians = reducedAngle;
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
} }
@ -947,13 +953,12 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
} }
@Override @Override
public double[] getInstanceAngles(){ public double[] getInstanceAngles() {
final double baseAngle = getAngleOffset(); final double angleIncrementRadians = getInstanceAngleIncrement();
final double incrAngle = getInstanceAngleIncrement();
double[] result = new double[ getFinCount()]; double[] result = new double[ getFinCount()];
for( int i=0; i<getFinCount(); ++i){ for( int finNumber=0; finNumber < getFinCount(); ++finNumber ){
result[i] = MathUtil.reduce360( baseAngle + incrAngle*i); result[finNumber] = MathUtil.reduce2PI( firstFinOffsetRadians + angleIncrementRadians*finNumber);
} }
return result; return result;
@ -1020,8 +1025,8 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
FinSet src = (FinSet) c; FinSet src = (FinSet) c;
this.finCount = src.finCount; this.finCount = src.finCount;
this.finRotation = src.finRotation; this.finRotation = src.finRotation;
this.firstFinOffset = src.firstFinOffset; this.firstFinOffsetRadians = src.firstFinOffsetRadians;
this.cantAngle = src.cantAngle; this.cantRadians = src.cantRadians;
this.cantRotation = src.cantRotation; this.cantRotation = src.cantRotation;
this.thickness = src.thickness; this.thickness = src.thickness;
this.crossSection = src.crossSection; this.crossSection = src.crossSection;
@ -1066,7 +1071,6 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
} }
/** /**
<<<<<<< HEAD
* use this for calculating physical properties, and routine drawing * 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 * @return points representing the fin-root points, relative to ( x: fin-front, y: centerline ) i.e. relto: fin Component reference point

View File

@ -2,8 +2,14 @@ package net.sf.openrocket.rocketcomponent.position;
public interface AnglePositionable { public interface AnglePositionable {
/**
* @return angle to the first element, in radians
*/
public double getAngleOffset(); public double getAngleOffset();
/**
* @param new offset angle, in radians
*/
public void setAngleOffset(final double angle); public void setAngleOffset(final double angle);
public AngleMethod getAngleMethod( ); public AngleMethod getAngleMethod( );

View File

@ -211,9 +211,12 @@ public class MathUtil {
/** /**
* Reduce the angle x to the range 0 - 2*PI. * Reduce the angle x to the range 0 - 2*PI.
*
* @deprecated function refers to units:degrees, but operates in units:radians. Please use 'MathUtil.reduce2PI'
* @param x Original angle. * @param x Original angle.
* @return The equivalent angle in the range 0 ... 2*PI. * @return The equivalent angle in the range 0 ... 2*PI.
*/ */
@Deprecated
public static double reduce360(double x) { public static double reduce360(double x) {
double d = Math.floor(x / (2 * Math.PI)); double d = Math.floor(x / (2 * Math.PI));
return x - d * 2 * Math.PI; return x - d * 2 * Math.PI;
@ -224,9 +227,11 @@ public class MathUtil {
* *
* Either -PI and PI might be returned, depending on the rounding function. * Either -PI and PI might be returned, depending on the rounding function.
* *
* @deprecated function refers to units:degrees, but operates in units:radians. Please use 'MathUtil.reducePI'
* @param x Original angle. * @param x Original angle.
* @return The equivalent angle in the range -PI ... PI. * @return The equivalent angle in the range -PI ... PI.
*/ */
@Deprecated
public static double reduce180(double x) { public static double reduce180(double x) {
double d = Math.rint(x / (2 * Math.PI)); double d = Math.rint(x / (2 * Math.PI));
return x - d * 2 * Math.PI; return x - d * 2 * Math.PI;

View File

@ -50,9 +50,25 @@ public class FinSetTest extends BaseTestCase {
fins.setFilletRadius(0.0); fins.setFilletRadius(0.0);
fins.setAngleMethod(AngleMethod.FIXED);
fins.setAngleOffset(Math.toRadians(90.0));
fins.setCantAngle(Math.toRadians(3.0));
return fins; return fins;
} }
@Test
public void testAngleOffset() {
final FinSet fins = FinSetTest.createSimpleFin();
assertEquals("Angle Offset Doesn't match!", Math.PI/2, fins.getAngleOffset(), EPSILON);
assertEquals("Angle Offset Doesn't match!", 90.0, Math.toDegrees(fins.getAngleOffset()), EPSILON);
assertEquals("Cant angle doesn't match!", Math.PI/60, fins.getCantAngle(), EPSILON);
assertEquals("Cant angle doesn't match!", 3.0, Math.toDegrees(fins.getCantAngle()), EPSILON);
}
@Test @Test
public void testTabLocation() { public void testTabLocation() {
final FinSet fins = FinSetTest.createSimpleFin(); final FinSet fins = FinSetTest.createSimpleFin();

View File

@ -69,14 +69,14 @@ public class EllipticalFinSetConfig extends FinSetConfig {
panel.add(label); panel.add(label);
m = new DoubleModel(component, "CantAngle", UnitGroup.UNITS_ANGLE, m = new DoubleModel(component, "CantAngle", UnitGroup.UNITS_ANGLE,
-FinSet.MAX_CANT, FinSet.MAX_CANT); -FinSet.MAX_CANT_RADIANS, FinSet.MAX_CANT_RADIANS);
spin = new JSpinner(m.getSpinnerModel()); spin = new JSpinner(m.getSpinnerModel());
spin.setEditor(new SpinnerEditor(spin)); spin.setEditor(new SpinnerEditor(spin));
panel.add(spin, "growx"); panel.add(spin, "growx");
panel.add(new UnitSelector(m), "growx"); panel.add(new UnitSelector(m), "growx");
panel.add(new BasicSlider(m.getSliderModel(-FinSet.MAX_CANT, FinSet.MAX_CANT)), panel.add(new BasicSlider(m.getSliderModel(-FinSet.MAX_CANT_RADIANS, FinSet.MAX_CANT_RADIANS)),
"w 100lp, wrap"); "w 100lp, wrap");

View File

@ -134,14 +134,14 @@ public class FreeformFinSetConfig extends FinSetConfig {
label.setToolTipText(trans.get("FreeformFinSetCfg.lbl.ttip.Fincant")); label.setToolTipText(trans.get("FreeformFinSetCfg.lbl.ttip.Fincant"));
panel.add(label); panel.add(label);
m = new DoubleModel(component, "CantAngle", UnitGroup.UNITS_ANGLE, -FinSet.MAX_CANT, FinSet.MAX_CANT); m = new DoubleModel(component, "CantAngle", UnitGroup.UNITS_ANGLE, -FinSet.MAX_CANT_RADIANS, FinSet.MAX_CANT_RADIANS);
spin = new JSpinner(m.getSpinnerModel()); spin = new JSpinner(m.getSpinnerModel());
spin.setEditor(new SpinnerEditor(spin)); spin.setEditor(new SpinnerEditor(spin));
panel.add(spin, "growx"); panel.add(spin, "growx");
panel.add(new UnitSelector(m), "growx"); panel.add(new UnitSelector(m), "growx");
panel.add(new BasicSlider(m.getSliderModel(-FinSet.MAX_CANT, FinSet.MAX_CANT)), "w 100lp, wrap 40lp"); panel.add(new BasicSlider(m.getSliderModel(-FinSet.MAX_CANT_RADIANS, FinSet.MAX_CANT_RADIANS)), "w 100lp, wrap 40lp");

View File

@ -75,14 +75,14 @@ public class TrapezoidFinSetConfig extends FinSetConfig {
label.setToolTipText(trans.get("TrapezoidFinSetCfg.lbl.ttip.Fincant")); label.setToolTipText(trans.get("TrapezoidFinSetCfg.lbl.ttip.Fincant"));
panel.add(label); panel.add(label);
final DoubleModel cantModel = new DoubleModel(component, "CantAngle", UnitGroup.UNITS_ANGLE, -FinSet.MAX_CANT, FinSet.MAX_CANT); final DoubleModel cantModel = new DoubleModel(component, "CantAngle", UnitGroup.UNITS_ANGLE, -FinSet.MAX_CANT_RADIANS, FinSet.MAX_CANT_RADIANS);
final JSpinner cantSpinner = new JSpinner(cantModel.getSpinnerModel()); final JSpinner cantSpinner = new JSpinner(cantModel.getSpinnerModel());
cantSpinner.setEditor(new SpinnerEditor(cantSpinner)); cantSpinner.setEditor(new SpinnerEditor(cantSpinner));
panel.add(cantSpinner, "growx"); panel.add(cantSpinner, "growx");
panel.add(new UnitSelector(cantModel), "growx"); panel.add(new UnitSelector(cantModel), "growx");
panel.add(new BasicSlider(cantModel.getSliderModel(-FinSet.MAX_CANT, FinSet.MAX_CANT)), panel.add(new BasicSlider(cantModel.getSliderModel(-FinSet.MAX_CANT_RADIANS, FinSet.MAX_CANT_RADIANS)),
"w 100lp, wrap"); "w 100lp, wrap");
} }