250
* Calculates the angle between the two segments (c1,c2),(c2,c3)
251
* using the coords in map units.
252
* @param c1 first point
253
* @param c2 second point
254
* @param c3 third point
255
* @return angle between the two segments in degree [-180;180]
257
public static double getDisplayedAngle(Coord c1, Coord c2, Coord c3) {
258
return getAngle(c1.getDisplayedCoord(), c2.getDisplayedCoord(), c3.getDisplayedCoord());
247
261
public final static int NOT_STRAIGHT = 0;
248
262
public final static int STRAIGHT_SPIKE = 1;
249
263
public final static int STRICTLY_STRAIGHT = 2;
282
296
return NOT_STRAIGHT;
301
* Checks if the two segments (c1,c2),(c2,c3) form a straight line
302
* using high precision coordinates.
303
* @param c1 first point
304
* @param c2 second point
305
* @param c3 third point
306
* @return NOT_STRAIGHT, STRAIGHT_SPIKE or STRICTLY_STRAIGHT
308
public static int isHighPrecStraight(Coord c1, Coord c2, Coord c3) {
309
if (c1.highPrecEquals(c3))
310
return STRAIGHT_SPIKE;
312
long c1Lat = c1.getHighPrecLat();
313
long c2Lat = c2.getHighPrecLat();
314
long c3Lat = c3.getHighPrecLat();
315
long c1Lon = c1.getHighPrecLon();
316
long c2Lon = c2.getHighPrecLon();
317
long c3Lon = c3.getHighPrecLon();
318
// calculate the area that is enclosed by the three points
319
// (as if a closing line is drawn from c3 back to c1)
320
area = c1Lon * c2Lat - c2Lon * c1Lat;
321
area += c2Lon * c3Lat - c3Lon * c2Lat;
322
area += c3Lon * c1Lat - c1Lon * c3Lat;
324
// area is empty-> points lie on a straight line
325
long delta1 = c1Lat - c2Lat;
326
long delta2 = c2Lat - c3Lat;
327
if (delta1 < 0 && delta2 > 0 || delta1 > 0 && delta2 < 0)
328
return STRAIGHT_SPIKE;
329
delta1 = c1Lon - c2Lon;
330
delta2 = c2Lon - c3Lon;
331
if (delta1 < 0 && delta2 > 0 || delta1 > 0 && delta2 < 0)
332
return STRAIGHT_SPIKE;
333
return STRICTLY_STRAIGHT;
335
// line is not straight
341
* approximate atan2, much faster than Math.atan2()
342
* Based on a 50-year old arctan approximation due to Hastings
344
private final static double PI_BY_2 = Math.PI / 2;
346
public static double atan2_approximation( double y, double x )
350
if ( y > 0.0f ) return PI_BY_2 ;
351
if ( y == 0.0f ) return 0.0f;
356
if ( Math.abs( z ) < 1.0f )
358
atan = z/(1.0f + 0.28f*z*z);
361
if ( y < 0.0f ) return atan - Math.PI;
362
return atan + Math.PI;
367
atan = PI_BY_2 - z/(z*z + 0.28f);
368
if ( y < 0.0f ) return atan - Math.PI;
374
* calculate a long value for the latitude and longitude of a coord
377
* @return a long that can be used as a key in HashMaps
379
public static long coord2Long(Coord co){
380
int lat30 = co.getHighPrecLat();
381
int lon30 = co.getHighPrecLon();
383
return (long)(lat30 & 0xffffffffL) << 32 | (lon30 & 0xffffffffL);