001package arcommon;
002
003import java.util.Random;
004
005public class MathUtil {
006    public static void setSeed(long seed) {
007        if (random == null) {
008            random = new Random(seed);
009        } else {
010            random.setSeed(seed);
011        }
012    }
013    
014    public static void randomize() {
015        random = new Random();
016    }
017    
018    private static Random random;
019
020    public static int randomNumber(int maximumValueNotIncluded) {
021        double number;
022        if (random == null) {
023            number = Math.random();
024        } else {
025            number = random.nextDouble();
026        }
027        number = number * maximumValueNotIncluded;
028        int result = ((int)number) % maximumValueNotIncluded;
029        return result;
030    }
031    
032    public static String randomString(int length, String symbols) {
033        if (length <= 0) {
034            throw new RuntimeException("length <= 0  " + length);
035        }
036        if (symbols == null) {
037            throw new RuntimeException("symbols == null");
038        }
039        if (symbols.length() < 2) {
040            throw new RuntimeException("symbols.length() < 2 \"" + symbols + "\"");
041        }
042        StringBuilder stringBuilder = new StringBuilder();
043        for (int i = 0; i < length; i++) {
044            int randomNumber = randomNumber(symbols.length());
045            stringBuilder.append(symbols.charAt(randomNumber));
046        }
047        return stringBuilder.toString();
048    }
049    
050    public static int log10(long number) {
051        return logN(number, 10);
052    }
053    
054    public static int log2(long number) {
055        return logN(number, 2);
056    }
057
058    public static int logN(long number, long log) {
059        int result = 0;
060        while (number > 0) {
061            number /= log;
062            result++;
063        }
064        return result;
065    }
066    
067    /**
068     * Returns the signum function of the argument.
069     * <br>
070     * Return zero if the argument is zero, 1 if the argument is greater than zero, -1 if the argument is less than zero.
071     * @see java.lang.Math#signum(double) see java.lang.Math.signum(doable) for a double variant
072     * @see java.lang.Math#signum(float) see java.lang.Math.signum(float) for a float variant
073     */
074    public static int signum(long number) {
075        if (number > 0) {
076            return 1;
077        }
078        if (number < 0) {
079            return -1;
080        }
081        return 0;
082    }
083    
084    public static double xyToAngle(int diffX, int diffY) {
085        double v = 0;
086        if (diffX != 0) {
087            v = Math.atan((double)diffY / diffX);
088        }
089        
090        if (v < 0) {
091            if (signum(diffX) < 0 && signum(diffY) > 0) {
092                v += Math.PI;
093            } else {
094                if (signum(diffX) > 0 && signum(diffY) < 0) {
095                    ;
096                } else {
097                    throw new RuntimeException("v < 0, diffX: " + diffX + ", diffY: " + diffY);
098                }
099            }
100        } else if (v > 0) {
101            if (signum(diffX) > 0 && signum(diffY) > 0) {
102                ;
103            } else {
104                if (signum(diffX) < 0 && signum(diffY) < 0) {
105                    v += Math.PI;
106                } else {
107                    throw new RuntimeException("v > 0, diffX: " + diffX + ", diffY: " + diffY);
108                }
109            }
110        } else if (v == 0) {
111            if (signum(diffX) == 0) {
112                if (signum(diffY) < 0) {
113                    v += Math.PI * 3 / 2;
114                } else {
115                    v += Math.PI / 2;
116                }
117            } else {
118                if (signum(diffX) < 0) {
119                    v += Math.PI;
120                } else {
121                    ;
122                }
123            }
124        }
125        return v;
126    }
127
128    public static double xyToLength(int x, int y) {
129        return Math.sqrt(x * x + y * y);
130    }
131    
132    public static double xyDiffToLength(int x1, int y1, int x2, int y2) {
133        int x = Math.abs(x1 - x2);
134        int y = Math.abs(y1 - y2);
135        return Math.sqrt(x * x + y * y);
136    }
137    
138    public static double degreesToRadians(double angle) {
139        return 2 * Math.PI - angle * 2 * Math.PI / 360;
140    }
141
142    public static double radiansToDegrees(double radians) {
143        return ((2 * Math.PI - radians) * 360 / (2 * Math.PI) + 360) % 360;
144    }
145}