/*******************************************************************************
* Copyright (c) 2000, 2008 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.draw2d.geometry;
import org.eclipse.draw2d.PositionConstants;
/**
* Represents a point (x, y) in 2-dimensional space. This class provides various methods
* for manipulating this Point or creating new derived geometrical Objects.
*/
public class Point
implements Cloneable, java.io.Serializable, Translatable
{
static final long serialVersionUID = 1;
/**A singleton for use in short calculations*/
public static final Point SINGLETON = new Point();
/**x value*/
public int x;
/**y value*/
public int y;
/**
* Constructs a Point at location (0,0).
* @since 2.0
*/
public Point() { }
/**
* Constructs a Point at the same location as the given Point.
* @param copy Point from which the initial values are taken.
* @since 2.0
*/
public Point(Point copy) {
x = copy.x;
y = copy.y;
}
/**
* Constructs a Point at the same location as the given SWT Point.
* @param copy Point from which the initial values are taken.
* @since 2.0
*/
public Point(org.eclipse.swt.graphics.Point copy) {
x = copy.x;
y = copy.y;
}
/**
* Constructs a Point at the specified x and y locations.
*
* @param x x value
* @param y y value
* @since 2.0
*/
public Point(int x, int y) {
this.x = x;
this.y = y;
}
/**
* Constructs a Point at the specified x and y locations.
* @param x x value
* @param y y value
* @since 2.0
*/
public Point(double x, double y) {
this.x = (int)x;
this.y = (int)y;
}
/**
* Test for equality.
* @param o Object being tested for equality
* @return true if both x and y values are equal
* @since 2.0
*/
public boolean equals(Object o) {
if (o instanceof Point) {
Point p = (Point)o;
return p.x == x && p.y == y;
}
return false;
}
/**
* @return a copy of this Point
* @since 2.0
*/
public Point getCopy() {
return new Point(x, y);
}
/**
* Calculates the difference in between this Point and the one specified.
* @param pt The Point being subtracted from this Point
* @return A new Dimension representing the difference
* @since 2.0
*/
public Dimension getDifference(Point pt) {
return new Dimension(this.x - pt.x, this.y - pt.y);
}
/**
* Calculates the distance from this Point to the one specified.
* @param pt The Point being compared to this
* @return The distance
* @since 2.0
*/
public double getDistance(Point pt) {
return Math.sqrt(getPreciseDistance2(pt));
}
/**
* Calculates the distance squared between this Point and the one specified. If
* the distance squared is larger than the maximum integer value, then
* <code>Integer.MAX_VALUE</code> will be returned.
* @param pt The reference Point
* @return distance<sup>2</sup>
* @since 2.0
*/
public int getDistance2(Point pt) {
long i = pt.x - x;
long j = pt.y - y;
long result = i * i + j * j;
if (result > Integer.MAX_VALUE)
return Integer.MAX_VALUE;
return (int)result;
}
private double getPreciseDistance2(Point pt) {
double i = pt.preciseX() - preciseX();
double j = pt.preciseY() - preciseY();
return i * i + j * j;
}
/**
* Calculates the orthogonal distance to the specified point. The orthogonal distance is
* the sum of the horizontal and vertical differences.
* @param pt The reference Point
* @return the orthoganal distance
*/
public int getDistanceOrthogonal(Point pt) {
return Math.abs(y - pt.y) + Math.abs(x - pt.x);
}
/**
* Creates a Point with negated x and y values.
* @return A new Point
* @since 2.0
*/
public Point getNegated() {
return getCopy().negate();
}
/**
* Calculates the relative position of the specified Point to this Point.
* @param p The reference Point
* @return NORTH, SOUTH, EAST, or WEST, as defined in {@link PositionConstants}
*/
public int getPosition(Point p) {
int dx = p.x - x;
int dy = p.y - y;
if (Math.abs(dx) > Math.abs(dy)) {
if (dx < 0)
return PositionConstants.WEST;
return PositionConstants.EAST;
}
if (dy < 0)
return PositionConstants.NORTH;
return PositionConstants.SOUTH;
}
/**
* Creates a new Point from this Point by scaling by the specified amount.
* @param amount scale factor
* @return A new Point
* @since 2.0
*/
public Point getScaled(double amount) {
return getCopy().scale(amount);
}
/**
* Creates a new SWT {@link org.eclipse.swt.graphics.Point Point} from this Point.
* @return A new SWT Point
* @since 2.0
*/
public org.eclipse.swt.graphics.Point getSWTPoint() {
return new org.eclipse.swt.graphics.Point(x, y);
}
/**
* Creates a new Point which is translated by the values of the input Dimension.
* @param delta Dimension which provides the translation amounts.
* @return A new Point
* @since 2.0
*/
public Point getTranslated(Dimension delta) {
return getCopy().translate(delta);
}
/**
* Creates a new Point which is translated by the specified x and y values
* @param x horizontal component
* @param y vertical component
* @return A new Point
* @since 2.0
*/
public Point getTranslated(int x, int y) {
return getCopy().translate(x, y);
}
/**
* Creates a new Point which is translated by the values of the provided Point.
* @param pt Point which provides the translation amounts.
* @return A new Point
* @since 2.0
*/
public Point getTranslated(Point pt) {
return getCopy().translate(pt);
}
/**
* Creates a new Point with the transposed values of this Point.
* Can be useful in orientation change calculations.
* @return A new Point
* @since 2.0
*/
public Point getTransposed() {
return getCopy().transpose();
}
/**
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
return (x * y) ^ (x + y);
}
/**
* Creates a new Point representing the MAX of two provided Points.
* @param p1 first point
* @param p2 second point
* @return A new Point representing the Max()
*/
public static Point max(Point p1, Point p2) {
return new Rectangle(p1, p2)
.getBottomRight()
.translate(-1, -1);
}
/**
* Creates a new Point representing the MIN of two provided Points.
* @param p1 first point
* @param p2 second point
* @return A new Point representing the Min()
*/
public static Point min(Point p1, Point p2) {
return new Rectangle(p1, p2).getTopLeft();
}
/**
* Negates the x and y values of this Point.
* @return <code>this</code> for convenience
* @since 2.0
*/
public Point negate() {
x = -x;
y = -y;
return this;
}
/** @see Translatable#performScale(double) */
public void performScale(double factor) {
scale(factor);
}
/** @see Translatable#performTranslate(int, int) */
public void performTranslate(int dx, int dy) {
translate(dx, dy);
}
/**
* Scales this Point by the specified amount.
* @return <code>this</code> for convenience
* @param amount scale factor
* @since 2.0
*/
public Point scale(double amount) {
x = (int)Math.floor(x * amount);
y = (int)Math.floor(y * amount);
return this;
}
/**
* Scales this Point by the specified values.
* @param xAmount horizontal scale factor
* @param yAmount vertical scale factor
* @return <code>this</code> for convenience
* @since 2.0
*/
public Point scale(double xAmount, double yAmount) {
x = (int)Math.floor(x * xAmount);
y = (int)Math.floor(y * yAmount);
return this;
}
/**
* Sets the location of this Point to the provided x and y locations.
* @return <code>this</code> for convenience
* @param x the x location
* @param y the y location
* @since 2.0
*/
public Point setLocation(int x, int y) {
this.x = x;
this.y = y;
return this;
}
/**
* Sets the location of this Point to the specified Point.
* @return <code>this</code> for convenience
* @param pt the Location
* @since 2.0
*/
public Point setLocation(Point pt) {
x = pt.x;
y = pt.y;
return this;
}
/**
* @return String representation.
* @since 2.0
*/
public String toString() {
return "Point(" + x + ", " + y + ")";//$NON-NLS-3$//$NON-NLS-2$//$NON-NLS-1$
}
/**
* Shifts the location of this Point by the location of the
* input Point along each of the axes, and returns this for
* convenience.
*
* @param p Point to which the origin is being shifted.
* @return <code>this</code> for convenience
* @since 2.0
*/
public Point translate(Point p) {
return translate(p.x, p.y);
}
/**
* Shifts this Point by the values of the Dimension along
* each axis, and returns this for convenience.
*
* @param d Dimension by which the origin is being shifted.
* @return <code>this</code> for convenience
* @since 2.0
*/
public Point translate(Dimension d) {
return translate(d.width, d.height);
}
/**
* Shifts this Point by the values supplied along each axes, and
* returns this for convenience.
*
* @param dx Amount by which point is shifted along X axis.
* @param dy Amount by which point is shifted along Y axis.
* @return <code>this</code> for convenience
* @since 2.0
*/
public Point translate(int dx, int dy) {
x += dx;
y += dy;
return this;
}
/**
* Transposes this object. X and Y values are exchanged.
* @return <code>this</code> for convenience
* @since 2.0
*/
public Point transpose() {
int temp = x;
x = y;
y = temp;
return this;
}
/**
* Returns <code>double</code> x coordinate
*
* @return <code>double</code> x coordinate
* @since 3.4
*/
public double preciseX() {
return x;
}
/**
* Returns <code>double</code> y coordinate
*
* @return <code>double</code> y coordinate
* @since 3.4
*/
public double preciseY() {
return y;
}
}