Fork of Poseidon providing Bukkit #1060 to older Beta versions (b1.0-b1.7.3)
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}