You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by er...@apache.org on 2021/05/27 09:13:08 UTC
[commons-numbers] branch master updated: NUMBERS-158: Angle
"normalization" operators.
This is an automated email from the ASF dual-hosted git repository.
erans 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 3cf0a49 NUMBERS-158: Angle "normalization" operators.
3cf0a49 is described below
commit 3cf0a49a330c3c9918f0fdc7f4d3fc6c08be0c36
Author: Gilles Sadowski <gi...@gmail.com>
AuthorDate: Thu May 27 11:09:59 2021 +0200
NUMBERS-158: Angle "normalization" operators.
API based on JDK 8 replaces "static" functions.
---
.../apache/commons/numbers/angle/PlaneAngle.java | 77 +++++++++++++++-------
.../commons/numbers/angle/PlaneAngleRadians.java | 59 +++++++++--------
.../numbers/angle/PlaneAngleRadiansTest.java | 26 ++++----
.../commons/numbers/angle/PlaneAngleTest.java | 56 +++++++++-------
.../apache/commons/numbers/angle/ReduceTest.java | 4 +-
5 files changed, 130 insertions(+), 92 deletions(-)
diff --git a/commons-numbers-angle/src/main/java/org/apache/commons/numbers/angle/PlaneAngle.java b/commons-numbers-angle/src/main/java/org/apache/commons/numbers/angle/PlaneAngle.java
index a421e43..78347af 100644
--- a/commons-numbers-angle/src/main/java/org/apache/commons/numbers/angle/PlaneAngle.java
+++ b/commons-numbers-angle/src/main/java/org/apache/commons/numbers/angle/PlaneAngle.java
@@ -16,6 +16,8 @@
*/
package org.apache.commons.numbers.angle;
+import java.util.function.UnaryOperator;
+
/**
* Represents the <a href="https://en.wikipedia.org/wiki/Angle">angle</a> concept.
*/
@@ -90,31 +92,6 @@ public final class PlaneAngle {
}
/**
- * Normalize an angle in an interval of size 1 turn around a
- * center value.
- *
- * @param center Center of the desired interval for the result.
- * @return {@code a - k} with integer {@code k} such that
- * {@code center - 0.5 <= a - k < center + 0.5} (in turns).
- */
- public PlaneAngle normalize(PlaneAngle center) {
- final double lowerBound = center.value - HALF_TURN;
- final double upperBound = center.value + HALF_TURN;
-
- final double normalized = value - Math.floor(value - lowerBound);
-
- return normalized < upperBound ?
- new PlaneAngle(normalized) :
- // If value is too small to be representable compared to the
- // floor expression above (ie, if value + x = x), then we may
- // end up with a number exactly equal to the upper bound here.
- // In that case, subtract one from the normalized value so that
- // we can fulfill the contract of only returning results strictly
- // less than the upper bound.
- new PlaneAngle(normalized - 1);
- }
-
- /**
* Test for equality with another object.
* Objects are considered to be equal if the two values are exactly the
* same, or both are {@code Double.NaN}.
@@ -141,4 +118,54 @@ public final class PlaneAngle {
public int hashCode() {
return Double.hashCode(value);
}
+
+ /**
+ * Normalizes an angle in an interval of size 1 turn around a center value.
+ */
+ public static final class Normalizer implements UnaryOperator<PlaneAngle> {
+ /** Lower bound. */
+ private final double lowerBound;
+ /** Upper bound. */
+ private final double upperBound;
+ /** Normalizer. */
+ private final Reduce reduce;
+
+ /**
+ * @param center Center of the desired interval.
+ */
+ private Normalizer(PlaneAngle center) {
+ lowerBound = center.value - HALF_TURN;
+ upperBound = center.value + HALF_TURN;
+ reduce = new Reduce(lowerBound, 1d);
+ }
+
+ /**
+ * @param a Angle.
+ * @return {@code = a - k} where {@code k} is an integer that satisfies
+ * {@code center - 0.5 <= a - k < center + 0.5} (in turns).
+ */
+ @Override
+ public PlaneAngle apply(PlaneAngle a) {
+ final double normalized = reduce.applyAsDouble(a.value) + lowerBound;
+ return normalized < upperBound ?
+ new PlaneAngle(normalized) :
+ // If value is too small to be representable compared to the
+ // floor expression above (ie, if value + x = x), then we may
+ // end up with a number exactly equal to the upper bound here.
+ // In that case, subtract one from the normalized value so that
+ // we can fulfill the contract of only returning results strictly
+ // less than the upper bound.
+ new PlaneAngle(normalized - 1);
+ }
+ }
+
+ /**
+ * Factory method.
+ *
+ * @param center Center of the desired interval.
+ * @return a {@link Normalizer} instance.
+ */
+ public static Normalizer normalizer(PlaneAngle center) {
+ return new Normalizer(center);
+ }
}
diff --git a/commons-numbers-angle/src/main/java/org/apache/commons/numbers/angle/PlaneAngleRadians.java b/commons-numbers-angle/src/main/java/org/apache/commons/numbers/angle/PlaneAngleRadians.java
index a4f0edc..c9a1c5c 100644
--- a/commons-numbers-angle/src/main/java/org/apache/commons/numbers/angle/PlaneAngleRadians.java
+++ b/commons-numbers-angle/src/main/java/org/apache/commons/numbers/angle/PlaneAngleRadians.java
@@ -16,6 +16,8 @@
*/
package org.apache.commons.numbers.angle;
+import java.util.function.DoubleUnaryOperator;
+
/**
* Utility class where all {@code double} values are assumed to be in
* radians.
@@ -31,45 +33,46 @@ public final class PlaneAngleRadians {
public static final double PI_OVER_TWO = 0.5 * PI;
/** Value of \( 3\pi/2 \): {@value}. */
public static final double THREE_PI_OVER_TWO = 3 * PI_OVER_TWO;
+ /** Normalizes an angle to be in the range [-π, π). */
+ public static final Normalizer WITHIN_MINUS_PI_AND_PI = new Normalizer(PlaneAngle.ZERO);
+ /** Normalize an angle to be in the range [0, 2π). */
+ public static final Normalizer WITHIN_0_AND_2PI = new Normalizer(PlaneAngle.PI);
/** Utility class. */
private PlaneAngleRadians() {}
/**
- * Normalize an angle in an interval of size 2π around a
- * center value.
- *
- * @param angle Value to be normalized.
- * @param center Center of the desired interval for the result.
- * @return {@code a - 2 * k} with integer {@code k} such that
- * {@code center - pi <= a - 2 * k * pi < center + pi}.
+ * Normalizes an angle in an interval of size 2π around a center value.
*/
- public static double normalize(double angle,
- double center) {
- final PlaneAngle a = PlaneAngle.ofRadians(angle);
- final PlaneAngle c = PlaneAngle.ofRadians(center);
- return a.normalize(c).toRadians();
- }
+ public static final class Normalizer implements DoubleUnaryOperator {
+ /** Underlying normalizer. */
+ private final PlaneAngle.Normalizer normalizer;
- /**
- * Normalize an angle to be in the range [-π, π).
- *
- * @param angle Value to be normalized.
- * @return {@code a - 2 * k} with integer {@code k} such that
- * {@code -pi <= a - 2 * k * pi < pi}.
- */
- public static double normalizeBetweenMinusPiAndPi(double angle) {
- return PlaneAngle.ofRadians(angle).normalize(PlaneAngle.ZERO).toRadians();
+ /**
+ * @param center Center (in radians) of the desired interval.
+ */
+ private Normalizer(PlaneAngle center) {
+ normalizer = PlaneAngle.normalizer(center);
+ }
+
+ /**
+ * @param a Angle (in radians).
+ * @return {@code a - 2 * k} with integer {@code k} such that
+ * {@code center - pi <= a - 2 * k * pi < center + pi} (in radians).
+ */
+ @Override
+ public double applyAsDouble(double a) {
+ return normalizer.apply(PlaneAngle.ofRadians(a)).toRadians();
+ }
}
/**
- * Normalize an angle to be in the range [0, 2π).
+ * Factory method.
*
- * @param angle Value to be normalized.
- * @return {@code a - 2 * k} with integer {@code k} such that
- * {@code 0 <= a - 2 * k * pi < 2 * pi}.
+ * @param center Center (in radians) of the desired interval.
+ * @return a {@link Normalizer} instance.
*/
- public static double normalizeBetweenZeroAndTwoPi(double angle) {
- return PlaneAngle.ofRadians(angle).normalize(PlaneAngle.PI).toRadians();
+ public static Normalizer normalizer(double center) {
+ return new Normalizer(PlaneAngle.ofRadians(center));
}
}
diff --git a/commons-numbers-angle/src/test/java/org/apache/commons/numbers/angle/PlaneAngleRadiansTest.java b/commons-numbers-angle/src/test/java/org/apache/commons/numbers/angle/PlaneAngleRadiansTest.java
index a320e26..2d31944 100644
--- a/commons-numbers-angle/src/test/java/org/apache/commons/numbers/angle/PlaneAngleRadiansTest.java
+++ b/commons-numbers-angle/src/test/java/org/apache/commons/numbers/angle/PlaneAngleRadiansTest.java
@@ -56,7 +56,7 @@ class PlaneAngleRadiansTest {
void testNormalize() {
for (double a = -15.0; a <= 15.0; a += 0.1) {
for (double b = -15.0; b <= 15.0; b += 0.2) {
- final double c = PlaneAngleRadians.normalize(a, b);
+ final double c = PlaneAngleRadians.normalizer(b).applyAsDouble(a);
Assertions.assertTrue((b - PlaneAngleRadians.PI) <= c);
Assertions.assertTrue(c <= (b + PlaneAngleRadians.PI));
double twoK = Math.rint((a - c) / PlaneAngleRadians.PI);
@@ -69,7 +69,7 @@ class PlaneAngleRadiansTest {
void testNormalizeBetweenMinusPiAndPi1() {
final double value = 1.25 * PlaneAngleRadians.TWO_PI;
final double expected = PlaneAngleRadians.PI_OVER_TWO;
- final double actual = PlaneAngleRadians.normalizeBetweenMinusPiAndPi(value);
+ final double actual = PlaneAngleRadians.WITHIN_MINUS_PI_AND_PI.applyAsDouble(value);
final double tol = Math.ulp(expected);
Assertions.assertEquals(expected, actual, tol);
}
@@ -77,7 +77,7 @@ class PlaneAngleRadiansTest {
void testNormalizeBetweenMinusPiAndPi2() {
final double value = 0.75 * PlaneAngleRadians.TWO_PI;
final double expected = -PlaneAngleRadians.PI_OVER_TWO;
- final double actual = PlaneAngleRadians.normalizeBetweenMinusPiAndPi(value);
+ final double actual = PlaneAngleRadians.WITHIN_MINUS_PI_AND_PI.applyAsDouble(value);
final double tol = Math.ulp(expected);
Assertions.assertEquals(expected, actual, tol);
}
@@ -85,7 +85,7 @@ class PlaneAngleRadiansTest {
void testNormalizeBetweenMinusPiAndPi3() {
final double value = PlaneAngleRadians.PI + 1e-10;
final double expected = -PlaneAngleRadians.PI + 1e-10;
- final double actual = PlaneAngleRadians.normalizeBetweenMinusPiAndPi(value);
+ final double actual = PlaneAngleRadians.WITHIN_MINUS_PI_AND_PI.applyAsDouble(value);
final double tol = Math.ulp(expected);
Assertions.assertEquals(expected, actual, tol);
}
@@ -93,7 +93,7 @@ class PlaneAngleRadiansTest {
void testNormalizeBetweenMinusPiAndPi4() {
final double value = 5 * PlaneAngleRadians.PI / 4;
final double expected = PlaneAngleRadians.PI * (1d / 4 - 1);
- final double actual = PlaneAngleRadians.normalizeBetweenMinusPiAndPi(value);
+ final double actual = PlaneAngleRadians.WITHIN_MINUS_PI_AND_PI.applyAsDouble(value);
final double tol = Math.ulp(expected);
Assertions.assertEquals(expected, actual, tol);
}
@@ -102,7 +102,7 @@ class PlaneAngleRadiansTest {
void testNormalizeBetweenMinusPiAndPi_lowerBound() {
final double value = PlaneAngleRadians.PI;
final double expected = -PlaneAngleRadians.PI;
- final double actual = PlaneAngleRadians.normalizeBetweenMinusPiAndPi(value);
+ final double actual = PlaneAngleRadians.WITHIN_MINUS_PI_AND_PI.applyAsDouble(value);
final double tol = Math.ulp(expected);
Assertions.assertEquals(expected, actual, tol);
}
@@ -110,7 +110,7 @@ class PlaneAngleRadiansTest {
void testNormalizeBetweenMinusPiAndPi_upperBound() {
final double value = PlaneAngleRadians.PI;
final double expected = -PlaneAngleRadians.PI;
- final double actual = PlaneAngleRadians.normalizeBetweenMinusPiAndPi(value);
+ final double actual = PlaneAngleRadians.WITHIN_MINUS_PI_AND_PI.applyAsDouble(value);
final double tol = Math.ulp(expected);
Assertions.assertEquals(expected, actual, tol);
}
@@ -119,7 +119,7 @@ class PlaneAngleRadiansTest {
void testNormalizeBetweenZeroAndTwoPi1() {
final double value = 1.25 * PlaneAngleRadians.TWO_PI;
final double expected = PlaneAngleRadians.PI_OVER_TWO;
- final double actual = PlaneAngleRadians.normalizeBetweenZeroAndTwoPi(value);
+ final double actual = PlaneAngleRadians.WITHIN_0_AND_2PI.applyAsDouble(value);
final double tol = Math.ulp(expected);
Assertions.assertEquals(expected, actual, tol);
}
@@ -127,7 +127,7 @@ class PlaneAngleRadiansTest {
void testNormalizeBetweenZeroAndTwoPi2() {
final double value = 1.75 * PlaneAngleRadians.TWO_PI;
final double expected = PlaneAngleRadians.THREE_PI_OVER_TWO;
- final double actual = PlaneAngleRadians.normalizeBetweenZeroAndTwoPi(value);
+ final double actual = PlaneAngleRadians.WITHIN_0_AND_2PI.applyAsDouble(value);
final double tol = Math.ulp(expected);
Assertions.assertEquals(expected, actual, tol);
}
@@ -135,7 +135,7 @@ class PlaneAngleRadiansTest {
void testNormalizeBetweenZeroAndTwoPi3() {
final double value = -PlaneAngleRadians.PI + 1e-10;
final double expected = PlaneAngleRadians.PI + 1e-10;
- final double actual = PlaneAngleRadians.normalizeBetweenZeroAndTwoPi(value);
+ final double actual = PlaneAngleRadians.WITHIN_0_AND_2PI.applyAsDouble(value);
final double tol = Math.ulp(expected);
Assertions.assertEquals(expected, actual, tol);
}
@@ -143,7 +143,7 @@ class PlaneAngleRadiansTest {
void testNormalizeBetweenZeroAndTwoPi4() {
final double value = 9 * PlaneAngleRadians.PI / 4;
final double expected = PlaneAngleRadians.PI / 4;
- final double actual = PlaneAngleRadians.normalizeBetweenZeroAndTwoPi(value);
+ final double actual = PlaneAngleRadians.WITHIN_0_AND_2PI.applyAsDouble(value);
final double tol = Math.ulp(expected);
Assertions.assertEquals(expected, actual, tol);
}
@@ -152,7 +152,7 @@ class PlaneAngleRadiansTest {
void testNormalizeBetweenZeroAndTwoPi_lowerBound() {
final double value = 0.0;
final double expected = 0.0;
- final double actual = PlaneAngleRadians.normalizeBetweenZeroAndTwoPi(value);
+ final double actual = PlaneAngleRadians.WITHIN_0_AND_2PI.applyAsDouble(value);
final double tol = Math.ulp(expected);
Assertions.assertEquals(expected, actual, tol);
}
@@ -160,7 +160,7 @@ class PlaneAngleRadiansTest {
void testNormalizeBetweenZeroAndTwoPi_upperBound() {
final double value = PlaneAngleRadians.TWO_PI;
final double expected = 0.0;
- final double actual = PlaneAngleRadians.normalizeBetweenZeroAndTwoPi(value);
+ final double actual = PlaneAngleRadians.WITHIN_0_AND_2PI.applyAsDouble(value);
final double tol = Math.ulp(expected);
Assertions.assertEquals(expected, actual, tol);
}
diff --git a/commons-numbers-angle/src/test/java/org/apache/commons/numbers/angle/PlaneAngleTest.java b/commons-numbers-angle/src/test/java/org/apache/commons/numbers/angle/PlaneAngleTest.java
index bf37b89..ab1f64f 100644
--- a/commons-numbers-angle/src/test/java/org/apache/commons/numbers/angle/PlaneAngleTest.java
+++ b/commons-numbers-angle/src/test/java/org/apache/commons/numbers/angle/PlaneAngleTest.java
@@ -16,6 +16,8 @@
*/
package org.apache.commons.numbers.angle;
+import java.util.function.UnaryOperator;
+
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@@ -52,7 +54,7 @@ class PlaneAngleTest {
for (double b = -15.0; b <= 15.0; b += 0.2) {
final PlaneAngle aA = PlaneAngle.ofRadians(a);
final PlaneAngle aB = PlaneAngle.ofRadians(b);
- final double c = aA.normalize(aB).toRadians();
+ final double c = PlaneAngle.normalizer(aB).apply(aA).toRadians();
Assertions.assertTrue((b - Math.PI) <= c);
Assertions.assertTrue(c <= (b + Math.PI));
double twoK = Math.rint((a - c) / Math.PI);
@@ -67,7 +69,7 @@ class PlaneAngleTest {
for (double b = -15.0; b <= 15.0; b += 0.2) {
final PlaneAngle aA = PlaneAngle.ofDegrees(a);
final PlaneAngle aB = PlaneAngle.ofRadians(b);
- final double c = aA.normalize(aB).toTurns();
+ final double c = PlaneAngle.normalizer(aB).apply(aA).toTurns();
Assertions.assertTrue((aB.toTurns() - 0.5) <= c);
Assertions.assertTrue(c <= (aB.toTurns() + 0.5));
double twoK = Math.rint(aA.toTurns() - c);
@@ -80,7 +82,7 @@ class PlaneAngleTest {
void testNormalizeAroundZero1() {
final double value = 1.25;
final double expected = 0.25;
- final double actual = PlaneAngle.ofTurns(value).normalize(PlaneAngle.ZERO).toTurns();
+ final double actual = PlaneAngle.normalizer(PlaneAngle.ZERO).apply(PlaneAngle.ofTurns(value)).toTurns();
final double tol = Math.ulp(expected);
Assertions.assertEquals(expected, actual, tol);
}
@@ -88,7 +90,7 @@ class PlaneAngleTest {
void testNormalizeAroundZero2() {
final double value = 0.75;
final double expected = -0.25;
- final double actual = PlaneAngle.ofTurns(value).normalize(PlaneAngle.ZERO).toTurns();
+ final double actual = PlaneAngle.normalizer(PlaneAngle.ZERO).apply(PlaneAngle.ofTurns(value)).toTurns();
final double tol = Math.ulp(expected);
Assertions.assertEquals(expected, actual, tol);
}
@@ -96,7 +98,7 @@ class PlaneAngleTest {
void testNormalizeAroundZero3() {
final double value = 0.5 + 1e-10;
final double expected = -0.5 + 1e-10;
- final double actual = PlaneAngle.ofTurns(value).normalize(PlaneAngle.ZERO).toTurns();
+ final double actual = PlaneAngle.normalizer(PlaneAngle.ZERO).apply(PlaneAngle.ofTurns(value)).toTurns();
final double tol = Math.ulp(expected);
Assertions.assertEquals(expected, actual, tol);
}
@@ -104,50 +106,56 @@ class PlaneAngleTest {
void testNormalizeAroundZero4() {
final double value = 5 * Math.PI / 4;
final double expected = Math.PI * (1d / 4 - 1);
- final double actual = PlaneAngle.ofRadians(value).normalize(PlaneAngle.ZERO).toRadians();
+ final double actual = PlaneAngle.normalizer(PlaneAngle.ZERO).apply(PlaneAngle.ofRadians(value)).toRadians();
final double tol = Math.ulp(expected);
Assertions.assertEquals(expected, actual, tol);
}
@Test
void testNormalizeUpperAndLowerBounds() {
+ final UnaryOperator<PlaneAngle> nZero = PlaneAngle.normalizer(PlaneAngle.ZERO);
+ final UnaryOperator<PlaneAngle> nPi = PlaneAngle.normalizer(PlaneAngle.PI);
+
// arrange
double eps = 1e-15;
// act/assert
- Assertions.assertEquals(-0.5, PlaneAngle.ofTurns(-0.5).normalize(PlaneAngle.ZERO).toTurns(), eps);
- Assertions.assertEquals(-0.5, PlaneAngle.ofTurns(0.5).normalize(PlaneAngle.ZERO).toTurns(), eps);
+ Assertions.assertEquals(-0.5, nZero.apply(PlaneAngle.ofTurns(-0.5)).toTurns(), eps);
+ Assertions.assertEquals(-0.5, nZero.apply(PlaneAngle.ofTurns(0.5)).toTurns(), eps);
- Assertions.assertEquals(-0.5, PlaneAngle.ofTurns(-1.5).normalize(PlaneAngle.ZERO).toTurns(), eps);
- Assertions.assertEquals(-0.5, PlaneAngle.ofTurns(1.5).normalize(PlaneAngle.ZERO).toTurns(), eps);
+ Assertions.assertEquals(-0.5, nZero.apply(PlaneAngle.ofTurns(-1.5)).toTurns(), eps);
+ Assertions.assertEquals(-0.5, nZero.apply(PlaneAngle.ofTurns(1.5)).toTurns(), eps);
- Assertions.assertEquals(0.0, PlaneAngle.ofTurns(0).normalize(PlaneAngle.PI).toTurns(), eps);
- Assertions.assertEquals(0.0, PlaneAngle.ofTurns(1).normalize(PlaneAngle.PI).toTurns(), eps);
+ Assertions.assertEquals(0.0, nPi.apply(PlaneAngle.ofTurns(0)).toTurns(), eps);
+ Assertions.assertEquals(0.0, nPi.apply(PlaneAngle.ofTurns(1)).toTurns(), eps);
- Assertions.assertEquals(0.0, PlaneAngle.ofTurns(-1).normalize(PlaneAngle.PI).toTurns(), eps);
- Assertions.assertEquals(0.0, PlaneAngle.ofTurns(2).normalize(PlaneAngle.PI).toTurns(), eps);
+ Assertions.assertEquals(0.0, nPi.apply(PlaneAngle.ofTurns(-1)).toTurns(), eps);
+ Assertions.assertEquals(0.0, nPi.apply(PlaneAngle.ofTurns(2)).toTurns(), eps);
}
@Test
void testNormalizeVeryCloseToBounds() {
+ final UnaryOperator<PlaneAngle> nZero = PlaneAngle.normalizer(PlaneAngle.ZERO);
+ final UnaryOperator<PlaneAngle> nPi = PlaneAngle.normalizer(PlaneAngle.PI);
+
// arrange
double eps = 1e-22;
- double small = 1e-16;
- double tiny = 1e-18; // 0.5 + tiny = 0.5 (the value is too small to add to 0.5)
+ double small = 2e-16;
+ double tiny = 5e-17; // 0.5 + tiny = 0.5 (the value is too small to add to 0.5)
// act/assert
- Assertions.assertEquals(1.0 - small, PlaneAngle.ofTurns(-small).normalize(PlaneAngle.PI).toTurns(), eps);
- Assertions.assertEquals(small, PlaneAngle.ofTurns(small).normalize(PlaneAngle.PI).toTurns(), eps);
+ Assertions.assertEquals(1.0 - small, nPi.apply(PlaneAngle.ofTurns(-small)).toTurns(), eps);
+ Assertions.assertEquals(small, nPi.apply(PlaneAngle.ofTurns(small)).toTurns(), eps);
- Assertions.assertEquals(0.5 - small, PlaneAngle.ofTurns(-0.5 - small).normalize(PlaneAngle.ZERO).toTurns(), eps);
- Assertions.assertEquals(-0.5 + small, PlaneAngle.ofTurns(0.5 + small).normalize(PlaneAngle.ZERO).toTurns(), eps);
+ Assertions.assertEquals(0.5 - small, nZero.apply(PlaneAngle.ofTurns(-0.5 - small)).toTurns(), eps);
+ Assertions.assertEquals(-0.5 + small, nZero.apply(PlaneAngle.ofTurns(0.5 + small)).toTurns(), eps);
- Assertions.assertEquals(0.0, PlaneAngle.ofTurns(-tiny).normalize(PlaneAngle.PI).toTurns(), eps);
- Assertions.assertEquals(tiny, PlaneAngle.ofTurns(tiny).normalize(PlaneAngle.PI).toTurns(), eps);
+ Assertions.assertEquals(0.0, nPi.apply(PlaneAngle.ofTurns(-tiny)).toTurns(), eps);
+ Assertions.assertEquals(tiny, nPi.apply(PlaneAngle.ofTurns(tiny)).toTurns(), eps);
- Assertions.assertEquals(-0.5, PlaneAngle.ofTurns(-0.5 - tiny).normalize(PlaneAngle.ZERO).toTurns(), eps);
- Assertions.assertEquals(-0.5, PlaneAngle.ofTurns(0.5 + tiny).normalize(PlaneAngle.ZERO).toTurns(), eps);
+ Assertions.assertEquals(-0.5, nZero.apply(PlaneAngle.ofTurns(-0.5 - tiny)).toTurns(), eps);
+ Assertions.assertEquals(-0.5, nZero.apply(PlaneAngle.ofTurns(0.5 + tiny)).toTurns(), eps);
}
@Test
diff --git a/commons-numbers-angle/src/test/java/org/apache/commons/numbers/angle/ReduceTest.java b/commons-numbers-angle/src/test/java/org/apache/commons/numbers/angle/ReduceTest.java
index f78818f..9dc0c34 100644
--- a/commons-numbers-angle/src/test/java/org/apache/commons/numbers/angle/ReduceTest.java
+++ b/commons-numbers-angle/src/test/java/org/apache/commons/numbers/angle/ReduceTest.java
@@ -98,11 +98,11 @@ class ReduceTest {
final double period = 2 * Math.PI;
for (double a = -15; a <= 15; a += 0.5) {
for (double center = -15; center <= 15; center += 1) {
- final double nA = PlaneAngleRadians.normalize(a, center);
+ final double nA = PlaneAngleRadians.normalizer(center).applyAsDouble(a);
final double offset = center - Math.PI;
final Reduce reduce = new Reduce(offset, period);
final double r = reduce.applyAsDouble(a) + offset;
- Assertions.assertEquals(nA, r, 52 * Math.ulp(nA),
+ Assertions.assertEquals(nA, r, 1.1e2 * Math.ulp(nA),
"a=" + a + " center=" + center);
}
}