/** Represents a point in three-dimensional coordinates. */
public class Point {
	/** The origin point, with zero for all coordinates. */
	public static Point ORIGIN = new Point(0, 0, 0);

	private double x;
	private double y;
	private double z;

	private Point(double x, double y, double z) {
		this.x = x;
		this.y = y;
		this.z = z;
	}

	/** Returns the x-coordinate of this point. */
	public double getX() { return x; }
	/** Returns the y-coordinate of this point. */
	public double getY() { return y; }
	/** Returns the z-coordinate of this point. */
	public double getZ() { return z; }

	public String toString() {
		return "(" + x + "," + y + "," + z + ")";
	}

	/** Returns the distance between this point and the
	 * parameter point. */
	public double getDistanceTo(Point other) {
		double dx = this.x - other.x;
		double dy = this.y - other.y;
		double dz = this.z - other.z;
		return Math.sqrt(dx * dx + dy * dy + dz * dz);
	}

	/** Returns the vector from the parameter point to this
	 * point - ie, one whose components are the difference of
	 * this vector's coordinates and the parameter vector's
	 * coordinates. */
	public Vector subtract(Point other) {
		double dx = this.x - other.x;
		double dy = this.y - other.y;
		double dz = this.z - other.z;
		return Vector.create(dx, dy, dz);
	}

	/** Returns a copy of this point shifted by the given vector
	 * scaled by the given scalar. */
	public Point addScaled(double scalar, Vector v) {
		return Point.create(x + scalar * v.getX(), y + scalar * v.getY(), z + scalar * v.getZ());
	}

	/** Returns a copy of this point shifted by the given * vector. */
	public Point add(Vector v) {
		return this.addScaled(1, v);
	}

	/** Constructs a point with the given coordinates. */
	public static Point create(double x, double y, double z) {
		return new Point(x, y, z);
	}
}
