001// License: GPL. For details, see LICENSE file. 002package 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 */ 011public 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 /** 047 * Returns the euclidean distance from this {@code EastNorth} to a specified {@code EastNorth}. 048 * 049 * @param en the specified coordinate to be measured against this {@code EastNorth} 050 * @return the euclidean distance from this {@code EastNorth} to a specified {@code EastNorth} 051 * @since 6166 052 */ 053 public double distance(final EastNorth en) { 054 return super.distance(en); 055 } 056 057 /** 058 * Returns the square of the euclidean distance from this {@code EastNorth} to a specified {@code EastNorth}. 059 * 060 * @param en the specified coordinate to be measured against this {@code EastNorth} 061 * @return the square of the euclidean distance from this {@code EastNorth} to a specified {@code EastNorth} 062 * @since 6166 063 */ 064 public double distanceSq(final EastNorth en) { 065 return super.distanceSq(en); 066 } 067 068 /** 069 * Counts length (distance from [0,0]) of this. 070 * 071 * @return length of this 072 */ 073 public double length(){ 074 return Math.sqrt(x*x + y*y); 075 } 076 077 /** 078 * Returns the heading, in radians, that you have to use to get from 079 * this EastNorth to another. Heading is mapped into [0, 2pi) 080 * 081 * @param other the "destination" position 082 * @return heading 083 */ 084 public double heading(EastNorth other) { 085 double hd = Math.atan2(other.east() - east(), other.north() - north()); 086 if(hd < 0) { 087 hd = 2 * Math.PI + hd; 088 } 089 return hd; 090 } 091 092 /** 093 * Replies true if east and north are different from Double.NaN 094 * 095 * @return true if east and north are different from Double.NaN 096 */ 097 public boolean isValid() { 098 return !java.lang.Double.isNaN(x) && !java.lang.Double.isNaN(y); 099 } 100 101 public EastNorth sub(EastNorth en) { 102 return new EastNorth(en.east() - east(), en.north() - north()); 103 } 104 105 /** 106 * Returns an EastNorth representing the this EastNorth rotated around 107 * a given EastNorth by a given angle 108 * @param pivot the center of the rotation 109 * @param angle the angle of the rotation 110 * @return EastNorth rotated object 111 */ 112 public EastNorth rotate(EastNorth pivot, double angle) { 113 double cosPhi = Math.cos(angle); 114 double sinPhi = Math.sin(angle); 115 double x = east() - pivot.east(); 116 double y = north() - pivot.north(); 117 double nx = cosPhi * x + sinPhi * y + pivot.east(); 118 double ny = -sinPhi * x + cosPhi * y + pivot.north(); 119 return new EastNorth(nx, ny); 120 } 121 122 @Override public String toString() { 123 return "EastNorth[e="+x+", n="+y+"]"; 124 } 125 126 /** 127 * Compares two EastNorth values 128 * 129 * @return true if "x" and "y" values are within 1E-6 of each other 130 */ 131 public boolean equalsEpsilon(EastNorth other, double e) { 132 return (Math.abs(x - other.x) < e && Math.abs(y - other.y) < e); 133 } 134}