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