added an angle normalization method to MathUtils
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@619861 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
d67bb46ed8
commit
95aca8ea3a
|
@ -43,6 +43,9 @@ public final class MathUtils {
|
|||
/** 0.0 cast as a short. */
|
||||
private static final short ZS = (short)0;
|
||||
|
||||
/** 2 π. */
|
||||
private static final double TWO_PI = 2 * Math.PI;
|
||||
|
||||
/**
|
||||
* Private Constructor
|
||||
*/
|
||||
|
@ -705,6 +708,28 @@ public final class MathUtils {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize an angle in a 2&pi wide interval around a center value.
|
||||
* <p>This method has three main uses:</p>
|
||||
* <ul>
|
||||
* <li>normalize an angle between 0 and 2π:<br/>
|
||||
* <code>a = MathUtils.normalizeAngle(a, Math.PI);</code></li>
|
||||
* <li>normalize an angle between -π and +π<br/>
|
||||
* <code>a = MathUtils.normalizeAngle(a, 0.0);</code></li>
|
||||
* <li>compute the angle between two defining angular positions:<br>
|
||||
* <code>angle = MathUtils.normalizeAngle(end, start) - start;</code></li>
|
||||
* </ul>
|
||||
* <p>Note that due to numerical accuracy and since π cannot be represented
|
||||
* exactly, the result interval is <em>closed</em>, it cannot be half-closed
|
||||
* as would be more satisfactory in a purely mathematical view.</p>
|
||||
* @param a angle to normalize
|
||||
* @param center center of the desired 2π interval for the result
|
||||
* @return a-2kπ with integer k and center-π <= a-2kπ <= center+π
|
||||
*/
|
||||
public static double normalizeAngle(double a, double center) {
|
||||
return a - TWO_PI * Math.floor((a + Math.PI - center) / TWO_PI);
|
||||
}
|
||||
|
||||
/**
|
||||
* Round the given value to the specified number of decimal places. The
|
||||
* value is rounded using the {@link BigDecimal#ROUND_HALF_UP} method.
|
||||
|
@ -1007,4 +1032,5 @@ public final class MathUtils {
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -146,6 +146,10 @@ Commons Math Release Notes</title>
|
|||
<action dev="luc" type="update" >
|
||||
Added a equals and hash methods in MathUtils to check for double arrays
|
||||
</action>
|
||||
<action dev="luc" type="update" >
|
||||
Added an angle normalization method in MathUtils to force angles in some
|
||||
user-defined interval
|
||||
</action>
|
||||
</release>
|
||||
<release version="1.1" date="2005-12-17"
|
||||
description="This is a maintenance release containing bug fixes and enhancements.
|
||||
|
|
|
@ -20,6 +20,7 @@ import junit.framework.TestCase;
|
|||
import junit.framework.TestSuite;
|
||||
|
||||
import org.apache.commons.math.TestUtils;
|
||||
import org.apache.commons.math.stat.descriptive.SummaryStatistics;
|
||||
|
||||
/**
|
||||
* Test cases for the MathUtils class.
|
||||
|
@ -521,6 +522,20 @@ public final class MathUtilsTest extends TestCase {
|
|||
assertEquals(0, MathUtils.nextAfter(-Double.MIN_VALUE, 1), 0);
|
||||
}
|
||||
|
||||
public void testNormalizeAngle() {
|
||||
SummaryStatistics stat = new SummaryStatistics();
|
||||
for (double a = -15.0; a <= 15.0; a += 0.1) {
|
||||
for (double b = -15.0; b <= 15.0; b += 0.2) {
|
||||
double c = MathUtils.normalizeAngle(a, b);
|
||||
assertTrue((b - Math.PI) <= c);
|
||||
assertTrue(c <= (b + Math.PI));
|
||||
double twoK = Math.rint((a - c) / Math.PI);
|
||||
stat.addValue(c - a + twoK * Math.PI);
|
||||
assertEquals(c, a - twoK * Math.PI, 1.0e-14);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testRoundDouble() {
|
||||
double x = 1.234567890;
|
||||
assertEquals(1.23, MathUtils.round(x, 2), 0.0);
|
||||
|
|
Loading…
Reference in New Issue