blob: 0a6e94216875aa6b32d18f1f9f28aa1f61956ecd [file] [log] [blame]
/*
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.java2d.pisces;
public class PiscesMath {
private PiscesMath() {}
private static final int SINTAB_LG_ENTRIES = 10;
private static final int SINTAB_ENTRIES = 1 << SINTAB_LG_ENTRIES;
private static int[] sintab;
public static final int PI = (int)(Math.PI*65536.0);
public static final int TWO_PI = (int)(2.0*Math.PI*65536.0);
public static final int PI_OVER_TWO = (int)((Math.PI/2.0)*65536.0);
public static final int SQRT_TWO = (int)(Math.sqrt(2.0)*65536.0);
static {
sintab = new int[SINTAB_ENTRIES + 1];
for (int i = 0; i < SINTAB_ENTRIES + 1; i++) {
double theta = i*(Math.PI/2.0)/SINTAB_ENTRIES;
sintab[i] = (int)(Math.sin(theta)*65536.0);
}
}
public static int sin(int theta) {
int sign = 1;
if (theta < 0) {
theta = -theta;
sign = -1;
}
// 0 <= theta
while (theta >= TWO_PI) {
theta -= TWO_PI;
}
// 0 <= theta < 2*PI
if (theta >= PI) {
theta = TWO_PI - theta;
sign = -sign;
}
// 0 <= theta < PI
if (theta > PI_OVER_TWO) {
theta = PI - theta;
}
// 0 <= theta <= PI/2
int itheta = (int)((long)theta*SINTAB_ENTRIES/(PI_OVER_TWO));
return sign*sintab[itheta];
}
public static int cos(int theta) {
return sin(PI_OVER_TWO - theta);
}
// public static double sqrt(double x) {
// double dsqrt = Math.sqrt(x);
// int ix = (int)(x*65536.0);
// Int Isqrt = Isqrt(Ix);
// Long Lx = (Long)(X*65536.0);
// Long Lsqrt = Lsqrt(Lx);
// System.Out.Println();
// System.Out.Println("X = " + X);
// System.Out.Println("Dsqrt = " + Dsqrt);
// System.Out.Println("Ix = " + Ix);
// System.Out.Println("Isqrt = " + Isqrt/65536.0);
// System.Out.Println("Lx = " + Lx);
// System.Out.Println("Lsqrt = " + Lsqrt/65536.0);
// Return Dsqrt;
// }
// From Ken Turkowski, _Fixed-Point Square Root_, In Graphics Gems V
public static int isqrt(int x) {
int fracbits = 16;
int root = 0;
int remHi = 0;
int remLo = x;
int count = 15 + fracbits/2;
do {
remHi = (remHi << 2) | (remLo >>> 30); // N.B. - unsigned shift R
remLo <<= 2;
root <<= 1;
int testdiv = (root << 1) + 1;
if (remHi >= testdiv) {
remHi -= testdiv;
root++;
}
} while (count-- != 0);
return root;
}
public static long lsqrt(long x) {
int fracbits = 16;
long root = 0;
long remHi = 0;
long remLo = x;
int count = 31 + fracbits/2;
do {
remHi = (remHi << 2) | (remLo >>> 62); // N.B. - unsigned shift R
remLo <<= 2;
root <<= 1;
long testDiv = (root << 1) + 1;
if (remHi >= testDiv) {
remHi -= testDiv;
root++;
}
} while (count-- != 0);
return root;
}
public static double hypot(double x, double y) {
// new RuntimeException().printStackTrace();
return Math.sqrt(x*x + y*y);
}
public static int hypot(int x, int y) {
return (int)((lsqrt((long)x*x + (long)y*y) + 128) >> 8);
}
public static long hypot(long x, long y) {
return (lsqrt(x*x + y*y) + 128) >> 8;
}
}