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 2D geometric point that usually represents the x, y coordinates.
031 * It can also represent a relative magnitude vector's x, y magnitudes.
032 */
033public class Point2D {
034    /**
035     * The x coordinate.
036     *
037     * @defaultValue 0.0
038     */
039    private double x;
040
041    /**
042     * The x coordinate.
043     * @return the x coordinate
044     */
045    public final double getX() {
046        return x;
047    }
048    
049    /**
050     * The y coordinate.
051     *
052     * @defaultValue 0.0
053     */
054    private double y;
055
056    /**
057     * The y coordinate.
058     * @return the y coordinate
059     */
060    public final double getY() {
061        return y;
062    }
063
064    /**
065     * Cache the hash code to make computing hashes faster.
066     */
067    private int hash = 0;
068
069    /**
070     * Creates a new instance of {@code Point2D}.
071     * @param x the x coordinate of the point
072     * @param y the y coordinate of the point
073     */
074    public Point2D(double x, double y) {
075        this.x  = x;
076        this.y = y;
077    }
078
079    /**
080     * Computes the distance between this point and point {@code (x1, y1)}.
081     *
082     * @param x1 the x coordinate of other point
083     * @param y1 the y coordinate of other point
084     * @return the distance between this point and point {@code (x1, y1)}.
085     */
086    public double distance(double x1, double y1) {
087        double a = getX() - x1;
088        double b = getY() - y1;
089        return Math.sqrt(a * a + b * b);
090    }
091
092    /**
093     * Computes the distance between this point and the specified {@code point}.
094     *
095     * @param point the other point
096     * @return the distance between this point and the specified {@code point}.
097     * @throws NullPointerException if the specified {@code point} is null
098     */
099    public double distance(Point2D point) {
100        return distance(point.getX(), point.getY());
101    }
102
103    /**
104     * Returns a point with the specified coordinates added to the coordinates
105     * of this point.
106     * @param x the X coordinate addition
107     * @param y the Y coordinate addition
108     * @return the point with added coordinates
109     * @since JavaFX 8.0
110     */
111    public Point2D add(double x, double y) {
112        return new Point2D(
113                getX() + x,
114                getY() + y);
115    }
116
117    /**
118     * Returns a point with the coordinates of the specified point added to the
119     * coordinates of this point.
120     * @param point the point whose coordinates are to be added
121     * @return the point with added coordinates
122     * @throws NullPointerException if the specified {@code point} is null
123     * @since JavaFX 8.0
124     */
125    public Point2D add(Point2D point) {
126        return add(point.getX(), point.getY());
127    }
128
129    /**
130     * Returns a point with the specified coordinates subtracted from
131     * the coordinates of this point.
132     * @param x the X coordinate subtraction
133     * @param y the Y coordinate subtraction
134     * @return the point with subtracted coordinates
135     * @since JavaFX 8.0
136     */
137    public Point2D subtract(double x, double y) {
138        return new Point2D(
139                getX() - x,
140                getY() - y);
141    }
142
143    /**
144     * Returns a point with the coordinates of this point multiplied
145     * by the specified factor
146     * @param factor the factor multiplying the coordinates
147     * @return the point with multiplied coordinates
148     */
149    public Point2D multiply(double factor) {
150        return new Point2D(getX() * factor, getY() * factor);
151    }
152
153    /**
154     * Returns a point with the coordinates of the specified point subtracted
155     * from the coordinates of this point.
156     * @param point the point whose coordinates are to be subtracted
157     * @return the point with subtracted coordinates
158     * @throws NullPointerException if the specified {@code point} is null
159     * @since JavaFX 8.0
160     */
161    public Point2D subtract(Point2D point) {
162        return subtract(point.getX(), point.getY());
163    }
164
165    /**
166     * Normalizes the relative magnitude vector represented by this instance.
167     * Returns a vector with the same direction and magnitude equal to 1.
168     * If this is a zero vector, a zero vector is returned.
169     * @return the normalized vector represented by a {@code Point2D} instance
170     * @since JavaFX 8.0
171     */
172    public Point2D normalize() {
173        final double mag = magnitude();
174
175        if (mag == 0.0) {
176            return new Point2D(0.0, 0.0);
177        }
178
179        return new Point2D(
180                getX() / mag,
181                getY() / mag);
182    }
183
184    /**
185     * Returns a point which lies in the middle between this point and the
186     * specified coordinates.
187     * @param x the X coordinate of the second endpoint
188     * @param y the Y coordinate of the second endpoint
189     * @return the point in the middle
190     * @since JavaFX 8.0
191     */
192    public Point2D midpoint(double x, double y) {
193        return new Point2D(
194                x + (getX() - x) / 2.0,
195                y + (getY() - y) / 2.0);
196    }
197
198    /**
199     * Returns a point which lies in the middle between this point and the
200     * specified point.
201     * @param point the other endpoint
202     * @return the point in the middle
203     * @throws NullPointerException if the specified {@code point} is null
204     * @since JavaFX 8.0
205     */
206    public Point2D midpoint(Point2D point) {
207        return midpoint(point.getX(), point.getY());
208    }
209
210    /**
211     * Computes the angle between the vector represented
212     * by this point and the specified vector.
213     * @param x the X magnitude of the other vector
214     * @param y the Y magnitude of the other vector
215     * @return the angle between the two vectors
216     * @since JavaFX 8.0
217     */
218    public double angle(double x, double y) {
219        final double ax = getX();
220        final double ay = getY();
221
222        final double dotProduct = ax * x + ay * y;
223
224        return Math.toDegrees(Math.acos(dotProduct / Math.sqrt(
225                (ax * ax + ay * ay) * (x * x + y * y))));
226    }
227
228    /**
229     * Computes the angle between the vector represented
230     * by this point and the vector represented by the specified point.
231     * @param point the other vector
232     * @return the angle between the two vectors, {@code NaN} if any of the two
233     *         vectors is a zero vector
234     * @throws NullPointerException if the specified {@code point} is null
235     * @since JavaFX 8.0
236     */
237    public double angle(Point2D point) {
238        return angle(point.getX(), point.getY());
239    }
240
241    /**
242     * Computes the angle between the three points with this point as a vertex.
243     * @param p1 one point
244     * @param p2 other point
245     * @return angle between the vectors (this, p1) and (this, p2),
246     *         {@code NaN} if the three points are not different from
247     *         one another
248     * @throws NullPointerException if {@code p1} or {@code p2} is null
249     * @since JavaFX 8.0
250     */
251    public double angle(Point2D p1, Point2D p2) {
252        final double x = getX();
253        final double y = getY();
254
255        final double ax = p1.getX() - x;
256        final double ay = p1.getY() - y;
257        final double bx = p2.getX() - x;
258        final double by = p2.getY() - y;
259
260        final double dotProduct = ax * bx + ay * by;
261
262        return Math.toDegrees(Math.acos(dotProduct / Math.sqrt(
263                (ax * ax + ay * ay) * (bx * bx + by * by))));
264    }
265
266    /**
267     * Computes magnitude (length) of the relative magnitude vector represented
268     * by this instance.
269     * @return magnitude of the vector
270     * @since JavaFX 8.0
271     */
272    public double magnitude() {
273        final double x = getX();
274        final double y = getY();
275
276        return Math.sqrt(x * x + y * y);
277    }
278
279    /**
280     * Computes dot (scalar) product of the vector represented by this instance
281     * and the specified vector.
282     * @param x the X magnitude of the other vector
283     * @param y the Y magnitude of the other vector
284     * @return the dot product of the two vectors
285     * @since JavaFX 8.0
286     */
287    public double dotProduct(double x, double y) {
288        return getX() * x + getY() * y;
289    }
290
291    /**
292     * Computes dot (scalar) product of the vector represented by this instance
293     * and the specified vector.
294     * @param vector the other vector
295     * @return the dot product of the two vectors
296     * @throws NullPointerException if the specified {@code vector} is null
297     * @since JavaFX 8.0
298     */
299    public double dotProduct(Point2D vector) {
300        return dotProduct(vector.getX(), vector.getY());
301    }
302
303    /**
304     * Computes cross product of the vector represented by this instance
305     * and the specified vector.
306     * @param x the X magnitude of the other vector
307     * @param y the Y magnitude of the other vector
308     * @return the cross product of the two vectors
309     * @since JavaFX 8.0
310     */
311    public Point3D crossProduct(double x, double y) {
312        final double ax = getX();
313        final double ay = getY();
314
315        return new Point3D(
316                0, 0, ax * y - ay * x);
317    }
318
319    /**
320     * Computes cross product of the vector represented by this instance
321     * and the specified vector.
322     * @param vector the other vector
323     * @return the cross product of the two vectors
324     * @throws NullPointerException if the specified {@code vector} is null
325     * @since JavaFX 8.0
326     */
327    public Point3D crossProduct(Point2D vector) {
328        return crossProduct(vector.getX(), vector.getY());
329    }
330
331    /**
332     * Indicates whether some other object is "equal to" this one.
333     * 
334     * @param obj the reference object with which to compare
335     * @return true if this point is the same as the obj argument; false otherwise
336      */
337    @Override public boolean equals(Object obj) {
338        if (obj == this) return true;
339        if (obj instanceof Point2D) {
340            Point2D other = (Point2D) obj;
341            return getX() == other.getX() && getY() == other.getY();
342        } else return false;
343    }
344
345    /**
346     * Returns a hash code value for the point.
347     * @return a hash code value for the point.
348     */
349    @Override public int hashCode() {
350        if (hash == 0) {
351            long bits = 7L;
352            bits = 31L * bits + Double.doubleToLongBits(getX());
353            bits = 31L * bits + Double.doubleToLongBits(getY());
354            hash = (int) (bits ^ (bits >> 32));
355        }
356        return hash;
357    }
358
359    /**
360     * Returns a string representation of this {@code Point2D}.
361     * This method is intended to be used only for informational purposes.
362     * The content and format of the returned string might vary between
363     * implementations.
364     * The returned string might be empty but cannot be {@code null}.
365     */
366    @Override public String toString() {
367        return "Point2D [x = " + getX() + ", y = " + getY() + "]";
368    }
369}