001/*
002 * PlotSquared, a land and world management plugin for Minecraft.
003 * Copyright (C) IntellectualSites <https://intellectualsites.com>
004 * Copyright (C) IntellectualSites team and contributors
005 *
006 * This program is free software: you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation, either version 3 of the License, or
009 * (at your option) any later version.
010 *
011 * This program is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014 * GNU General Public License for more details.
015 *
016 * You should have received a copy of the GNU General Public License
017 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
018 */
019package com.plotsquared.core.util;
020
021public class MathMan {
022
023    private static final int ATAN2_BITS = 7;
024    private static final int ATAN2_BITS2 = ATAN2_BITS << 1;
025    private static final int ATAN2_MASK = ~(-1 << ATAN2_BITS2);
026    private static final int ATAN2_COUNT = ATAN2_MASK + 1;
027    private static final int ATAN2_DIM = (int) Math.sqrt(ATAN2_COUNT);
028    private static final float INV_ATAN2_DIM_MINUS_1 = 1.0f / (ATAN2_DIM - 1);
029    private static final float[] atan2 = new float[ATAN2_COUNT];
030    private static final int[] table =
031            {0, 16, 22, 27, 32, 35, 39, 42, 45, 48, 50, 53, 55, 57, 59, 61, 64, 65, 67, 69, 71, 73, 75,
032                    76, 78, 80, 81, 83, 84, 86, 87, 89, 90, 91, 93, 94, 96, 97, 98, 99, 101, 102, 103, 104,
033                    106, 107, 108, 109, 110, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123,
034                    124, 125, 126, 128, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140,
035                    141, 142, 143, 144, 144, 145, 146, 147, 148, 149, 150, 150, 151, 152, 153, 154, 155,
036                    155, 156, 157, 158, 159, 160, 160, 161, 162, 163, 163, 164, 165, 166, 167, 167, 168,
037                    169, 170, 170, 171, 172, 173, 173, 174, 175, 176, 176, 177, 178, 178, 179, 180, 181,
038                    181, 182, 183, 183, 184, 185, 185, 186, 187, 187, 188, 189, 189, 190, 191, 192, 192,
039                    193, 193, 194, 195, 195, 196, 197, 197, 198, 199, 199, 200, 201, 201, 202, 203, 203,
040                    204, 204, 205, 206, 206, 207, 208, 208, 209, 209, 210, 211, 211, 212, 212, 213, 214,
041                    214, 215, 215, 216, 217, 217, 218, 218, 219, 219, 220, 221, 221, 222, 222, 223, 224,
042                    224, 225, 225, 226, 226, 227, 227, 228, 229, 229, 230, 230, 231, 231, 232, 232, 233,
043                    234, 234, 235, 235, 236, 236, 237, 237, 238, 238, 239, 240, 240, 241, 241, 242, 242,
044                    243, 243, 244, 244, 245, 245, 246, 246, 247, 247, 248, 248, 249, 249, 250, 250, 251,
045                    251, 252, 252, 253, 253, 254, 254, 255};
046
047    static {
048        for (int i = 0; i < ATAN2_DIM; i++) {
049            for (int j = 0; j < ATAN2_DIM; j++) {
050                float x0 = (float) i / ATAN2_DIM;
051                float y0 = (float) j / ATAN2_DIM;
052
053                atan2[(j * ATAN2_DIM) + i] = (float) Math.atan2(y0, x0);
054            }
055        }
056    }
057
058    public static final int gcd(int a, int b) {
059        if (b == 0) {
060            return a;
061        }
062        return gcd(b, a % b);
063    }
064
065    public static final int gcd(int[] a) {
066        int result = a[0];
067        for (int i = 1; i < a.length; i++) {
068            result = gcd(result, a[i]);
069        }
070        return result;
071    }
072
073    /**
074     * @deprecated Unused internally. Scheduled for removal in next major release.
075     */
076    @Deprecated(forRemoval = true, since = "6.11.1")
077    public static long pairInt(int x, int y) {
078        return (((long) x) << 32) | (y & 0xffffffffL);
079    }
080
081    /**
082     * @deprecated Unused internally. Scheduled for removal in next major release.
083     */
084    @Deprecated(forRemoval = true, since = "6.11.1")
085    public static int unpairIntX(long pair) {
086        return (int) (pair >> 32);
087    }
088
089    /**
090     * @deprecated Unused internally. Scheduled for removal in next major release.
091     */
092    @Deprecated(forRemoval = true, since = "6.11.1")
093    public static int unpairIntY(long pair) {
094        return (int) pair;
095    }
096
097    /**
098     * @deprecated Unused internally. Scheduled for removal in next major release.
099     */
100    @Deprecated(forRemoval = true, since = "6.11.1")
101    public static byte pair16(byte x, byte y) {
102        return (byte) (x + (y << 4));
103    }
104
105    /**
106     * @deprecated Unused internally. Scheduled for removal in next major release.
107     */
108    @Deprecated(forRemoval = true, since = "6.11.1")
109    public static byte unpair16x(byte value) {
110        return (byte) (value & 0xF);
111    }
112
113    /**
114     * @deprecated Unused internally. Scheduled for removal in next major release.
115     */
116    @Deprecated(forRemoval = true, since = "6.11.1")
117    public static byte unpair16y(byte value) {
118        return (byte) ((value >> 4) & 0xF);
119    }
120
121    /**
122     * @deprecated Unused internally. Scheduled for removal in next major release.
123     */
124    @Deprecated(forRemoval = true, since = "6.11.1")
125    public static long inverseRound(double val) {
126        long round = Math.round(val);
127        return (long) (round + Math.signum(val - round));
128    }
129
130    /**
131     * @deprecated Unused internally. Scheduled for removal in next major release.
132     */
133    @Deprecated(forRemoval = true, since = "6.11.1")
134    public static int sqrt(int x) {
135        int xn;
136
137        if (x >= 0x10000) {
138            if (x >= 0x1000000) {
139                if (x >= 0x10000000) {
140                    if (x >= 0x40000000) {
141                        xn = table[x >> 24] << 8;
142                    } else {
143                        xn = table[x >> 22] << 7;
144                    }
145                } else {
146                    if (x >= 0x4000000) {
147                        xn = table[x >> 20] << 6;
148                    } else {
149                        xn = table[x >> 18] << 5;
150                    }
151                }
152
153                xn = (xn + 1 + (x / xn)) >> 1;
154                xn = (xn + 1 + (x / xn)) >> 1;
155                return ((xn * xn) > x) ? --xn : xn;
156            } else {
157                if (x >= 0x100000) {
158                    if (x >= 0x400000) {
159                        xn = table[x >> 16] << 4;
160                    } else {
161                        xn = table[x >> 14] << 3;
162                    }
163                } else {
164                    if (x >= 0x40000) {
165                        xn = table[x >> 12] << 2;
166                    } else {
167                        xn = table[x >> 10] << 1;
168                    }
169                }
170
171                xn = (xn + 1 + (x / xn)) >> 1;
172
173                return ((xn * xn) > x) ? --xn : xn;
174            }
175        } else {
176            if (x >= 0x100) {
177                if (x >= 0x1000) {
178                    if (x >= 0x4000) {
179                        xn = (table[x >> 8]) + 1;
180                    } else {
181                        xn = (table[x >> 6] >> 1) + 1;
182                    }
183                } else {
184                    if (x >= 0x400) {
185                        xn = (table[x >> 4] >> 2) + 1;
186                    } else {
187                        xn = (table[x >> 2] >> 3) + 1;
188                    }
189                }
190
191                return ((xn * xn) > x) ? --xn : xn;
192            } else {
193                if (x >= 0) {
194                    return table[x] >> 4;
195                }
196            }
197        }
198        throw new IllegalArgumentException("Invalid number:" + x);
199    }
200
201
202    public static double getMean(int[] array) {
203        double count = 0;
204        for (int i : array) {
205            count += i;
206        }
207        return count / array.length;
208    }
209
210    /**
211     * @deprecated Unused internally. Scheduled for removal in next major release.
212     */
213    @Deprecated(forRemoval = true, since = "6.11.1")
214    public static double getMean(double[] array) {
215        double count = 0;
216        for (double i : array) {
217            count += i;
218        }
219        return count / array.length;
220    }
221
222    public static int pair(short x, short y) {
223        return (x << 16) | (y & 0xFFFF);
224    }
225
226    public static final int average(int a, int b) {
227        return (a & b) + (a ^ b) / 2;
228    }
229
230
231    /**
232     * @deprecated Unused internally. Scheduled for removal in next major release.
233     */
234    @Deprecated(forRemoval = true, since = "6.11.1")
235    public static short unpairX(int hash) {
236        return (short) (hash >> 16);
237    }
238
239    /**
240     * @deprecated Unused internally. Scheduled for removal in next major release.
241     */
242    @Deprecated(forRemoval = true, since = "6.11.1")
243    public static short unpairY(int hash) {
244        return (short) (hash & 0xFFFF);
245    }
246
247    /**
248     * get the x,y,z unit vector from pitch and yaw specified
249     *
250     * @param yaw   yaw
251     * @param pitch pitch
252     * @return x, y, z unit vector
253     * @deprecated Unused internally. Scheduled for removal in next major release.
254     */
255    @Deprecated(forRemoval = true, since = "6.11.1")
256    public static float[] getDirection(float yaw, float pitch) {
257        double pitch_sin = Math.sin(pitch);
258        return new float[]{(float) (pitch_sin * Math.cos(yaw)),
259                (float) (pitch_sin * Math.sin(yaw)), (float) Math.cos(pitch)};
260    }
261
262    /**
263     * @deprecated Unused internally. Scheduled for removal in next major release.
264     */
265    @Deprecated(forRemoval = true, since = "6.11.1")
266    public static int floorMod(int x, int y) {
267        int i = x % y;
268        if (i < 0) {
269            i += y;
270        }
271        return i;
272    }
273
274    public static int roundInt(double value) {
275        return (int) (value < 0 ? (value == (int) value) ? value : value - 1 : value);
276    }
277
278    /**
279     * Returns [ pitch, yaw ]
280     *
281     * @param x x
282     * @param y y
283     * @param z z
284     * @return pitch and yaw of x,y,z from 0,0,0
285     * @deprecated Unused internally. Scheduled for removal in next major release.
286     */
287    @Deprecated(forRemoval = true, since = "6.11.1")
288    public static float[] getPitchAndYaw(float x, float y, float z) {
289        float distance = sqrtApprox((z * z) + (x * x));
290        return new float[]{atan2(y, distance), atan2(x, z)};
291    }
292
293    /**
294     * @deprecated Unused internally. Scheduled for removal in next major release.
295     */
296    @Deprecated(forRemoval = true, since = "6.11.1")
297    public static final float atan2(float y, float x) {
298        float add;
299        float mul;
300
301        if (x < 0.0f) {
302            if (y < 0.0f) {
303                x = -x;
304                y = -y;
305
306                mul = 1.0f;
307            } else {
308                x = -x;
309                mul = -1.0f;
310            }
311
312            add = -3.141592653f;
313        } else {
314            if (y < 0.0f) {
315                y = -y;
316                mul = -1.0f;
317            } else {
318                mul = 1.0f;
319            }
320
321            add = 0.0f;
322        }
323
324        float invDiv = 1.0f / (((x < y) ? y : x) * INV_ATAN2_DIM_MINUS_1);
325
326        int xi = (int) (x * invDiv);
327        int yi = (int) (y * invDiv);
328
329        return (atan2[(yi * ATAN2_DIM) + xi] + add) * mul;
330    }
331
332    /**
333     * @deprecated Unused internally. Scheduled for removal in next major release.
334     */
335    @Deprecated(forRemoval = true, since = "6.11.1")
336    public static float sqrtApprox(float f) {
337        return f * Float.intBitsToFloat(0x5f375a86 - (Float.floatToIntBits(f) >> 1));
338    }
339
340
341    /**
342     * @deprecated Unused internally. Scheduled for removal in next major release.
343     */
344    @Deprecated(forRemoval = true, since = "6.11.1")
345    public static double sqrtApprox(double d) {
346        return Double
347                .longBitsToDouble(((Double.doubleToLongBits(d) - (1L << 52)) >> 1) + (1L << 61));
348    }
349
350    /**
351     * @deprecated Unused internally. Scheduled for removal in next major release.
352     */
353    @Deprecated(forRemoval = true, since = "6.11.1")
354    public static float invSqrt(float x) {
355        float xhalf = 0.5f * x;
356        int i = Float.floatToIntBits(x);
357        i = 0x5f3759df - (i >> 1);
358        x = Float.intBitsToFloat(i);
359        x = x * (1.5f - (xhalf * x * x));
360        return x;
361    }
362
363    public static int getPositiveId(int i) {
364        if (i < 0) {
365            return (-i * 2) - 1;
366        }
367        return i * 2;
368    }
369
370    public static boolean isInteger(String str) {
371        if (str == null) {
372            return false;
373        }
374        int length = str.length();
375        if (length == 0) {
376            return false;
377        }
378        int i = 0;
379        if (str.charAt(0) == '-') {
380            if (length == 1) {
381                return false;
382            }
383            i = 1;
384        }
385        for (; i < length; i++) {
386            char c = str.charAt(i);
387            if ((c <= '/') || (c >= ':')) {
388                return false;
389            }
390        }
391        return true;
392    }
393
394    /**
395     * @deprecated Unused internally. Scheduled for removal in next major release.
396     */
397    @Deprecated(forRemoval = true, since = "6.11.1")
398    public static double getSD(double[] array, double av) {
399        double sd = 0;
400        for (double element : array) {
401            sd += Math.pow(Math.abs(element - av), 2);
402        }
403        return Math.sqrt(sd / array.length);
404    }
405
406    public static double getSD(int[] array, double av) {
407        double sd = 0;
408        for (int element : array) {
409            sd += Math.pow(Math.abs(element - av), 2);
410        }
411        return Math.sqrt(sd / array.length);
412    }
413
414    /**
415     * @deprecated Unused internally. Scheduled for removal in next major release.
416     */
417    @Deprecated(forRemoval = true, since = "6.11.1")
418    public static int mod(int x, int y) {
419        if (isPowerOfTwo(y)) {
420            return x & (y - 1);
421        }
422        return x % y;
423    }
424
425    /**
426     * @deprecated Unused internally. Scheduled for removal in next major release.
427     */
428    @Deprecated(forRemoval = true, since = "6.11.1")
429    public static int unsignedmod(int x, int y) {
430        if (isPowerOfTwo(y)) {
431            return x & (y - 1);
432        }
433        return x % y;
434    }
435
436    /**
437     * @deprecated Unused internally. Scheduled for removal in next major release.
438     */
439    @Deprecated(forRemoval = true, since = "6.11.1")
440    public static boolean isPowerOfTwo(int number) {
441        return (number & (number - 1)) == 0;
442    }
443
444}