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:
Luc Maisonobe 2008-02-08 12:36:33 +00:00
parent d67bb46ed8
commit 95aca8ea3a
3 changed files with 45 additions and 0 deletions

View File

@ -43,6 +43,9 @@ public final class MathUtils {
/** 0.0 cast as a short. */ /** 0.0 cast as a short. */
private static final short ZS = (short)0; private static final short ZS = (short)0;
/** 2 π. */
private static final double TWO_PI = 2 * Math.PI;
/** /**
* Private Constructor * 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&pi;:<br/>
* <code>a = MathUtils.normalizeAngle(a, Math.PI);</code></li>
* <li>normalize an angle between -&pi; and +&pi;<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 &pi; 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&pi; interval for the result
* @return a-2k&pi; with integer k and center-&pi; &lt;= a-2k&pi; &lt;= center+&pi;
*/
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 * Round the given value to the specified number of decimal places. The
* value is rounded using the {@link BigDecimal#ROUND_HALF_UP} method. * value is rounded using the {@link BigDecimal#ROUND_HALF_UP} method.
@ -1007,4 +1032,5 @@ public final class MathUtils {
} }
return ret; return ret;
} }
} }

View File

@ -146,6 +146,10 @@ Commons Math Release Notes</title>
<action dev="luc" type="update" > <action dev="luc" type="update" >
Added a equals and hash methods in MathUtils to check for double arrays Added a equals and hash methods in MathUtils to check for double arrays
</action> </action>
<action dev="luc" type="update" >
Added an angle normalization method in MathUtils to force angles in some
user-defined interval
</action>
</release> </release>
<release version="1.1" date="2005-12-17" <release version="1.1" date="2005-12-17"
description="This is a maintenance release containing bug fixes and enhancements. description="This is a maintenance release containing bug fixes and enhancements.

View File

@ -20,6 +20,7 @@ import junit.framework.TestCase;
import junit.framework.TestSuite; import junit.framework.TestSuite;
import org.apache.commons.math.TestUtils; import org.apache.commons.math.TestUtils;
import org.apache.commons.math.stat.descriptive.SummaryStatistics;
/** /**
* Test cases for the MathUtils class. * 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); 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() { public void testRoundDouble() {
double x = 1.234567890; double x = 1.234567890;
assertEquals(1.23, MathUtils.round(x, 2), 0.0); assertEquals(1.23, MathUtils.round(x, 2), 0.0);