// File: Location.java from the package edu.colorado.geometry // Additional javadoc documentation is available from the Location link in: // http://www.cs.colorado.edu/~main/docs package edu.colorado.geometry; /****************************************************************************** * A Location object keeps track of a location on a two-dimensional * plane. * * @see * * Java Source Code for this class * (www.cs.colorado.edu/~main/edu/colorado/geometry/Location.java) * * * @author Michael Main * (main@colorado.edu) * * @version Feb 10, 2016 ******************************************************************************/ public class Location implements Cloneable { private double x; // The x coordinate of this Location private double y; // The y coordinate of this Location /** * Construct a Location with specified coordinates. * @param xInitial * the initial x coordinate of this Location * @param yInitial * the initial y coordinate of this Location * @postcondition * This Location has been initialized at the given coordinates. **/ public Location(double xInitial, double yInitial) { x = xInitial; y = yInitial; } /** * Generate a copy of this Location. * @return * The return value is a copy of this Location. Subsequent * changes to the copy will not affect the original, nor vice versa. * Note that the return value is a Location (not a plain Object) * which is permitted with Java 5.0. **/ public Location clone( ) { // Clone a Location object. Location answer; try { answer = (Location) super.clone( ); } catch (CloneNotSupportedException e) { // This exception should not occur. But if it does, it would probably // indicate a programming error that made super.clone unavailable. // The most common error would be forgetting the "Implements Cloneable" // clause at the start of this class. throw new RuntimeException ("This class does not implement Cloneable."); } return answer; } /** * Compute the distance between two Locations. * @param p1 * the first Location * @param p2 * the second Location * @return * the distance between p1 and p2 * @note * The answer is Double.POSITIVE_INFINITY if the distance * calculation overflows. The answer is Double.NaN if either * Location is null. **/ public static double distance(Location p1, Location p2) { double a, b, c_squared; // Check whether one of the locations is null. if ((p1 == null) || (p2 == null)) return Double.NaN; // Calculate differences in x and y coordinates. a = p1.x - p2.x; b = p1.y - p2.y; // Use Pythagorean Theorem to calculate the square of the distance. // between the locations. c_squared = a*a + b*b; return Math.sqrt(c_squared); } /** * Compare this Location to another object for equality. * @param obj * an object with which this Location will be compared * @return * A return value of true indicates that * obj refers to a * Location object with the same value as this * Location. Otherwise the return value is * false. * @note * If obj is null or does not refer to a * Location object, then the answer is * false. **/ public boolean equals(Object obj) { if (obj instanceof Location) { Location candidate = (Location) obj; return (candidate.x == x) && (candidate.y == y); } else return false; } /** * Get the x coordinate of this Location. * @return * the x coordinate of this Location. **/ public double getX( ) { return x; } /** * Get the y coordinate of this Location. * @return * the y coordinate of this Location. **/ public double getY( ) { return y; } /** * Generate and return a Location halfway between two others. * @param p1 * the first Location * @param p2 * the second Location * @return * a Location that is halfway between p1 * and p2. * @note * The answer is null if either p1 or p2 is null. **/ public static Location midpoint(Location p1, Location p2) { double xMid, yMid; //Check whether one of the locations is null. if ((p1 == null) || (p2 == null)) return null; // Compute the x and y midpoints. xMid = (p1.x/2) + (p2.x/2); yMid = (p1.y/2) + (p2.y/2); // Create a new location and return it. Location answer = new Location(xMid, yMid); return answer; } /** * Rotate this Location 90 degrees in a clockwise direction. * @postcondition * This Location has been rotated clockwise 90 degrees around * the origin. **/ public void rotate90( ) { double xNew; double yNew; // For a 90 degree clockwise rotations, the new x is the original y // and the new y is -1 times the original x. xNew = y; yNew = -x; x = xNew; y = yNew; } /** * Move this Location by given amounts along the x and y axes. * @param xAmount * the amount to move this Location along the x axis * @param yAmount * the amount to move this Location along the y axis * @postcondition * This Location has been moved by the given amounts along the two axes. * @note * The shift may cause a coordinate to go above * Double.MAX_VALUE or below the minimum double value. * In these cases, subsequent activations of getX or * getY will return Double.POSITIVE_INFINITY or * Double.NEGATIVE_INFINITY. **/ public void shift(double xAmount, double yAmount) { x += xAmount; y += yAmount; } /** * Generate a String representation of this Location. * @return * a String representation of this Location **/ public String toString( ) { return "(x=" + x + " y=" + y + ")"; } }