Renderer, ...: use PixelRect::GetCenter()
[xcsoar.git] / test / src / TestGeoPoint.cpp
blob41db349af0f4659d7ed41cba8b4f752c71872ea5
1 /* Copyright_License {
3 XCSoar Glide Computer - http://www.xcsoar.org/
4 Copyright (C) 2000-2013 The XCSoar Project
5 A detailed list of copyright holders can be found in the file "AUTHORS".
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 #include "Geo/GeoPoint.hpp"
24 #include "Geo/GeoVector.hpp"
25 #include "Geo/Math.hpp"
26 #include "Math/Angle.hpp"
27 #include "Math/fixed.hpp"
29 #include "TestUtil.hpp"
32 #include <cstdio>
34 int main(int argc, char **argv)
36 plan_tests(66);
38 // test constructor
39 GeoPoint p1(Angle::Degrees(345.32), Angle::Degrees(-6.332));
40 ok1(p1.IsValid());
41 ok1(equals(p1, -6.332, 345.32));
43 // test normalize()
44 p1.Normalize();
45 ok1(p1.IsValid());
46 ok1(equals(p1, -6.332, -14.68));
48 // test parametric()
49 GeoPoint p2(Angle::Degrees(2), Angle::Degrees(1));
50 GeoPoint p3 = p1.Parametric(p2, fixed(5));
51 ok1(p2.IsValid());
52 ok1(p3.IsValid());
53 ok1(equals(p3, -1.332, -4.68));
55 // test interpolate
56 GeoPoint p4 = p1.Interpolate(p3, fixed(0.5));
57 ok1(p4.IsValid());
58 ok1(equals(p4, -3.832, -9.68));
60 GeoPoint p5 = p1.Interpolate(p3, fixed(0.25));
61 ok1(p5.IsValid());
62 ok1(equals(p5, -5.082, -12.18));
64 // test *
65 GeoPoint p6 = p2 * fixed(3.5);
66 ok1(p6.IsValid());
67 ok1(equals(p6, 3.5, 7));
69 // test +
70 p6 = p6 + p2;
71 ok1(p6.IsValid());
72 ok1(equals(p6, 4.5, 9));
74 // test +=
75 p6 += p2;
76 ok1(p6.IsValid());
77 ok1(equals(p6, 5.5, 11));
79 // test -
80 p6 = p6 - p2;
81 ok1(p6.IsValid());
82 ok1(equals(p6, 4.5, 9));
84 // test sort()
85 ok1(!p1.Sort(p3));
86 ok1(p3.Sort(p1));
87 ok1(!p1.Sort(p4));
88 ok1(p4.Sort(p1));
89 ok1(!p1.Sort(p5));
90 ok1(p5.Sort(p1));
91 ok1(!p4.Sort(p3));
92 ok1(p3.Sort(p4));
93 ok1(!p5.Sort(p3));
94 ok1(p3.Sort(p5));
95 ok1(!p5.Sort(p4));
96 ok1(p4.Sort(p5));
98 // test distance()
100 // note: distance between p1 and p4 and between p3 and p4 is not
101 // the same due to linear interpolation instead of real geographic
102 // intermediate point calculation
103 ok1(equals(p2.Distance(p6), 869326.653160));
104 ok1(equals(p6.Distance(p2), 869326.653160));
105 ok1(equals(p1.Distance(p5), 309562.219016));
106 ok1(equals(p1.Distance(p4), 619603.149273));
107 ok1(equals(p1.Distance(p3), 1240649.267606));
108 ok1(equals(p3.Distance(p4), 621053.760625));
110 // test bearing()
112 // note: the bearings p1 -> p5, p5 -> p4 and so on are not the same due to
113 // linear interpolation instead of real geographic intermediate point
114 // calculation
115 ok1(equals(p2.Bearing(p6), 63.272424));
116 ok1(equals(p6.Bearing(p2), 243.608847));
117 ok1(equals(p1.Bearing(p5), 63.449343));
118 ok1(equals(p1.Bearing(p4), 63.582620));
119 ok1(equals(p1.Bearing(p3), 63.784526));
120 ok1(equals(p5.Bearing(p4), 63.466726));
121 ok1(equals(p5.Bearing(p3), 63.646072));
122 ok1(equals(p4.Bearing(p3), 63.540756));
123 ok1(equals(p5.Bearing(p6), 65.982854));
124 ok1(equals(p2.Bearing(p3), 250.786774));
126 // test distance_bearing()
127 // note: should be the same output as bearing() and distance()
128 GeoVector v = p2.DistanceBearing(p6);
129 ok1(equals(v.distance, 869326.653160));
130 ok1(equals(v.bearing, 63.272424));
132 // test intermediate_point()
133 GeoPoint p7(Angle::Zero(), Angle::Zero());
134 ok1(p7.IsValid());
135 GeoPoint p8 = p7.IntermediatePoint(p2, fixed(100000));
136 ok1(p8.IsValid());
137 ok1(equals(p8, 0.402274, 0.804342));
138 ok1(equals(p8.Distance(p7), 100000));
139 GeoPoint p9 = p7.IntermediatePoint(p2, fixed(100000000));
140 ok1(p9.IsValid());
141 ok1(equals(p9, p2));
143 // test projected_distance()
144 ok1(equals(p8.ProjectedDistance(p7, p2), 100000));
145 ok1(equals(p4.ProjectedDistance(p1, p3), 619599.304393));
146 ok1(equals((p2 * fixed(2)).ProjectedDistance(p2, p6), 248567.832772));
148 // Tests moved here from test_fixed.cpp
149 GeoPoint l1(Angle::Zero(), Angle::Zero());
150 ok1(l1.IsValid());
151 GeoPoint l2(Angle::Degrees(-0.3), Angle::Degrees(1.0));
152 ok1(l2.IsValid());
153 GeoPoint l3(Angle::Degrees(0.00001), Angle::Zero());
154 ok1(l3.IsValid());
155 GeoPoint l4(Angle::Degrees(10), Angle::Zero());
156 ok1(l4.IsValid());
157 l4.SetInvalid();
158 ok1(!l4.IsValid());
160 bool find_lat_lon_okay = true;
161 for (Angle bearing = Angle::Zero(); bearing < Angle::FullCircle();
162 bearing += Angle::Degrees(5)) {
163 GeoPoint p_test = FindLatitudeLongitude(p1, bearing, fixed(50000));
164 find_lat_lon_okay = equals(p_test.Distance(p1), 50000) && find_lat_lon_okay;
166 ok1(find_lat_lon_okay);
168 v = l1.DistanceBearing(l2);
169 printf("Dist %g bearing %d\n",
170 FIXED_DOUBLE(v.distance), FIXED_INT(v.bearing.Degrees()));
171 // 116090 @ 343
173 v = l1.DistanceBearing(l3);
174 printf("Dist %g bearing %d\n",
175 FIXED_DOUBLE(v.distance), FIXED_INT(v.bearing.Degrees()));
176 ok(positive(v.distance) && v.distance < fixed(2), "earth distance short", 0);
178 v = l1.DistanceBearing(l4);
179 printf("Dist %g bearing %d\n",
180 FIXED_DOUBLE(v.distance), FIXED_INT(v.bearing.Degrees()));
182 GeoPoint p10(GeoPoint::Invalid());
183 ok1(!p10.IsValid());
186 return exit_status();