001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package com.sun.perseus.platform;
028:
029: /**
030: * This class is used to provide URL resolution.
031: *
032: * @version $Id: MathSupport.java,v 1.5 2006/04/21 06:34:50 st125089 Exp $
033: */
034: public final class MathSupport {
035: /**
036: * The <code>double</code> value that is closer than any other to
037: * <i>pi</i>, the ratio of the circumference of a circle to its
038: * diameter.
039: */
040: public static final float PI = 3.14159265358979323846f;
041:
042: /**
043: * Returns the trigonometric cosine of an angle. Special cases:
044: * <ul><li>If the argument is NaN or an infinity, then the
045: * result is NaN.</ul>
046: * <p>
047: * A result must be within 1 ulp of the correctly rounded result. Results
048: * must be semi-monotonic.
049: *
050: * @param a an angle, in radians.
051: * @return the cosine of the argument.
052: */
053: public static float cos(float a) {
054: return (float) Math.cos(a);
055: }
056:
057: /**
058: * Returns the trigonometric sine of an angle. Special cases:
059: * <ul><li>If the argument is NaN or an infinity, then the
060: * result is NaN.
061: * <li>If the argument is zero, then the result is a zero with the
062: * same sign as the argument.</ul>
063: * <p>
064: * A result must be within 1 ulp of the correctly rounded result. Results
065: * must be semi-monotonic.
066: *
067: * @param a an angle, in radians.
068: * @return the sine of the argument.
069: */
070: public static float sin(float a) {
071: return (float) Math.sin(a);
072: }
073:
074: /**
075: * Returns the trigonometric tangent of an angle. Special cases:
076: * <ul><li>If the argument is NaN or an infinity, then the result
077: * is NaN.
078: * <li>If the argument is zero, then the result is a zero with the
079: * same sign as the argument.</ul>
080: * <p>
081: * A result must be within 1 ulp of the correctly rounded result. Results
082: * must be semi-monotonic.
083: *
084: * @param a an angle, in radians.
085: * @return the tangent of the argument.
086: */
087: public static float tan(float a) {
088: return (float) Math.tan(a);
089: }
090:
091: /**
092: * Returns the closest <code>int</code> to the argument. The
093: * result is rounded to an integer by adding 1/2, taking the
094: * floor of the result, and casting the result to type <code>int</code>.
095: * In other words, the result is equal to the value of the expression:
096: * <p><pre>(int)Math.floor(a + 0.5f)</pre>
097: * <p>
098: * Special cases:
099: * <ul><li>If the argument is NaN, the result is 0.
100: * <li>If the argument is negative infinity or any value less than or
101: * equal to the value of <code>Integer.MIN_VALUE</code>, the result is
102: * equal to the value of <code>Integer.MIN_VALUE</code>.
103: * <li>If the argument is positive infinity or any value greater than or
104: * equal to the value of <code>Integer.MAX_VALUE</code>, the result is
105: * equal to the value of <code>Integer.MAX_VALUE</code>.</ul>
106: *
107: * @param a a floating-point value to be rounded to an integer.
108: * @return the value of the argument rounded to the nearest
109: * <code>int</code> value.
110: * @see java.lang.Integer#MAX_VALUE
111: * @see java.lang.Integer#MIN_VALUE
112: */
113: public static int round(float a) {
114: return (int) Math.floor(a + 0.5f);
115: }
116:
117: /**
118: * Returns the correctly rounded positive square root of a
119: * <code>float</code> value.
120: * Special cases:
121: * <ul><li>If the argument is NaN or less than zero, then the result
122: * is NaN.
123: * <li>If the argument is positive infinity, then the result is positive
124: * infinity.
125: * <li>If the argument is positive zero or negative zero, then the
126: * result is the same as the argument.</ul>
127: * Otherwise, the result is the <code>float</code> value closest to
128: * the true mathematical square root of the argument value.
129: *
130: * @param a a value.
131: * <!--@return the value of √ <code>a</code>.-->
132: * @return the positive square root of <code>a</code>.
133: * If the argument is NaN or less than zero, the result is NaN.
134: */
135: public static float sqrt(float a) {
136: return (float) Math.sqrt(a);
137: }
138:
139: /**
140: * Converts rectangular coordinates (<code>x</code>, <code>y</code>)
141: * to polar (r, <i>theta</i>).
142: * This method computes the phase <i>theta</i> by computing an arc tangent
143: * of <code>y/x</code> in the range of -<i>pi</i> to <i>pi</i>. Special
144: * cases:
145: * <ul><li>If either argument is NaN, then the result is NaN.
146: * <li>If the first argument is positive zero and the second argument
147: * is positive, or the first argument is positive and finite and the
148: * second argument is positive infinity, then the result is positive
149: * zero.
150: * <li>If the first argument is negative zero and the second argument
151: * is positive, or the first argument is negative and finite and the
152: * second argument is positive infinity, then the result is negative zero.
153: * <li>If the first argument is positive zero and the second argument
154: * is negative, or the first argument is positive and finite and the
155: * second argument is negative infinity, then the result is the
156: * <code>float</code> value closest to <i>pi</i>.
157: * <li>If the first argument is negative zero and the second argument
158: * is negative, or the first argument is negative and finite and the
159: * second argument is negative infinity, then the result is the
160: * <code>float</code> value closest to -<i>pi</i>.
161: * <li>If the first argument is positive and the second argument is
162: * positive zero or negative zero, or the first argument is positive
163: * infinity and the second argument is finite, then the result is the
164: * <code>float</code> value closest to <i>pi</i>/2.
165: * <li>If the first argument is negative and the second argument is
166: * positive zero or negative zero, or the first argument is negative
167: * infinity and the second argument is finite, then the result is the
168: * <code>float</code> value closest to -<i>pi</i>/2.
169: * <li>If both arguments are positive infinity, then the result is the
170: * <code>float</code> value closest to <i>pi</i>/4.
171: * <li>If the first argument is positive infinity and the second argument
172: * is negative infinity, then the result is the <code>float</code>
173: * value closest to 3*<i>pi</i>/4.
174: * <li>If the first argument is negative infinity and the second argument
175: * is positive infinity, then the result is the <code>float</code> value
176: * closest to -<i>pi</i>/4.
177: * <li>If both arguments are negative infinity, then the result is the
178: * <code>float</code> value closest to -3*<i>pi</i>/4.</ul>
179: * <p>
180: * A result must be within 2 ulps of the correctly rounded result. Results
181: * must be semi-monotonic.
182: *
183: * @param y the ordinate coordinate
184: * @param x the abscissa coordinate
185: * @return the <i>theta</i> component of the point
186: * (<i>r</i>, <i>theta</i>)
187: * in polar coordinates that corresponds to the point
188: * (<i>x</i>, <i>y</i>) in Cartesian coordinates.
189: */
190: public static float atan2(float y, float x) {
191: // if x=y=0
192: if ((y == 0.0f) && (x == 0.0f)) {
193: return 0.0f;
194: }
195:
196: // if x>0 atan(y/x)
197: if (x > 0.0f) {
198: return atan(y / x);
199: }
200:
201: // if x<0 sign(y)*(pi - atan(|y/x|))
202: if (x < 0.0f) {
203: if (y < 0.0f) {
204: return (float) (-(Math.PI - MathSupport.atan(y / x)));
205: } else {
206: return (float) (Math.PI - MathSupport.atan(-y / x));
207: }
208: }
209:
210: // if x=0 y!=0 sign(y)*pi/2
211: if (y < 0.0f) {
212: return (float) (-(Math.PI / 2.0f));
213: } else {
214: return (float) (Math.PI / 2.0f);
215: }
216:
217: }
218:
219: /**
220: * Returns the arc tangent of an angle, in the range of -<i>pi</i>/2
221: * through <i>pi</i>/2. Special cases:
222: * <ul><li>If the argument is NaN, then the result is NaN.
223: * <li>If the argument is zero, then the result is a zero with the
224: * same sign as the argument.</ul>
225: * <p>
226: * A result must be within 1 ulp of the correctly rounded result. Results
227: * must be semi-monotonic.
228: *
229: * @param a the value whose arc tangent is to be returned.
230: * @return the arc tangent of the argument.
231: */
232: public static float atan(float a) {
233: //atan(x) = x/(1+ 0.28*x^2) (|x|<=1)
234: //atan(x) = pi/2 - x/(x^2 + 0.28) (|x| >=1)
235:
236: if (MathSupport.abs(a) <= 1.0f) {
237: return (a / (1 + 0.28f * (a * a)));
238: } else {
239: float retval = (((float) Math.PI) / 2.0f)
240: - (a / ((a * a) + 0.28f));
241: if (a < (-1.0f)) {
242: return (retval - (float) Math.PI);
243: } else {
244: //if a > 1.0f
245: return retval;
246: }
247: }
248: }
249:
250: /**
251: * Returns the absolute value of an <code>int</code> value.
252: * If the argument is not negative, the argument is returned.
253: * If the argument is negative, the negation of the argument is returned.
254: * <p>
255: * Note that if the argument is equal to the value of
256: * <code>Integer.MIN_VALUE</code>, the most negative representable
257: * <code>int</code> value, the result is that same value, which is
258: * negative.
259: *
260: * @param a the argument whose absolute value is to be determined
261: * @return the absolute value of the argument.
262: * @see java.lang.Integer#MIN_VALUE
263: */
264: public static int abs(int a) {
265: return (a < 0) ? -a : a;
266: }
267:
268: /**
269: * Returns the absolute value of a <code>float</code> value.
270: * If the argument is not negative, the argument is returned.
271: * If the argument is negative, the negation of the argument is returned.
272: * Special cases:
273: * <ul><li>If the argument is positive zero or negative zero, the
274: * result is positive zero.
275: * <li>If the argument is infinite, the result is positive infinity.
276: * <li>If the argument is NaN, the result is NaN.</ul>
277: * In other words, the result is the same as the value of the expression:
278: * <p><pre>Float.intBitsToFloat(0x7fffffff & Float.floatToIntBits(a))</pre>
279: *
280: * @param a the argument whose absolute value is to be determined
281: * @return the absolute value of the argument.
282: */
283: public static float abs(float a) {
284: return (a <= 0.0F) ? 0.0F - a : a;
285: }
286:
287: /**
288: * Converts an angle measured in degrees to an approximately
289: * equivalent angle measured in radians. The conversion from
290: * degrees to radians is generally inexact.
291: *
292: * @param angdeg an angle, in degrees
293: * @return the measurement of the angle <code>angdeg</code>
294: * in radians.
295: * @since 1.2
296: */
297: public static float toRadians(float angdeg) {
298: return angdeg / 180.0f * PI;
299: }
300:
301: /**
302: * Converts an angle measured in radians to an approximately
303: * equivalent angle measured in degrees. The conversion from
304: * radians to degrees is generally inexact; users should
305: * <i>not</i> expect <code>cos(toRadians(90.0))</code> to exactly
306: * equal <code>0.0</code>.
307: *
308: * @param angrad an angle, in radians
309: * @return the measurement of the angle <code>angrad</code>
310: * in degrees.
311: * @since 1.2
312: */
313: public static float toDegrees(float angrad) {
314: return angrad * 180.0f / PI;
315: }
316:
317: }
|