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}