FileDocCategorySizeDatePackage
PiscesMath.javaAPI DocphoneME MR2 API (J2ME)4623Wed May 02 18:00:36 BST 2007com.sun.pisces

PiscesMath.java

/*
 * 
 * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved. 
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER 
 *  
 * This program 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. 
 *  
 * This program 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 at /legal/license.txt). 
 *  
 * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa 
 * Clara, CA 95054 or visit www.sun.com if you need additional 
 * information or have any questions.
 */


package com.sun.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;
    }
}