001 // License: GPL. Copyright 2007 by Immanuel Scholz and others 002 package org.openstreetmap.josm.data.coor; 003 004 /** 005 * Northing, Easting of the projected coordinates. 006 * 007 * This class is immutable. 008 * 009 * @author Imi 010 */ 011 public class EastNorth extends Coordinate { 012 013 public EastNorth(double east, double north) { 014 super(east,north); 015 } 016 017 public double east() { 018 return x; 019 } 020 021 public double north() { 022 return y; 023 } 024 025 public EastNorth add(double dx, double dy) { 026 return new EastNorth(x+dx, y+dy); 027 } 028 029 public EastNorth add(EastNorth other) { 030 return new EastNorth(x+other.x, y+other.y); 031 } 032 033 public EastNorth scale(double s) { 034 return new EastNorth(s * x, s * y); 035 } 036 037 public EastNorth interpolate(EastNorth en2, double proportion) { 038 return new EastNorth(this.x + proportion * (en2.x - this.x), 039 this.y + proportion * (en2.y - this.y)); 040 } 041 042 public EastNorth getCenter(EastNorth en2) { 043 return new EastNorth((this.x + en2.x)/2.0, (this.y + en2.y)/2.0); 044 } 045 046 public double distance(EastNorth en2) { 047 return Math.sqrt((this.x-en2.x)*(this.x-en2.x) + (this.y-en2.y)*(this.y-en2.y)); 048 } 049 050 /** 051 * Returns the heading, in radians, that you have to use to get from 052 * this EastNorth to another. Heading is mapped into [0, 2pi) 053 * 054 * @param other the "destination" position 055 * @return heading 056 */ 057 public double heading(EastNorth other) { 058 double hd = Math.atan2(other.east() - east(), other.north() - north()); 059 if(hd < 0) hd = 2 * Math.PI + hd; 060 return hd; 061 } 062 063 /** 064 * Replies true if east and north are different from Double.NaN 065 * 066 * @return true if east and north are different from Double.NaN 067 */ 068 public boolean isValid() { 069 return !java.lang.Double.isNaN(x) && !java.lang.Double.isNaN(y); 070 } 071 072 public EastNorth sub(EastNorth en) { 073 return new EastNorth(en.east() - east(), en.north() - north()); 074 } 075 076 /** 077 * Returns an EastNorth representing the this EastNorth rotated around 078 * a given EastNorth by a given angle 079 * @param pivot the center of the rotation 080 * @param angle the angle of the rotation 081 * @return EastNorth rotated object 082 */ 083 public EastNorth rotate(EastNorth pivot, double angle) { 084 double cosPhi = Math.cos(angle); 085 double sinPhi = Math.sin(angle); 086 double x = east() - pivot.east(); 087 double y = north() - pivot.north(); 088 double nx = cosPhi * x + sinPhi * y + pivot.east(); 089 double ny = -sinPhi * x + cosPhi * y + pivot.north(); 090 return new EastNorth(nx, ny); 091 } 092 093 @Override public String toString() { 094 return "EastNorth[e="+x+", n="+y+"]"; 095 } 096 097 /** 098 * Compares two EastNorth values 099 * 100 * @return true if "x" and "y" values are within 1E-6 of each other 101 */ 102 public boolean equalsEpsilon(EastNorth other, double e) { 103 return (Math.abs(x - other.x) < e && Math.abs(y - other.y) < e); 104 } 105 }