You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ma...@apache.org on 2021/06/08 11:29:53 UTC
[commons-numbers] branch master updated: NUMBERS-134: cleaning up
Angles class
This is an automated email from the ASF dual-hosted git repository.
mattjuntunen pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git
The following commit(s) were added to refs/heads/master by this push:
new d0aa478 NUMBERS-134: cleaning up Angles class
d0aa478 is described below
commit d0aa478385267813da3ce4a2892cab9a30ad5174
Author: Matt Juntunen <ma...@apache.org>
AuthorDate: Mon Jun 7 21:44:13 2021 -0400
NUMBERS-134: cleaning up Angles class
---
.../org/apache/commons/numbers/angle/Angle.java | 147 +++++++--------------
.../resources/spotbugs/spotbugs-exclude-filter.xml | 5 -
2 files changed, 49 insertions(+), 103 deletions(-)
diff --git a/commons-numbers-angle/src/main/java/org/apache/commons/numbers/angle/Angle.java b/commons-numbers-angle/src/main/java/org/apache/commons/numbers/angle/Angle.java
index 5aebe72..d290b2f 100644
--- a/commons-numbers-angle/src/main/java/org/apache/commons/numbers/angle/Angle.java
+++ b/commons-numbers-angle/src/main/java/org/apache/commons/numbers/angle/Angle.java
@@ -27,16 +27,20 @@ public abstract class Angle implements DoubleSupplier {
public static final double TWO_PI = 2 * Math.PI;
/** π/2. */
public static final double PI_OVER_TWO = 0.5 * Math.PI;
- /** Conversion factor. */
+ /** Turns to degrees conversion factor. */
private static final double TURN_TO_DEG = 360d;
+ /** Radians to degrees conversion factor. */
+ private static final double RAD_TO_DEG = 180.0 / Math.PI;
+ /** Degrees to radians conversion factor. */
+ private static final double DEG_TO_RAD = Math.PI / 180.0;
/** Value (unit depends on concrete instance). */
- protected final double value;
+ private final double value;
/**
* @param value Value in turns.
*/
- private Angle(double value) {
+ private Angle(final double value) {
this.value = value;
}
@@ -53,6 +57,23 @@ public abstract class Angle implements DoubleSupplier {
}
/**
+ * Test for equality with another object.
+ * Objects are considered to be equal if their concrete types are
+ * equal and their values are exactly the same (or both are {@code Double.NaN}).
+ *
+ * @param other Object to test for equality with this instance.
+ * @return {@code true} if the objects are equal, {@code false} if
+ * {@code other} is {@code null}, not of the same type as this instance,
+ * or not equal to this instance.
+ */
+ @Override
+ public boolean equals(final Object other) {
+ return other != null &&
+ getClass().equals(other.getClass()) &&
+ Double.doubleToLongBits(value) == Double.doubleToLongBits(((Angle) other).value);
+ }
+
+ /**
* @return the angle in <a href="https://en.wikipedia.org/wiki/Turn_%28geometry%29">turns</a>.
*/
public abstract Turn toTurn();
@@ -68,21 +89,6 @@ public abstract class Angle implements DoubleSupplier {
public abstract Deg toDeg();
/**
- * Objects are considered to be equal if their values are exactly
- * the same, or both are {@code Double.NaN}.
- * Caveat: Method should be called only on instances of the same
- * concrete type in order to avoid that angles with the same value
- * but different units are be considered equal.
- *
- * @param other Angle.
- * @return {@code true} if the two instances have the same {@link #value}.
- */
- protected boolean isSame(Angle other) {
- return this == other ||
- Double.doubleToLongBits(value) == Double.doubleToLongBits(other.value);
- }
-
- /**
* Unit: <a href="https://en.wikipedia.org/wiki/Turn_%28geometry%29">turns</a>.
*/
public static final class Turn extends Angle {
@@ -94,7 +100,7 @@ public abstract class Angle implements DoubleSupplier {
/**
* @param angle (in turns).
*/
- private Turn(double angle) {
+ private Turn(final double angle) {
super(angle);
}
@@ -102,27 +108,10 @@ public abstract class Angle implements DoubleSupplier {
* @param angle (in turns).
* @return a new intance.
*/
- public static Turn of(double angle) {
+ public static Turn of(final double angle) {
return new Turn(angle);
}
- /**
- * Test for equality with another object.
- * Objects are considered to be equal if their values are exactly
- * the same, or both are {@code Double.NaN}.
- *
- * @param other Object to test for equality with this instance.
- * @return {@code true} if the objects are equal, {@code false} if
- * {@code other} is {@code null}, not an instance of {@code Turn},
- * or not equal to this instance.
- */
- @Override
- public boolean equals(Object other) {
- return other instanceof Turn ?
- isSame((Turn) other) :
- false;
- }
-
/** {@inheritDoc} */
@Override
public Turn toTurn() {
@@ -132,13 +121,13 @@ public abstract class Angle implements DoubleSupplier {
/** {@inheritDoc} */
@Override
public Rad toRad() {
- return Rad.of(value * TWO_PI);
+ return Rad.of(getAsDouble() * TWO_PI);
}
/** {@inheritDoc} */
@Override
public Deg toDeg() {
- return Deg.of(value * TURN_TO_DEG);
+ return Deg.of(getAsDouble() * TURN_TO_DEG);
}
/**
@@ -148,9 +137,8 @@ public abstract class Angle implements DoubleSupplier {
* @param lo Lower bound of the normalized interval.
* @return the normalization operator.
*/
- public static DoubleUnaryOperator normalizer(double lo) {
- final Normalizer n = new Normalizer(lo, 1d);
- return a -> n.applyAsDouble(a);
+ public static DoubleUnaryOperator normalizer(final double lo) {
+ return new Normalizer(lo, 1d);
}
}
@@ -163,7 +151,7 @@ public abstract class Angle implements DoubleSupplier {
/** π. */
public static final Rad PI = Rad.of(Math.PI);
/** 2π. */
- public static final Rad TWO_PI = Rad.of(2 * Math.PI);
+ public static final Rad TWO_PI = Rad.of(Angle.TWO_PI);
/** Normalizing operator (result will be within the <code>[0, 2π[</code> interval). */
public static final DoubleUnaryOperator WITHIN_0_AND_2PI = normalizer(0d);
/** Normalizing operator (result will be within the <code>[-π, π[</code> interval). */
@@ -172,7 +160,7 @@ public abstract class Angle implements DoubleSupplier {
/**
* @param angle (in radians).
*/
- private Rad(double angle) {
+ private Rad(final double angle) {
super(angle);
}
@@ -180,31 +168,14 @@ public abstract class Angle implements DoubleSupplier {
* @param angle (in radians).
* @return a new intance.
*/
- public static Rad of(double angle) {
+ public static Rad of(final double angle) {
return new Rad(angle);
}
- /**
- * Test for equality with another object.
- * Objects are considered to be equal if their values are exactly
- * the same, or both are {@code Double.NaN}.
- *
- * @param other Object to test for equality with this instance.
- * @return {@code true} if the objects are equal, {@code false} if
- * {@code other} is {@code null}, not an instance of {@code Rad},
- * or not equal to this instance.
- */
- @Override
- public boolean equals(Object other) {
- return other instanceof Rad ?
- isSame((Rad) other) :
- false;
- }
-
/** {@inheritDoc} */
@Override
public Turn toTurn() {
- return Turn.of(value / Angle.TWO_PI);
+ return Turn.of(getAsDouble() / Angle.TWO_PI);
}
/** {@inheritDoc} */
@@ -216,7 +187,7 @@ public abstract class Angle implements DoubleSupplier {
/** {@inheritDoc} */
@Override
public Deg toDeg() {
- return Deg.of(value / Angle.TWO_PI * TURN_TO_DEG);
+ return Deg.of(getAsDouble() * RAD_TO_DEG);
}
/**
@@ -226,9 +197,8 @@ public abstract class Angle implements DoubleSupplier {
* @param lo Lower bound of the normalized interval.
* @return the normalization operator.
*/
- public static DoubleUnaryOperator normalizer(double lo) {
- final Normalizer n = new Normalizer(lo, Angle.TWO_PI);
- return a -> n.applyAsDouble(a);
+ public static DoubleUnaryOperator normalizer(final double lo) {
+ return new Normalizer(lo, Angle.TWO_PI);
}
}
@@ -244,7 +214,7 @@ public abstract class Angle implements DoubleSupplier {
/**
* @param angle (in degrees).
*/
- private Deg(double angle) {
+ private Deg(final double angle) {
super(angle);
}
@@ -252,37 +222,20 @@ public abstract class Angle implements DoubleSupplier {
* @param angle (in degrees).
* @return a new intance.
*/
- public static Deg of(double angle) {
+ public static Deg of(final double angle) {
return new Deg(angle);
}
- /**
- * Test for equality with another object.
- * Objects are considered to be equal if their values are exactly
- * the same, or both are {@code Double.NaN}.
- *
- * @param other Object to test for equality with this instance.
- * @return {@code true} if the objects are equal, {@code false} if
- * {@code other} is {@code null}, not an instance of {@code Deg},
- * or not equal to this instance.
- */
- @Override
- public boolean equals(Object other) {
- return other instanceof Deg ?
- isSame((Deg) other) :
- false;
- }
-
/** {@inheritDoc} */
@Override
public Turn toTurn() {
- return Turn.of(value / TURN_TO_DEG);
+ return Turn.of(getAsDouble() / TURN_TO_DEG);
}
/** {@inheritDoc} */
@Override
public Rad toRad() {
- return Rad.of(value / TURN_TO_DEG * Angle.TWO_PI);
+ return Rad.of(getAsDouble() * DEG_TO_RAD);
}
/** {@inheritDoc} */
@@ -298,9 +251,8 @@ public abstract class Angle implements DoubleSupplier {
* @param lo Lower bound of the normalized interval.
* @return the normalization operator.
*/
- public static DoubleUnaryOperator normalizer(double lo) {
- final Normalizer n = new Normalizer(lo, TURN_TO_DEG);
- return a -> n.applyAsDouble(a);
+ public static DoubleUnaryOperator normalizer(final double lo) {
+ return new Normalizer(lo, TURN_TO_DEG);
}
}
@@ -323,8 +275,8 @@ public abstract class Angle implements DoubleSupplier {
* @param lo Lower bound of the desired interval.
* @param period Circonference of the circle.
*/
- Normalizer(double lo,
- double period) {
+ Normalizer(final double lo,
+ final double period) {
this.period = period;
this.lo = lo;
this.hi = lo + period;
@@ -337,7 +289,7 @@ public abstract class Angle implements DoubleSupplier {
* {@code lo <= a - k < lo + period}.
*/
@Override
- public double applyAsDouble(double a) {
+ public double applyAsDouble(final double a) {
if (lo <= a &&
a < hi) {
// Already within the main interval.
@@ -351,10 +303,9 @@ public abstract class Angle implements DoubleSupplier {
// floor expression above (i.e. value + x = x), then we may
// end up with a number exactly equal to the upper bound.
// In that case, subtract one period from the normalized value
- // so that the result is strictly less than the upper bound.
- normalized == hi ?
- lo : // Ensure that the result is not below the lower bound.
- normalized - period;
+ // so that the result is strictly less than the upper bound. (We also
+ // want to ensure that we do not return anything less than the lower bound.)
+ Math.max(lo, normalized - period);
}
}
}
diff --git a/src/main/resources/spotbugs/spotbugs-exclude-filter.xml b/src/main/resources/spotbugs/spotbugs-exclude-filter.xml
index 479aab1..c3012e8 100644
--- a/src/main/resources/spotbugs/spotbugs-exclude-filter.xml
+++ b/src/main/resources/spotbugs/spotbugs-exclude-filter.xml
@@ -41,11 +41,6 @@
<Method name="sqrt"/>
<BugPattern name="FE_FLOATING_POINT_EQUALITY"/>
</Match>
- <Match>
- <Class name="org.apache.commons.numbers.angle.Angle$Normalizer"/>
- <Method name="applyAsDouble"/>
- <BugPattern name="FE_FLOATING_POINT_EQUALITY"/>
- </Match>
<Match>
<!-- Benchmark state classes can expose internal representations -->