Worldwind public release 0.2
[worldwind-tracker.git] / gov / nasa / worldwind / geom / Point.java
blob71fe6feb4164f54822bedb75cf1d6f528e90072e
1 /*
2 Copyright (C) 2001, 2006 United States Government
3 as represented by the Administrator of the
4 National Aeronautics and Space Administration.
5 All Rights Reserved.
6 */
7 package gov.nasa.worldwind.geom;
9 import gov.nasa.worldwind.*;
11 /**
12 * <code>Point</code> represents an homogeneous cartesian point in 3 dimensional space.
13 * <p/>
14 * Instances of <code>Point</code> are immutable. </p>
16 * @author Tom Gaskins
17 * @version $Id: Point.java 1750 2007-05-06 19:53:06Z tgaskins $
19 public class Point implements gov.nasa.worldwind.Cacheable
21 private final double x;
22 private final double y;
23 private final double z;
24 private final double w;
26 /**
27 * Value of <code>ZERO</code> is (0,0,0)
29 public static final Point ZERO = new Point(0, 0, 0);
30 /**
31 * Value of <code>UNIT_X</code> is (1,0,0)
33 public static final Point UNIT_X = new Point(1, 0, 0);
34 /**
35 * Value of <code>UNIT_Y</code> is (0,1,0)
37 public static final Point UNIT_Y = new Point(0, 1, 0);
38 /**
39 * Value of <code>UNIT_Z</code> is (0,0,1)
41 public static final Point UNIT_Z = new Point(0, 0, 1);
43 /**
44 * Constructs a new <code>Point</code> from four parameters.
46 * @param x the x position of the <code>Point</code>
47 * @param y the y position of the <code>Point</code>
48 * @param z the z position of the <code>Point</code>
49 * @param w the w position of the <code>Point</code>
51 public Point(double x, double y, double z, double w)
53 this.x = x;
54 this.y = y;
55 this.z = z;
56 this.w = w;
59 /**
60 * Constructs a new <code>Point</code> from three parameters. The <code>w</code> field is set to 1.
62 * @param x the x position of the <code>Point</code>
63 * @param y the y position of the <code>Point</code>
64 * @param z the z position of the <code>Point</code>
66 public Point(double x, double y, double z)
68 this.x = x;
69 this.y = y;
70 this.z = z;
71 this.w = 1;
74 /**
75 * Returns the w element of this Point. This method differs from <code>w()</code> in that subclasses may override
76 * it.
78 * @return the w element of this <code>Point</code>
79 * @see Point#w()
81 public double getW()
83 return w;
86 /**
87 * Returns the x element of this Point. This method differs from <code>x()</code> in that subclasses may override
88 * it.
90 * @return the x element of this <code>Point</code>
91 * @see Point#x()
93 public double getX()
95 return x;
98 /**
99 * Returns the y element of this Point. This method differs from <code>y()</code> in that subclasses may override
100 * it.
102 * @return the y element of this <code>Point</code>
103 * @see Point#y()
105 public double getY()
107 return y;
111 * Returns the y element of this Point. This method differs from <code>y()</code> in that subclasses may override
112 * it.
114 * @return the y element of this <code>Point</code>
115 * @see Point#z()
117 public double getZ()
119 return z;
123 * Returns the x element of this <code>Point</code>.
125 * @return the x element of this <code>Point</code>
127 public final double x()
129 return this.x;
133 * Returns the y element of this <code>Point</code>.
135 * @return the y element of this <code>Point</code>
137 public final double y()
139 return this.y;
143 * Returns the z element of this <code>Point</code>.
145 * @return the z element of this <code>Point</code>
147 public final double z()
149 return this.z;
153 * Returns the w element of this <code>Point</code>.
155 * @return the w element of this <code>Point</code>
157 public final double w()
159 return this.w;
163 * Calculates the sum of these two <code>Point</code>s. The resulting <code>Point</code> has x value equivalent to
164 * <code>this.x + p.x</code>, the results for y,z and w are calculated in the same way.
166 * @param p the <code>Point</code> to be added to this <code>Point</code>
167 * @return a <code>Point</code> resulting from the algebraic operation <code>this + p</code>
168 * @throws IllegalArgumentException if <code>p</code> is null
170 public final Point add(Point p)
172 if (p == null)
174 String message = WorldWind.retrieveErrMsg("nullValue.PointIsNull");
175 WorldWind.logger().log(java.util.logging.Level.FINE, message);
176 throw new IllegalArgumentException(message);
179 return new Point(this.x + p.x, this.y + p.y, this.z + p.z, 1);
183 * Calculates the difference between these two <code>Point</code>s. The resulting <code>Point</code> is equivalent
184 * to <code>this.x - p.x</code>, the results for y, z and w are calculated in the same way.
186 * @param p the <code>Point</code> to subtract from this <code>Point</code>
187 * @return a <code>Point</code> resulting from the algebraic operation<code>this - p</code>
188 * @throws IllegalArgumentException if <code>p</code> is null
190 public final Point subtract(Point p)
192 if (p == null)
194 String message = WorldWind.retrieveErrMsg("nullValue.PointIsNull");
195 WorldWind.logger().log(java.util.logging.Level.FINE, message);
196 throw new IllegalArgumentException(message);
199 return new Point(this.x - p.x, this.y - p.y, this.z - p.z, 1);
203 * Multiplies this <code>Point</code> by a scalar quantity. This method simply returns a new <code>Point</code>
204 * whose values each equal the old <code>Point</code>'s corresponding value multiplied by this scalar.
206 * @param s the scalar to be multiplied by
207 * @return a <code>Point</code> resulting from the scalar multiplication of <code>this</code> and <code>s</code>
209 public final Point multiply(double s)
211 return new Point(this.x * s, this.y * s, this.z * s, 1);
214 public final Point scale(double sx, double sy, double sz)
216 return new Point(this.x * sx, this.y * sy, this.z * sz, this.w);
219 public final Point normalize()
221 double s = 1d / this.length();
222 return this.scale(s, s, s);
226 * Performs a dot product of the x, y and z coorinates of <code>this</code> and <code>p</code>.
228 * @param p the <code>Point</code> to perform a dot product with
229 * @return the scalar product of <code>this</code> and <code>p</code>
230 * @throws IllegalArgumentException if <code>p</code> is null
232 public final double dot(Point p)
234 if (p == null)
236 String message = WorldWind.retrieveErrMsg("nullValue.PointIsNull");
237 WorldWind.logger().log(java.util.logging.Level.FINE, message);
238 throw new IllegalArgumentException(message);
241 return this.x * p.x + this.y * p.y + this.z * p.z;
245 * Performs a dot product of the x, y and z coorinates of <code>this</code> with itself. This method is equivalent
246 * to <code>this.dot(this)</code>.
247 * <p/>
248 * <p/>
249 * A useful characteristic of this method is that the resulting value is the square of this <code>Point</code>'s
250 * distance from <code>ZERO</code>. Finding the square of the distance from the origin in this manner is preferred
251 * over finding the square by first finding the length and then squaring it because this is faster and less prone to
252 * loss of precision. </p>
254 * @return this <code>Point</code> dotted with itself
255 * @see Point#ZERO
257 public final double selfDot()
259 return this.x * this.x + this.y * this.y + this.z * this.z;
263 * Performs a dot product of all four components of <code>this</code> and <code>p</code>.
265 * @param p the <code>Point</code> to perform a dot product with
266 * @return the scalar product of <code>this</code> and <code>p</code>
267 * @throws IllegalArgumentException if <code>p</code> is null
269 public final double dot4(Point p)
271 if (p == null)
273 String message = WorldWind.retrieveErrMsg("nullValue.PointIsNull");
274 WorldWind.logger().log(java.util.logging.Level.FINE, message);
275 throw new IllegalArgumentException(message);
278 return this.x * p.x + this.y * p.y + this.z * p.z + this.w * this.w;
282 * Calculates the distance between this <code>Point</code> and the origin.
284 * @return the distance between this <code>Point</code> and <code>ZERO</code>
285 * @see Point#ZERO
287 public final double length()
289 return Math.sqrt(this.selfDot());
293 * Calculates the unsigned distance between this <code>Point</code> and <code>p</code>.
295 * @param p the <code>Point</code> to find the distance from
296 * @return the distance between these two <code>Point</code>s
297 * @throws IllegalArgumentException if <code>p</code> is null
299 public final double distanceTo(Point p)
301 if (p == null)
303 String message = WorldWind.retrieveErrMsg("nullValue.PointIsNull");
304 WorldWind.logger().log(java.util.logging.Level.FINE, message);
305 throw new IllegalArgumentException(message);
308 double dx = this.x - p.x;
309 double dy = this.y - p.y;
310 double dz = this.z - p.z;
311 return Math.sqrt(dx * dx + dy * dy + dz * dz);
315 * Calculates the squared unsigned distance between this <code>Point</code> and <code>p</code>. This method is
316 * useful when actual distances are not required, but some measure is needed for comparison purposes. It avoids the
317 * square root required for computing actual distance.
319 * @param p the <code>Point</code> to find the square distance from
320 * @return the square of the distance between these two <code>Point</code>s
321 * @throws IllegalArgumentException if <code>p</code> is null
323 public final double distanceToSquared(Point p)
325 if (p == null)
327 String message = WorldWind.retrieveErrMsg("nullValue.PointIsNull");
328 WorldWind.logger().log(java.util.logging.Level.FINE, message);
329 throw new IllegalArgumentException(message);
331 double dx = this.x - p.x;
332 double dy = this.y - p.y;
333 double dz = this.z - p.z;
334 return (dx * dx + dy * dy + dz * dz);
338 * Determines the midpoint of two <code>Point</code>s.
340 * @param p1 the first <code>Point</code>
341 * @param p2 the second <code>Point</code>
342 * @return the midpoint of these two <code>Point</code>s
343 * @throws IllegalArgumentException if either <code>p1</code> or <code>p2</code> is null
345 public static Point midPoint(Point p1, Point p2)
347 if (p1 == null || p2 == null)
349 String message = WorldWind.retrieveErrMsg("nullValue.PointIsNull");
350 WorldWind.logger().log(java.util.logging.Level.FINE, message);
351 throw new IllegalArgumentException(message);
354 return new Point(0.5 * (p1.x + p2.x), 0.5 * (p1.y + p2.y), 0.5 * (p1.z + p2.z));
358 * Scales a <code>Point</code> along a vector. The resulting <code>Point</code> is affected by both the scale factor
359 * and the size of the vector direction. For example, a vector (2,2,2) and a vector (1,1,1) would produce a
360 * different result, if all other variables remain constant. For this reason, programmers may wish to normalize
361 * <code>direction</code> before calling this function.
363 * @param scale the factor to be scaled by
364 * @param direction the direction of scaling
365 * @param origin the original <code>Point</code>
366 * @return <code>origin</code> scaled by <code>scale</code> in the direction specified
367 * @throws IllegalArgumentException if <code>direction</code> or <code>origin</code> is null
369 public static Point fromOriginAndDirection(double scale, Point direction, Point origin)
371 if (direction == null)
373 String message = WorldWind.retrieveErrMsg("nullValue.DirectionIsNull");
374 WorldWind.logger().log(java.util.logging.Level.FINE, message);
375 throw new IllegalArgumentException(message);
378 if (origin == null)
380 String message = WorldWind.retrieveErrMsg("nullValue.OriginIsNull");
381 WorldWind.logger().log(java.util.logging.Level.FINE, message);
382 throw new IllegalArgumentException(message);
385 double x = scale * direction.x() + origin.x;
386 double y = scale * direction.y() + origin.y;
387 double z = scale * direction.z() + origin.z;
389 return new Point(x, y, z);
393 * Calculate the extrema of a given array of <code>Point</code>s. The resulting array is always of length 2, with
394 * the first element containing the minimum extremum, and the second containing the maximum. The minimum extremum is
395 * composed by taking the smallest x, y and z values from all the <code>Point</code>s in the array. These values are
396 * not necessarily taken from the same <code>Point</code>. The maximum extrema is composed in the same fashion.
398 * @param points any array of <code>Point</code>s
399 * @return a array with length of 2, comprising the most extreme values in the given array
400 * @throws IllegalArgumentException if <code>points</code> is null
402 public static Point[] composeExtrema(Point points[])
404 if (points == null)
406 String message = WorldWind.retrieveErrMsg("nullValue.PointsArrayIsNull");
407 WorldWind.logger().log(java.util.logging.Level.FINE, message);
408 throw new IllegalArgumentException(message);
411 if (points.length == 0)
412 return new Point[] {Point.ZERO, Point.ZERO};
414 double xmin = points[0].x;
415 double ymin = points[0].y;
416 double zmin = points[0].z;
417 double xmax = xmin;
418 double ymax = ymin;
419 double zmax = zmin;
421 for (int i = 1; i < points.length; i++)
423 double x = points[i].x;
424 if (x > xmax)
426 xmax = x;
428 else if (x < xmin)
430 xmin = x;
433 double y = points[i].y;
434 if (y > ymax)
436 ymax = y;
438 else if (y < ymin)
440 ymin = y;
443 double z = points[i].z;
444 if (z > zmax)
446 zmax = z;
448 else if (z < zmin)
450 zmin = z;
454 return new Point[] {new Point(xmin, ymin, zmin), new Point(xmax, ymax, zmax)};
458 * Determines the cross product of these two <code>Point</code>s. This is post multiplied by that.
460 * @param that the second <code>Point</code>
461 * @return the cross product of two <code>Point</code>s
462 * @throws IllegalArgumentException if <code>that</code> is null
464 public Point cross(Point that)
466 if (that == null)
468 String msg = WorldWind.retrieveErrMsg("nullValue.PointIsNull");
469 WorldWind.logger().log(java.util.logging.Level.FINE, msg);
470 throw new IllegalArgumentException(msg);
472 return new Point(this.y * that.z - this.z * that.y, this.z * that.x - this.x * that.z,
473 this.x * that.y - this.y * that.x);
477 * Compares this <code>Point</code> to <code>o</code> for equality.
478 * <p/>
479 * This method makes comparisons on private fields; overriding implementations should include a call to
480 * <code>super.equals()</code>.
482 * @param o the <code>Object</code> to be compared to for equality.
483 * @return true if the contents are equal, false otherwise
485 @Override
486 public boolean equals(Object o)
488 if (this == o)
489 return true;
490 if (o == null || getClass() != o.getClass())
491 return false;
493 final gov.nasa.worldwind.geom.Point point = (gov.nasa.worldwind.geom.Point) o;
495 if (Double.compare(point.w, w) != 0)
496 return false;
497 if (Double.compare(point.x, x) != 0)
498 return false;
499 if (Double.compare(point.y, y) != 0)
500 return false;
501 //noinspection RedundantIfStatement
502 if (Double.compare(point.z, z) != 0)
503 return false;
505 return true;
509 * Generates an integer that is always the same for identical objects, but usually different for different objects.
510 * This method overrides the one in <code>Object</code>.
511 * <p/>
512 * This method makes comparisons on private fields; overriding implementations should include a call to
513 * <code>super.hashCode()</code>.
515 * @return the hashCode for this <code>Point</code>.
517 @Override
518 public int hashCode()
520 int result;
521 long temp;
522 temp = x != +0.0d ? Double.doubleToLongBits(x) : 0L;
523 result = (int) (temp ^ (temp >>> 32));
524 temp = y != +0.0d ? Double.doubleToLongBits(y) : 0L;
525 result = 29 * result + (int) (temp ^ (temp >>> 32));
526 temp = z != +0.0d ? Double.doubleToLongBits(z) : 0L;
527 result = 29 * result + (int) (temp ^ (temp >>> 32));
528 temp = w != +0.0d ? Double.doubleToLongBits(w) : 0L;
529 result = 29 * result + (int) (temp ^ (temp >>> 32));
530 return result;
534 * Generates a string representation of this object. The returned string has the format "(x, y, z, w)" where x, y, z
535 * and w correspond to their respective values in this <code>Point</code>.
537 * @return a string representation of this <code>Point</code>
539 @Override
540 public final String toString()
542 return "(" + Double.toString(this.x) + ", " + Double.toString(this.y) + ", " + Double.toString(this.z) + ", "
543 + Double.toString(this.w) + ")";
547 * Obtains the amount of memory this <code>Point</code> consumes.
549 * @return the memory footprint of this <code>Point</code> in bytes.
551 public final long getSizeInBytes()
553 // we could consider using a constant value here
554 return Double.SIZE << 2;