source: josm/trunk/src/org/openstreetmap/josm/data/coor/EastNorth.java@ 11143

Last change on this file since 11143 was 10915, checked in by michael2402, 8 years ago

Trim interpolate in EastNorth/LatLon for performance and add comment explaining it. Added unit tests.

  • Property svn:eol-style set to native
File size: 5.7 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.coor;
3
4/**
5 * Northing, Easting of the projected coordinates.
6 *
7 * This class is immutable.
8 *
9 * @author Imi
10 */
11public class EastNorth extends Coordinate {
12
13 private static final long serialVersionUID = 1L;
14
15 /**
16 * Constructs a new {@code EastNorth}.
17 * @param east easting
18 * @param north northing
19 */
20 public EastNorth(double east, double north) {
21 super(east, north);
22 }
23
24 /**
25 * Returns easting.
26 * @return easting
27 */
28 public double east() {
29 return x;
30 }
31
32 /**
33 * Returns northing.
34 * @return northing
35 */
36 public double north() {
37 return y;
38 }
39
40 /**
41 * Adds an offset to this {@link EastNorth} instance and returns the result.
42 * @param dEast The offset to add in east direction.
43 * @param dNorth The offset to add in north direction.
44 * @return The result.
45 */
46 public EastNorth add(double dEast, double dNorth) {
47 return new EastNorth(east()+dEast, north()+dNorth);
48 }
49
50 /**
51 * Adds the coordinates of an other EastNorth instance to this one.
52 * @param other The other instance.
53 * @return The new EastNorth position.
54 */
55 public EastNorth add(EastNorth other) {
56 return new EastNorth(x+other.x, y+other.y);
57 }
58
59 /**
60 * Subtracts an east/north value from this point.
61 * @param other The other value to subtract from this.
62 * @return A point with the new coordinates.
63 */
64 public EastNorth subtract(EastNorth other) {
65 return new EastNorth(x-other.x, y-other.y);
66 }
67
68 /**
69 * Scales this {@link EastNorth} instance to a given factor and returns the result.
70 * @param s factor
71 * @return The result.
72 */
73 public EastNorth scale(double s) {
74 return new EastNorth(s * x, s * y);
75 }
76
77 /**
78 * Does a linear interpolation between two EastNorth instances.
79 * @param en2 The other EstNort instance.
80 * @param proportion The proportion the other instance influences the result.
81 * @return The new {@link EastNorth} position.
82 */
83 public EastNorth interpolate(EastNorth en2, double proportion) {
84 // this is an alternate form of this.x + proportion * (en2.x - this.x) that is slightly faster
85 return new EastNorth((1 - proportion) * this.x + proportion * en2.x,
86 (1 - proportion) * this.y + proportion * en2.y);
87 }
88
89 /**
90 * Gets the center between two {@link EastNorth} instances.
91 * @param en2 The other instance.
92 * @return The center between this and the other instance.
93 */
94 public EastNorth getCenter(EastNorth en2) {
95 // The JIT will inline this for us, it is as fast as the normal /2 approach
96 return interpolate(en2, .5);
97 }
98
99 /**
100 * Returns the euclidean distance from this {@code EastNorth} to a specified {@code EastNorth}.
101 *
102 * @param en the specified coordinate to be measured against this {@code EastNorth}
103 * @return the euclidean distance from this {@code EastNorth} to a specified {@code EastNorth}
104 * @since 6166
105 */
106 public double distance(final EastNorth en) {
107 return super.distance(en);
108 }
109
110 /**
111 * Returns the square of the euclidean distance from this {@code EastNorth} to a specified {@code EastNorth}.
112 *
113 * @param en the specified coordinate to be measured against this {@code EastNorth}
114 * @return the square of the euclidean distance from this {@code EastNorth} to a specified {@code EastNorth}
115 * @since 6166
116 */
117 public double distanceSq(final EastNorth en) {
118 return super.distanceSq(en);
119 }
120
121 /**
122 * Counts length (distance from [0,0]) of this.
123 *
124 * @return length of this
125 */
126 public double length() {
127 return Math.sqrt(x*x + y*y);
128 }
129
130 /**
131 * Returns the heading, in radians, that you have to use to get from
132 * this EastNorth to another. Heading is mapped into [0, 2pi)
133 *
134 * @param other the "destination" position
135 * @return heading
136 */
137 public double heading(EastNorth other) {
138 double hd = Math.atan2(other.east() - east(), other.north() - north());
139 if (hd < 0) {
140 hd = 2 * Math.PI + hd;
141 }
142 return hd;
143 }
144
145 /**
146 * Replies true if east and north are different from Double.NaN and not infinite
147 *
148 * @return true if east and north are different from Double.NaN and not infinite
149 */
150 public boolean isValid() {
151 return !Double.isNaN(x) && !Double.isNaN(y) && !Double.isInfinite(x) && !Double.isInfinite(y);
152 }
153
154 /**
155 * Returns an EastNorth representing the this EastNorth rotated around
156 * a given EastNorth by a given angle
157 * @param pivot the center of the rotation
158 * @param angle the angle of the rotation
159 * @return EastNorth rotated object
160 */
161 public EastNorth rotate(EastNorth pivot, double angle) {
162 double cosPhi = Math.cos(angle);
163 double sinPhi = Math.sin(angle);
164 double x = east() - pivot.east();
165 double y = north() - pivot.north();
166 // CHECKSTYLE.OFF: SingleSpaceSeparator
167 double nx = cosPhi * x + sinPhi * y + pivot.east();
168 double ny = -sinPhi * x + cosPhi * y + pivot.north();
169 // CHECKSTYLE.ON: SingleSpaceSeparator
170 return new EastNorth(nx, ny);
171 }
172
173 @Override
174 public String toString() {
175 return "EastNorth[e="+x+", n="+y+']';
176 }
177
178 /**
179 * Compares two EastNorth values
180 * @param other other east.north
181 * @param e epsilon
182 *
183 * @return true if "x" and "y" values are within epsilon {@code e} of each other
184 */
185 public boolean equalsEpsilon(EastNorth other, double e) {
186 return Math.abs(x - other.x) < e && Math.abs(y - other.y) < e;
187 }
188}
Note: See TracBrowser for help on using the repository browser.