Fork of Poseidon providing Bukkit #1060 to older Beta versions (b1.0-b1.7.3)
at develop 634 lines 14 kB view raw
1package org.bukkit.util; 2 3import org.bukkit.Location; 4import org.bukkit.World; 5 6import java.util.Random; 7 8/** 9 * Represents a mutable vector. Because the components of Vectors are mutable, 10 * storing Vectors long term may be dangerous if passing code modifies the 11 * Vector later. If you want to keep around a Vector, it may be wise to call 12 * <code>clone()</code> in order to get a copy. 13 * 14 * @author sk89q 15 */ 16public class Vector implements Cloneable { 17 private static final long serialVersionUID = -2657651106777219169L; 18 19 private static Random random = new Random(); 20 21 /** 22 * Threshold for fuzzy equals(). 23 */ 24 private static final double epsilon = 0.000001; 25 26 protected double x; 27 protected double y; 28 protected double z; 29 30 /** 31 * Construct the vector with all components as 0. 32 */ 33 public Vector() { 34 this.x = 0; 35 this.y = 0; 36 this.z = 0; 37 } 38 39 /** 40 * Construct the vector with provided integer components. 41 * 42 * @param x 43 * @param y 44 * @param z 45 */ 46 public Vector(int x, int y, int z) { 47 this.x = x; 48 this.y = y; 49 this.z = z; 50 } 51 52 /** 53 * Construct the vector with provided double components. 54 * 55 * @param x 56 * @param y 57 * @param z 58 */ 59 public Vector(double x, double y, double z) { 60 this.x = x; 61 this.y = y; 62 this.z = z; 63 } 64 65 /** 66 * Construct the vector with provided float components. 67 * 68 * @param x 69 * @param y 70 * @param z 71 */ 72 public Vector(float x, float y, float z) { 73 this.x = x; 74 this.y = y; 75 this.z = z; 76 } 77 78 /** 79 * Adds the vector by another. 80 * 81 * @param vec 82 * @return the same vector 83 */ 84 public Vector add(Vector vec) { 85 x += vec.x; 86 y += vec.y; 87 z += vec.z; 88 return this; 89 } 90 91 /** 92 * Subtracts the vector by another. 93 * 94 * @param vec 95 * @return the same vector 96 */ 97 public Vector subtract(Vector vec) { 98 x -= vec.x; 99 y -= vec.y; 100 z -= vec.z; 101 return this; 102 } 103 104 /** 105 * Multiplies the vector by another. 106 * 107 * @param vec 108 * @return the same vector 109 */ 110 public Vector multiply(Vector vec) { 111 x *= vec.x; 112 y *= vec.y; 113 z *= vec.z; 114 return this; 115 } 116 117 /** 118 * Divides the vector by another. 119 * 120 * @param vec 121 * @return the same vector 122 */ 123 public Vector divide(Vector vec) { 124 x /= vec.x; 125 y /= vec.y; 126 z /= vec.z; 127 return this; 128 } 129 130 /** 131 * Copies another vector 132 * 133 * @param vec 134 * @return the same vector 135 */ 136 public Vector copy(Vector vec) { 137 x = vec.x; 138 y = vec.y; 139 z = vec.z; 140 return this; 141 } 142 143 /** 144 * Gets the magnitude of the vector, defined as sqrt(x^2+y^2+z^2). The value 145 * of this method is not cached and uses a costly square-root function, so 146 * do not repeatedly call this method to get the vector's magnitude. NaN 147 * will be returned if the inner result of the sqrt() function overflows, 148 * which will be caused if the length is too long. 149 * 150 * @return the magnitude 151 */ 152 public double length() { 153 return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2)); 154 } 155 156 /** 157 * Gets the magnitude of the vector squared. 158 * 159 * @return the magnitude 160 */ 161 public double lengthSquared() { 162 return Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2); 163 } 164 165 /** 166 * Get the distance between this vector and another. The value 167 * of this method is not cached and uses a costly square-root function, so 168 * do not repeatedly call this method to get the vector's magnitude. NaN 169 * will be returned if the inner result of the sqrt() function overflows, 170 * which will be caused if the distance is too long. 171 * 172 * @return the distance 173 */ 174 public double distance(Vector o) { 175 return Math.sqrt(Math.pow(x - o.x, 2) + Math.pow(y - o.y, 2) + Math.pow(z - o.z, 2)); 176 } 177 178 /** 179 * Get the squared distance between this vector and another. 180 * 181 * @return the distance 182 */ 183 public double distanceSquared(Vector o) { 184 return Math.pow(x - o.x, 2) + Math.pow(y - o.y, 2) + Math.pow(z - o.z, 2); 185 } 186 187 /** 188 * Gets the angle between this vector and another in radians. 189 * 190 * @param other 191 * @return angle in radians 192 */ 193 public float angle(Vector other) { 194 double dot = dot(other) / (length() * other.length()); 195 196 return (float) Math.acos(dot); 197 } 198 199 /** 200 * Sets this vector to the midpoint between this vector and another. 201 * 202 * @param other 203 * @return this same vector (now a midpoint) 204 */ 205 public Vector midpoint(Vector other) { 206 x = (x + other.x) / 2; 207 y = (y + other.y) / 2; 208 z = (z + other.z) / 2; 209 return this; 210 } 211 212 /** 213 * Gets a new midpoint vector between this vector and another. 214 * 215 * @param other 216 * @return a new midpoint vector 217 */ 218 public Vector getMidpoint(Vector other) { 219 x = (x + other.x) / 2; 220 y = (y + other.y) / 2; 221 z = (z + other.z) / 2; 222 return new Vector(x, y, z); 223 } 224 225 /** 226 * Performs scalar multiplication, multiplying all components with a scalar. 227 * 228 * @param m 229 * @return the same vector 230 */ 231 public Vector multiply(int m) { 232 x *= m; 233 y *= m; 234 z *= m; 235 return this; 236 } 237 238 /** 239 * Performs scalar multiplication, multiplying all components with a scalar. 240 * 241 * @param m 242 * @return the same vector 243 */ 244 public Vector multiply(double m) { 245 x *= m; 246 y *= m; 247 z *= m; 248 return this; 249 } 250 251 /** 252 * Performs scalar multiplication, multiplying all components with a scalar. 253 * 254 * @param m 255 * @return the same vector 256 */ 257 public Vector multiply(float m) { 258 x *= m; 259 y *= m; 260 z *= m; 261 return this; 262 } 263 264 /** 265 * Calculates the dot product of this vector with another. The dot product 266 * is defined as x1*x2+y1*y2+z1*z2. The returned value is a scalar. 267 * 268 * @param other 269 * @return dot product 270 */ 271 public double dot(Vector other) { 272 return x * other.x + y * other.y + z * other.z; 273 } 274 275 /** 276 * Calculates the cross product of this vector with another. The cross 277 * product is defined as: 278 * <p> 279 * x = y1 * z2 - y2 * z1<br/> 280 * y = z1 * x2 - z2 * x1<br/> 281 * z = x1 * y2 - x2 * y1 282 * 283 * @param o 284 * @return the same vector 285 */ 286 public Vector crossProduct(Vector o) { 287 double newX = y * o.z - o.y * z; 288 double newY = z * o.x - o.z * x; 289 double newZ = x * o.y - o.x * y; 290 291 x = newX; 292 y = newY; 293 z = newZ; 294 return this; 295 } 296 297 /** 298 * Converts this vector to a unit vector (a vector with length of 1). 299 * 300 * @return the same vector 301 */ 302 public Vector normalize() { 303 double length = length(); 304 305 x /= length; 306 y /= length; 307 z /= length; 308 309 return this; 310 } 311 312 /** 313 * Zero this vector's components. 314 * 315 * @return the same vector 316 */ 317 public Vector zero() { 318 x = 0; 319 y = 0; 320 z = 0; 321 return this; 322 } 323 324 /** 325 * Returns whether this vector is in an axis-aligned bounding box. 326 * The minimum and maximum vectors given must be truly the minimum and 327 * maximum X, Y and Z components. 328 * 329 * @param min 330 * @param max 331 * @return whether this vector is in the AABB 332 */ 333 public boolean isInAABB(Vector min, Vector max) { 334 return x >= min.x && x <= max.x && y >= min.y && y <= max.y && z >= min.z && z <= max.z; 335 } 336 337 /** 338 * Returns whether this vector is within a sphere. 339 * 340 * @param origin 341 * @param radius 342 * @return whether this vector is in the sphere 343 */ 344 public boolean isInSphere(Vector origin, double radius) { 345 return (Math.pow(origin.x - x, 2) + Math.pow(origin.y - y, 2) + Math.pow(origin.z - z, 2)) <= Math.pow(radius, 2); 346 } 347 348 /** 349 * Gets the X component. 350 * 351 * @return 352 */ 353 public double getX() { 354 return x; 355 } 356 357 /** 358 * Gets the floored value of the X component, indicating the block that 359 * this vector is contained with. 360 * 361 * @return block X 362 */ 363 public int getBlockX() { 364 return (int) Math.floor(x); 365 } 366 367 /** 368 * Gets the Y component. 369 * 370 * @return 371 */ 372 public double getY() { 373 return y; 374 } 375 376 /** 377 * Gets the floored value of the Y component, indicating the block that 378 * this vector is contained with. 379 * 380 * @return block y 381 */ 382 public int getBlockY() { 383 return (int) Math.floor(y); 384 } 385 386 /** 387 * Gets the Z component. 388 * 389 * @return 390 */ 391 public double getZ() { 392 return z; 393 } 394 395 /** 396 * Gets the floored value of the Z component, indicating the block that 397 * this vector is contained with. 398 * 399 * @return block z 400 */ 401 public int getBlockZ() { 402 return (int) Math.floor(z); 403 } 404 405 /** 406 * Set the X component. 407 * 408 * @param x 409 * @return x 410 */ 411 public Vector setX(int x) { 412 this.x = x; 413 return this; 414 } 415 416 /** 417 * Set the X component. 418 * 419 * @param x 420 * @return x 421 */ 422 public Vector setX(double x) { 423 this.x = x; 424 return this; 425 } 426 427 /** 428 * Set the X component. 429 * 430 * @param x 431 * @return x 432 */ 433 public Vector setX(float x) { 434 this.x = x; 435 return this; 436 } 437 438 /** 439 * Set the Y component. 440 * 441 * @param y 442 * @return y 443 */ 444 public Vector setY(int y) { 445 this.y = y; 446 return this; 447 } 448 449 /** 450 * Set the Y component. 451 * 452 * @param y 453 * @return y 454 */ 455 public Vector setY(double y) { 456 this.y = y; 457 return this; 458 } 459 460 /** 461 * Set the Y component. 462 * 463 * @param y 464 * @return y 465 */ 466 public Vector setY(float y) { 467 this.y = y; 468 return this; 469 } 470 471 /** 472 * Set the Z component. 473 * 474 * @param z 475 * @return z 476 */ 477 public Vector setZ(int z) { 478 this.z = z; 479 return this; 480 } 481 482 /** 483 * Set the Z component. 484 * 485 * @param z 486 * @return z 487 */ 488 public Vector setZ(double z) { 489 this.z = z; 490 return this; 491 } 492 493 /** 494 * Set the Z component. 495 * 496 * @param z 497 * @return z 498 */ 499 public Vector setZ(float z) { 500 this.z = z; 501 return this; 502 } 503 504 /** 505 * Checks to see if two objects are equal. 506 * <p> 507 * Only two Vectors can ever return true. This method uses a fuzzy match 508 * to account for floating point errors. The epsilon can be retrieved 509 * with epsilon. 510 */ 511 @Override 512 public boolean equals(Object obj) { 513 if (!(obj instanceof Vector)) { 514 return false; 515 } 516 517 Vector other = (Vector) obj; 518 519 return Math.abs(x - other.x) < epsilon && Math.abs(y - other.y) < epsilon && Math.abs(z - other.z) < epsilon && (this.getClass().equals(obj.getClass())); 520 } 521 522 /** 523 * Returns a hash code for this vector 524 * 525 * @return hash code 526 */ 527 @Override 528 public int hashCode() { 529 int hash = 7; 530 531 hash = 79 * hash + (int) (Double.doubleToLongBits(this.x) ^ (Double.doubleToLongBits(this.x) >>> 32)); 532 hash = 79 * hash + (int) (Double.doubleToLongBits(this.y) ^ (Double.doubleToLongBits(this.y) >>> 32)); 533 hash = 79 * hash + (int) (Double.doubleToLongBits(this.z) ^ (Double.doubleToLongBits(this.z) >>> 32)); 534 return hash; 535 } 536 537 /** 538 * Get a new vector. 539 * 540 * @return vector 541 */ 542 @Override 543 public Vector clone() { 544 try { 545 Vector v = (Vector) super.clone(); 546 547 v.x = x; 548 v.y = y; 549 v.z = z; 550 return v; 551 } catch (CloneNotSupportedException e) { 552 e.printStackTrace(); 553 } 554 return null; 555 } 556 557 /** 558 * Returns this vector's components as x,y,z. 559 */ 560 @Override 561 public String toString() { 562 return x + "," + y + "," + z; 563 } 564 565 /** 566 * Gets a Location version of this vector with yaw and pitch being 0. 567 * 568 * @param world 569 * @return the location 570 */ 571 public Location toLocation(World world) { 572 return new Location(world, x, y, z); 573 } 574 575 /** 576 * Gets a Location version of this vector. 577 * 578 * @param world 579 * @return the location 580 */ 581 public Location toLocation(World world, float yaw, float pitch) { 582 return new Location(world, x, y, z, yaw, pitch); 583 } 584 585 /** 586 * Get the block vector of this vector. 587 * 588 * @return 589 */ 590 public BlockVector toBlockVector() { 591 return new BlockVector(x, y, z); 592 } 593 594 /** 595 * Get the threshold used for equals(). 596 * 597 * @return 598 */ 599 public static double getEpsilon() { 600 return epsilon; 601 } 602 603 /** 604 * Gets the minimum components of two vectors. 605 * 606 * @param v1 607 * @param v2 608 * @return minimum 609 */ 610 public static Vector getMinimum(Vector v1, Vector v2) { 611 return new Vector(Math.min(v1.x, v2.x), Math.min(v1.y, v2.y), Math.min(v1.z, v2.z)); 612 } 613 614 /** 615 * Gets the maximum components of two vectors. 616 * 617 * @param v1 618 * @param v2 619 * @return maximum 620 */ 621 public static Vector getMaximum(Vector v1, Vector v2) { 622 return new Vector(Math.max(v1.x, v2.x), Math.max(v1.y, v2.y), Math.max(v1.z, v2.z)); 623 } 624 625 /** 626 * Gets a random vector with components having a random value between 627 * 0 and 1. 628 * 629 * @return 630 */ 631 public static Vector getRandom() { 632 return new Vector(random.nextDouble(), random.nextDouble(), random.nextDouble()); 633 } 634}