view dwtx/draw2d/geometry/Point.d @ 98:95307ad235d9

Added Draw2d code, still work in progress
author Frank Benoit <benoit@tionex.de>
date Sun, 03 Aug 2008 00:52:14 +0200
parents
children 1082a0fc2bb8
line wrap: on
line source

/*******************************************************************************
 * 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
 * Port to the D programming language:
 *     Frank Benoit <benoit@tionex.de>
 *******************************************************************************/
module dwtx.draw2d.geometry.Point;

import dwt.dwthelper.utils;

import dwtx.draw2d.PositionConstants;
import dwtx.draw2d.geometry.Translatable;
import dwtx.draw2d.geometry.Dimension;
import dwtx.draw2d.geometry.Rectangle;

static import dwt.graphics.Point;

import tango.text.convert.Format;

/**
 * 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
    : Cloneable, /+java.io.Serializable,+/ Translatable
{

static final long serialVersionUID = 1;
/**A singleton for use in short calculations*/
public static const Point SINGLETON;

static this(){
    SINGLETON = new Point();
}

/**x value*/
public int x;
/**y value*/
public int y;

/**
 * Constructs a Point at location (0,0).
 * @since 2.0
 */
public this() { }

/**
 * 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 this(Point copy) {
    x = copy.x;
    y = copy.y;
}

/**
 * Constructs a Point at the same location as the given DWT Point.
 * @param copy  Point from which the initial values are taken.
 * @since 2.0
 */
public this(dwt.graphics.Point.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 this(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 this(double x, double y) {
    this.x = cast(int)x;
    this.y = cast(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 override int opEquals(Object o) {
    if ( auto p = cast(Point)o ) {
        return p.x is x && p.y is 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 cast(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 DWT {@link dwt.graphics.Point Point} from this Point.
 * @return  A new DWT Point
 * @since 2.0
 */
public dwt.graphics.Point.Point getSWTPoint() {
    return new dwt.graphics.Point.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#toHash()
 */
public override hash_t toHash() {
    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 = cast(int)Math.floor(x * amount);
    y = cast(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 = cast(int)Math.floor(x * xAmount);
    y = cast(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 override String toString() {
    return Format("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;
}

}