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. */
|
/** 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π:<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
|
* 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue