1 #include "greatcircle.h"
5 static bool antipodes(const Coordinates
&c1
, const Coordinates
&c2
)
7 return ((qAbs(c1
.lat() + c2
.lat()) < DELTA
)
8 && (qAbs(180.0 - qAbs(c1
.lon() - c2
.lon())) < DELTA
));
11 GreatCircle::GreatCircle(const Coordinates
&c1
, const Coordinates
&c2
)
13 double lat1
, lon1
, lat2
, lon2
;
15 if (antipodes(c1
, c2
)) {
16 /* In case of antipodes (which would lead to garbage output without
17 this hack), move the points DELTA degrees closer to each other in
18 a way that the route never crosses the antimeridian. */
19 if (c1
.lon() < c2
.lon()) {
20 lon1
= deg2rad(c1
.lon() + DELTA
);
21 lon2
= deg2rad(c2
.lon() - DELTA
);
23 lon1
= deg2rad(c1
.lon() - DELTA
);
24 lon2
= deg2rad(c2
.lon() + DELTA
);
26 if (c1
.lat() < c2
.lat()) {
27 lat1
= deg2rad(c1
.lat() + DELTA
);
28 lat2
= deg2rad(c2
.lat() - DELTA
);
30 lat1
= deg2rad(c1
.lat() - DELTA
);
31 lat2
= deg2rad(c2
.lat() + DELTA
);
34 lat1
= deg2rad(c1
.lat());
35 lon1
= deg2rad(c1
.lon());
36 lat2
= deg2rad(c2
.lat());
37 lon2
= deg2rad(c2
.lon());
40 double cosLat1
= cos(lat1
);
41 double cosLat2
= cos(lat2
);
45 _xA
= cosLat1
* cos(lon1
);
46 _xB
= cosLat2
* cos(lon2
);
47 _yA
= cosLat1
* sin(lon1
);
48 _yB
= cosLat2
* sin(lon2
);
50 _d
= 2 * asin(sqrt(pow((sin((lat1
- lat2
) / 2)), 2) + cosLat1
* cosLat2
51 * pow(sin((lon1
- lon2
) / 2), 2)));
55 Coordinates
GreatCircle::pointAt(double f
) const
57 double A
= sin((1.0 - f
) * _d
) / _sinD
;
58 double B
= sin(f
* _d
) / _sinD
;
59 double x
= A
* _xA
+ B
* _xB
;
60 double y
= A
* _yA
+ B
* _yB
;
61 double z
= A
* _sinLat1
+ B
* _sinLat2
;
63 return Coordinates(rad2deg(atan2(y
, x
)), rad2deg(atan2(z
, sqrt(x
*x
+ y
*y
))));