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/GeoClip.hpp"
24 #include "TestUtil.hpp"
28 static inline GeoPoint
29 make_geo_point(int longitude
, int latitude
)
31 return GeoPoint(Angle::Degrees(longitude
),
32 Angle::Degrees(latitude
));
36 test_ClipLine(const GeoClip
&clip
, GeoPoint a
, GeoPoint b
,
37 const GeoPoint a2
, const GeoPoint b2
)
47 GeoClip
clip(GeoBounds(make_geo_point(2, 5), make_geo_point(6, 1)));
50 test_ClipLine(clip
, make_geo_point(2, 5), make_geo_point(6, 1),
51 make_geo_point(2, 5), make_geo_point(6, 1));
53 /* clipping at east border */
54 test_ClipLine(clip
, make_geo_point(2, 4), make_geo_point(7, 4),
55 make_geo_point(2, 4), make_geo_point(6, 4));
57 /* clipping east & west */
58 test_ClipLine(clip
, make_geo_point(1, 4), make_geo_point(7, 4),
59 make_geo_point(2, 4), make_geo_point(6, 4));
62 test_ClipLine(clip
, make_geo_point(3, 7), make_geo_point(3, 2),
63 make_geo_point(3, 5), make_geo_point(3, 2));
65 /* clipping north & south */
66 test_ClipLine(clip
, make_geo_point(3, 7), make_geo_point(3, -1000),
67 make_geo_point(3, 5), make_geo_point(3, 1));
69 /* clipping southwest */
70 test_ClipLine(clip
, make_geo_point(5, 2), make_geo_point(7, 0),
71 make_geo_point(5, 2), make_geo_point(6, 1));
73 /* clipping northwest & southeast */
74 test_ClipLine(clip
, make_geo_point(0, 9), make_geo_point(9, -3),
75 make_geo_point(3, 5), make_geo_point(6, 1));
79 find(const GeoPoint
*haystack
, unsigned size
, const GeoPoint needle
)
81 for (unsigned i
= 0; i
< size
; ++i
)
82 if (equals(haystack
[i
], needle
))
88 equals(const GeoPoint
*a
, unsigned a_size
, const GeoPoint
*b
, unsigned b_size
)
96 int offset
= find(b
, b_size
, *a
);
100 for (unsigned i
= 0; i
< a_size
; ++i
) {
101 unsigned j
= (i
+ offset
) % a_size
;
102 if (!equals(a
[i
], b
[j
]))
110 test_clip_polygon(const GeoClip
&clip
, const GeoPoint
*src
, unsigned src_size
,
111 const GeoPoint
*result
, unsigned result_size
)
114 unsigned dest_size
= clip
.ClipPolygon(dest
, src
, src_size
);
115 ok1(equals(result
, result_size
, dest
, dest_size
));
121 GeoClip
clip(GeoBounds(make_geo_point(2, 5), make_geo_point(6, 1)));
123 /* invalid polygon */
124 const GeoPoint src1
[2] = {
125 make_geo_point(0, 0),
126 make_geo_point(1, 1),
129 test_clip_polygon(clip
, src1
, 0, NULL
, 0);
130 test_clip_polygon(clip
, src1
, 1, NULL
, 0);
131 test_clip_polygon(clip
, src1
, 2, NULL
, 0);
134 const GeoPoint src2
[3] = {
135 make_geo_point(3, 4),
136 make_geo_point(5, 4),
137 make_geo_point(3, 2),
139 test_clip_polygon(clip
, src2
, 3, src2
, 3);
141 /* one vertex clipped */
142 const GeoPoint src3
[3] = {
143 make_geo_point(3, 4),
144 make_geo_point(9, 4),
145 make_geo_point(3, 2),
147 const GeoPoint result3
[4] = {
148 make_geo_point(3, 4),
149 make_geo_point(6, 4),
150 make_geo_point(6, 3),
151 make_geo_point(3, 2),
153 test_clip_polygon(clip
, src3
, 3, result3
, 4);
155 /* two vertices clipped */
156 const GeoPoint src4
[3] = {
157 make_geo_point(1, 4),
158 make_geo_point(9, 4),
159 make_geo_point(3, 2),
161 const GeoPoint result4
[5] = {
162 make_geo_point(2, 3),
163 make_geo_point(2, 4),
164 make_geo_point(6, 4),
165 make_geo_point(6, 3),
166 make_geo_point(3, 2),
168 test_clip_polygon(clip
, src4
, 3, result4
, 5);
170 /* clipping a secant */
171 const GeoPoint src5
[3] = {
172 make_geo_point(1, 2),
173 make_geo_point(3, 2),
174 make_geo_point(3, 0),
176 const GeoPoint result5
[4] = {
177 make_geo_point(2, 1),
178 make_geo_point(2, 2),
179 make_geo_point(3, 2),
180 make_geo_point(3, 1),
182 test_clip_polygon(clip
, src5
, 3, result5
, 4);
184 /* all four vertices clipped */
185 const GeoPoint src6
[4] = {
186 make_geo_point(1, 3),
187 make_geo_point(4, 6),
188 make_geo_point(7, 3),
189 make_geo_point(4, 0),
191 const GeoPoint result6
[8] = {
192 make_geo_point(2, 4),
193 make_geo_point(3, 5),
194 make_geo_point(5, 5),
195 make_geo_point(6, 4),
196 make_geo_point(6, 2),
197 make_geo_point(5, 1),
198 make_geo_point(3, 1),
199 make_geo_point(2, 2),
201 test_clip_polygon(clip
, src6
, 4, result6
, 8);
203 /* rectangle full clip */
204 const GeoPoint src7
[4] = {
205 make_geo_point(-10, -10),
206 make_geo_point(-10, 10),
207 make_geo_point(10, 10),
208 make_geo_point(10, -10),
210 const GeoPoint result7
[4] = {
211 make_geo_point(2, 1),
212 make_geo_point(2, 5),
213 make_geo_point(6, 5),
214 make_geo_point(6, 1),
216 test_clip_polygon(clip
, src7
, 4, result7
, 4);
218 /* triangle full clip */
219 const GeoPoint src8
[3] = {
220 make_geo_point(-10, 50),
221 make_geo_point(50, 5),
222 make_geo_point(-5, -50),
224 test_clip_polygon(clip
, src8
, 3, result7
, 4);
227 int main(int argc
, char **argv
)
234 return exit_status();