Spec-Zone .ru
спецификации, руководства, описания, API
001/*
002 * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.  Oracle designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Oracle in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
022 * or visit www.oracle.com if you need additional information or have any
023 * questions.
024 */
025
026package javafx.geometry;
027
028// PENDING_DOC_REVIEW of this whole class
029/**
030 * A 3D geometric point that usually represents the x, y, z coordinates.
031 * It can also represent a relative magnitude vector's x, y, z magnitudes.
032 *
033 * @since JavaFX 1.3
034 */
035public class Point3D {
036    /**
037     * The x coordinate.
038     *
039     * @defaultValue 0.0
040     */
041    private double x;
042
043    /**
044     * The x coordinate.
045     * @return the x coordinate
046     */
047    public final double getX() {
048        return x;
049    }
050    
051    /**
052     * The y coordinate.
053     *
054     * @defaultValue 0.0
055     */
056    private double y;
057
058    /**
059     * The y coordinate.
060     * @return the y coordinate
061     */
062    public final double getY() {
063        return y;
064    }
065    
066    /**
067     * The z coordinate.
068     *
069     * @defaultValue 0.0
070     */
071    private double z;
072
073    /**
074     * The z coordinate.
075     * @return the z coordinate
076     */
077    public final double getZ() {
078        return z;
079    }
080
081    /**
082     * Cache the hash code to make computing hashes faster.
083     */
084    private int hash = 0;
085
086    /**
087     * Creates a new instance of {@code Point3D}.
088     * @param x The X coordinate of the {@code Point3D}
089     * @param y The Y coordinate of the {@code Point3D}
090     * @param z The Z coordinate of the {@code Point3D}
091     */
092    public Point3D(double x, double y, double z) {
093        this.x = x;
094        this.y = y;
095        this.z = z;
096    }
097
098    /**
099     * Computes the distance between this point and point {@code (x1, y1, z1)}.
100     *
101     * @param x1 the x coordinate of other point
102     * @param y1 the y coordinate of other point
103     * @param z1 the z coordinate of other point
104     * @return the distance between this point and point {@code (x1, y1, z1)}.
105     */
106    public double distance(double x1, double y1, double z1) {
107        double a = getX() - x1;
108        double b = getY() - y1;
109        double c = getZ() - z1;
110        return Math.sqrt(a * a + b * b + c * c);
111    }
112
113    /**
114     * Computes the distance between this point and the specified {@code point}.
115     *
116     * @param point the other point
117     * @return the distance between this point and the specified {@code point}.
118     * @throws NullPointerException if the specified {@code point} is null
119     */
120    public double distance(Point3D  point) {
121        return distance(point.getX(), point.getY(), point.getZ());
122    }
123
124    /**
125     * Returns a point with the specified coordinates added to the coordinates
126     * of this point.
127     * @param x the X coordinate addition
128     * @param y the Y coordinate addition
129     * @param z the Z coordinate addition
130     * @return the point with added coordinates
131     * @since JavaFX 8.0
132     */
133    public Point3D add(double x, double y, double z) {
134        return new Point3D(
135                getX() + x,
136                getY() + y,
137                getZ() + z);
138    }
139
140    /**
141     * Returns a point with the coordinates of the specified point added to the
142     * coordinates of this point.
143     * @param point the point whose coordinates are to be added
144     * @return the point with added coordinates
145     * @throws NullPointerException if the specified {@code point} is null
146     * @since JavaFX 8.0
147     */
148    public Point3D add(Point3D point) {
149        return add(point.getX(), point.getY(), point.getZ());
150    }
151
152    /**
153     * Returns a point with the specified coordinates subtracted from
154     * the coordinates of this point.
155     * @param x the X coordinate subtraction
156     * @param y the Y coordinate subtraction
157     * @param z the Z coordinate subtraction
158     * @return the point with subtracted coordinates
159     * @since JavaFX 8.0
160     */
161    public Point3D subtract(double x, double y, double z) {
162        return new Point3D(
163                getX() - x,
164                getY() - y,
165                getZ() - z);
166    }
167
168    /**
169     * Returns a point with the coordinates of the specified point subtracted
170     * from the coordinates of this point.
171     * @param point the point whose coordinates are to be subtracted
172     * @return the point with subtracted coordinates
173     * @throws NullPointerException if the specified {@code point} is null
174     * @since JavaFX 8.0
175     */
176    public Point3D subtract(Point3D point) {
177        return subtract(point.getX(), point.getY(), point.getZ());
178    }
179
180    /**
181     * Returns a point with the coordinates of this point multiplied
182     * by the specified factor
183     * @param factor the factor multiplying the coordinates
184     * @return the point with multiplied coordinates
185     */
186    public Point3D multiply(double factor) {
187        return new Point3D(getX() * factor, getY() * factor, getZ() * factor);
188    }
189
190    /**
191     * Normalizes the relative magnitude vector represented by this instance.
192     * Returns a vector with the same direction and magnitude equal to 1.
193     * If this is a zero vector, a zero vector is returned.
194     * @return the normalized vector represented by a {@code Point3D} instance
195     * @since JavaFX 8.0
196     */
197    public Point3D normalize() {
198        final double mag = magnitude();
199
200        if (mag == 0.0) {
201            return new Point3D(0.0, 0.0, 0.0);
202        }
203
204        return new Point3D(
205                getX() / mag,
206                getY() / mag,
207                getZ() / mag);
208    }
209
210    /**
211     * Returns a point which lies in the middle between this point and the
212     * specified coordinates.
213     * @param x the X coordinate of the second endpoint
214     * @param y the Y coordinate of the second endpoint
215     * @param z the Z coordinate of the second endpoint
216     * @return the point in the middle
217     * @since JavaFX 8.0
218     */
219    public Point3D midpoint(double x, double y, double z) {
220        return new Point3D(
221                x + (getX() - x) / 2.0,
222                y + (getY() - y) / 2.0,
223                z + (getZ() - z) / 2.0);
224    }
225
226    /**
227     * Returns a point which lies in the middle between this point and the
228     * specified point.
229     * @param point the other endpoint
230     * @return the point in the middle
231     * @throws NullPointerException if the specified {@code point} is null
232     * @since JavaFX 8.0
233     */
234    public Point3D midpoint(Point3D point) {
235        return midpoint(point.getX(), point.getY(), point.getZ());
236    }
237
238    /**
239     * Computes the angle between the vector represented
240     * by this point and the specified vector.
241     * @param x the X magnitude of the other vector
242     * @param y the Y magnitude of the other vector
243     * @param z the Z magnitude of the other vector
244     * @return the angle between the two vectors
245     * @since JavaFX 8.0
246     */
247    public double angle(double x, double y, double z) {
248        final double ax = getX();
249        final double ay = getY();
250        final double az = getZ();
251
252        final double dotProduct = ax * x + ay * y + az * z;
253
254        return Math.toDegrees(Math.acos(dotProduct / Math.sqrt(
255                (ax * ax + ay * ay + az * az) * (x * x + y * y + z * z))));
256    }
257
258    /**
259     * Computes the angle between the vector represented
260     * by this point and the vector represented by the specified point.
261     * @param point the other vector
262     * @return the angle between the two vectors, {@code NaN} if any of the two
263     *         vectors is a zero vector
264     * @throws NullPointerException if the specified {@code point} is null
265     * @since JavaFX 8.0
266     */
267    public double angle(Point3D point) {
268        return angle(point.getX(), point.getY(), point.getZ());
269    }
270
271    /**
272     * Computes the angle between the three points with this point as a vertex.
273     * @param p1 one point
274     * @param p2 other point
275     * @return angle between the vectors (this, p1) and (this, p2),
276     *         {@code NaN} if the three points are not different from 
277     *         one another
278     * @throws NullPointerException if the {@code p1} or {@code p2} is null
279     * @since JavaFX 8.0
280     */
281    public double angle(Point3D p1, Point3D p2) {
282        final double x = getX();
283        final double y = getY();
284        final double z = getZ();
285
286        final double ax = p1.getX() - x;
287        final double ay = p1.getY() - y;
288        final double az = p1.getZ() - z;
289        final double bx = p2.getX() - x;
290        final double by = p2.getY() - y;
291        final double bz = p2.getZ() - z;
292
293        final double dotProduct = ax * bx + ay * by + az * bz;
294
295        return Math.toDegrees(Math.acos(dotProduct / Math.sqrt(
296                (ax * ax + ay * ay + az * az) * (bx * bx + by * by + bz * bz))));
297    }
298
299    /**
300     * Computes magnitude (length) of the relative magnitude vector represented
301     * by this instance.
302     * @return magnitude of the vector
303     * @since JavaFX 8.0
304     */
305    public double magnitude() {
306        final double x = getX();
307        final double y = getY();
308        final double z = getZ();
309
310        return Math.sqrt(x * x + y * y + z * z);
311    }
312
313    /**
314     * Computes dot (scalar) product of the vector represented by this instance
315     * and the specified vector.
316     * @param x the X magnitude of the other vector
317     * @param y the Y magnitude of the other vector
318     * @param z the Z magnitude of the other vector
319     * @return the dot product of the two vectors
320     * @since JavaFX 8.0
321     */
322    public double dotProduct(double x, double y, double z) {
323        return getX() * x + getY() * y + getZ() * z;
324    }
325
326    /**
327     * Computes dot (scalar) product of the vector represented by this instance
328     * and the specified vector.
329     * @param vector the other vector
330     * @return the dot product of the two vectors
331     * @throws NullPointerException if the specified {@code vector} is null
332     * @since JavaFX 8.0
333     */
334    public double dotProduct(Point3D vector) {
335        return dotProduct(vector.getX(), vector.getY(), vector.getZ());
336    }
337
338    /**
339     * Computes cross product of the vector represented by this instance
340     * and the specified vector.
341     * @param x the X magnitude of the other vector
342     * @param y the Y magnitude of the other vector
343     * @param z the Z magnitude of the other vector
344     * @return the cross product of the two vectors
345     * @since JavaFX 8.0
346     */
347    public Point3D crossProduct(double x, double y, double z) {
348        final double ax = getX();
349        final double ay = getY();
350        final double az = getZ();
351
352        return new Point3D(
353                ay * z - az * y,
354                az * x - ax * z,
355                ax * y - ay * x);
356    }
357
358    /**
359     * Computes cross product of the vector represented by this instance
360     * and the specified vector.
361     * @param vector the other vector
362     * @return the cross product of the two vectors
363     * @throws NullPointerException if the specified {@code vector} is null
364     * @since JavaFX 8.0
365     */
366    public Point3D crossProduct(Point3D vector) {
367        return crossProduct(vector.getX(), vector.getY(), vector.getZ());
368    }
369
370    /**
371     * Returns a hash code value for the point.
372     * @return a hash code value for the point.
373     */
374    @Override public boolean equals(Object obj) {
375        if (obj == this) return true;
376        if (obj instanceof Point3D) {
377            Point3D other = (Point3D) obj;
378            return getX() == other.getX() && getY() == other.getY() && getZ() == other.getZ();
379        } else return false;
380    }
381
382    /**
383     * Returns a hash code for this {@code Point3D} object.
384     * @return a hash code for this {@code Point3D} object.
385     */ 
386    @Override public int hashCode() {
387        if (hash == 0) {
388            long bits = 7L;
389            bits = 31L * bits + Double.doubleToLongBits(getX());
390            bits = 31L * bits + Double.doubleToLongBits(getY());
391            bits = 31L * bits + Double.doubleToLongBits(getZ());
392            hash = (int) (bits ^ (bits >> 32));
393        }
394        return hash;
395    }
396
397    /**
398     * Returns a string representation of this {@code Point3D}.
399     * This method is intended to be used only for informational purposes.
400     * The content and format of the returned string might vary between
401     * implementations.
402     * The returned string might be empty but cannot be {@code null}.
403     */
404    @Override public String toString() {
405        return "Point3D [x = " + getX() + ", y = " + getY() + ", z = " + getZ() + "]";
406    }
407}