source: inundation/utilities/test_polygon.py @ 1995

Last change on this file since 1995 was 1910, checked in by ole, 19 years ago

Made utilities a Python package
Added numerical_tools (and test) containing ensure_numeric from the old util module.
Added test_polygon.py

File size: 10.6 KB
Line 
1#!/usr/bin/env python
2
3
4import unittest
5from Numeric import zeros, array, allclose
6from math import sqrt, pi
7
8from polygon import *
9
10
11def test_function(x, y):
12    return x+y
13
14class Test_Polygon(unittest.TestCase):
15    def setUp(self):
16        pass
17
18    def tearDown(self):
19        pass
20
21
22    def test_that_C_extension_compiles(self):
23        FN = 'polygon_ext.c'
24        try:
25            import polygon_ext
26        except:
27            from compile import compile
28
29            try:
30                compile(FN)
31            except:
32                raise 'Could not compile %s' %FN
33            else:
34                import polygon_ext
35
36
37    #Polygon stuff
38    def test_polygon_function_constants(self):
39        p1 = [[0,0], [10,0], [10,10], [0,10]]
40        p2 = [[0,0], [10,10], [15,5], [20, 10], [25,0], [30,10], [40,-10]]
41
42        f = Polygon_function( [(p1, 1.0)] )
43        z = f([5, 5, 27, 35], [5, 9, 8, -5]) #Two first inside p1
44        assert allclose(z, [1,1,0,0])
45
46
47        f = Polygon_function( [(p2, 2.0)] )
48        z = f([5, 5, 27, 35], [5, 9, 8, -5]) #First and last inside p2
49        assert allclose(z, [2,0,0,2])
50
51
52        #Combined
53        f = Polygon_function( [(p1, 1.0), (p2, 2.0)] )
54        z = f([5, 5, 27, 35], [5, 9, 8, -5])
55        assert allclose(z, [2,1,0,2])
56
57
58    def test_polygon_function_callable(self):
59        """Check that values passed into Polygon_function can be callable
60        themselves.
61        """
62        p1 = [[0,0], [10,0], [10,10], [0,10]]
63        p2 = [[0,0], [10,10], [15,5], [20, 10], [25,0], [30,10], [40,-10]]
64
65        f = Polygon_function( [(p1, test_function)] )
66        z = f([5, 5, 27, 35], [5, 9, 8, -5]) #Two first inside p1
67        assert allclose(z, [10,14,0,0])
68
69        #Combined
70        f = Polygon_function( [(p1, test_function), (p2, 2.0)] )
71        z = f([5, 5, 27, 35], [5, 9, 8, -5])
72        assert allclose(z, [2,14,0,2])
73
74
75        #Combined w default
76        f = Polygon_function( [(p1, test_function), (p2, 2.0)], default = 3.14)
77        z = f([5, 5, 27, 35], [5, 9, 8, -5])
78        assert allclose(z, [2,14,3.14,2])
79
80
81        #Combined w default func
82        f = Polygon_function( [(p1, test_function), (p2, 2.0)],
83                              default = test_function)
84        z = f([5, 5, 27, 35], [5, 9, 8, -5])
85        assert allclose(z, [2,14,35,2])
86
87
88    def test_point_on_line(self):
89
90        #Endpoints first
91        assert point_on_line( 0, 0, 0,0, 1,0 )
92        assert point_on_line( 1, 0, 0,0, 1,0 )
93
94        #Then points on line
95        assert point_on_line( 0.5, 0, 0,0, 1,0 )
96        assert point_on_line( 0, 0.5, 0,1, 0,0 )
97        assert point_on_line( 1, 0.5, 1,1, 1,0 )
98        assert point_on_line( 0.5, 0.5, 0,0, 1,1 )
99
100        #Then points not on line
101        assert not point_on_line( 0.5, 0, 0,1, 1,1 )
102        assert not point_on_line( 0, 0.5, 0,0, 1,1 )
103
104        #From real example that failed
105        assert not point_on_line( 40,50, 40,20, 40,40 )
106
107
108        #From real example that failed
109        assert not point_on_line( 40,19, 40,20, 40,40 )
110
111
112
113
114    def test_inside_polygon_main(self):
115
116
117        #Simplest case: Polygon is the unit square
118        polygon = [[0,0], [1,0], [1,1], [0,1]]
119
120        assert inside_polygon( (0.5, 0.5), polygon )
121        assert not inside_polygon( (0.5, 1.5), polygon )
122        assert not inside_polygon( (0.5, -0.5), polygon )
123        assert not inside_polygon( (-0.5, 0.5), polygon )
124        assert not inside_polygon( (1.5, 0.5), polygon )
125
126        #Try point on borders
127        assert inside_polygon( (1., 0.5), polygon, closed=True)
128        assert inside_polygon( (0.5, 1), polygon, closed=True)
129        assert inside_polygon( (0., 0.5), polygon, closed=True)
130        assert inside_polygon( (0.5, 0.), polygon, closed=True)
131
132        assert not inside_polygon( (0.5, 1), polygon, closed=False)
133        assert not inside_polygon( (0., 0.5), polygon, closed=False)
134        assert not inside_polygon( (0.5, 0.), polygon, closed=False)
135        assert not inside_polygon( (1., 0.5), polygon, closed=False)
136
137
138
139        #From real example (that failed)
140        polygon = [[20,20], [40,20], [40,40], [20,40]]
141        points = [ [40, 50] ]
142        res = inside_polygon(points, polygon)
143        assert len(res) == 0
144
145        polygon = [[20,20], [40,20], [40,40], [20,40]]
146        points = [ [25, 25], [30, 20], [40, 50], [90, 20], [40, 90] ]
147        res = inside_polygon(points, polygon)
148        assert len(res) == 2
149        assert allclose(res, [0,1])
150
151
152
153        #More convoluted and non convex polygon
154        polygon = [[0,0], [1,0], [0.5,-1], [2, -1], [2,1], [0,1]]
155        assert inside_polygon( (0.5, 0.5), polygon )
156        assert inside_polygon( (1, -0.5), polygon )
157        assert inside_polygon( (1.5, 0), polygon )
158
159        assert not inside_polygon( (0.5, 1.5), polygon )
160        assert not inside_polygon( (0.5, -0.5), polygon )
161
162
163        #Very convoluted polygon
164        polygon = [[0,0], [10,10], [15,5], [20, 10], [25,0], [30,10], [40,-10]]
165        assert inside_polygon( (5, 5), polygon )
166        assert inside_polygon( (17, 7), polygon )
167        assert inside_polygon( (27, 2), polygon )
168        assert inside_polygon( (35, -5), polygon )
169        assert not inside_polygon( (15, 7), polygon )
170        assert not inside_polygon( (24, 3), polygon )
171        assert not inside_polygon( (25, -10), polygon )
172
173
174
175        #Another combination (that failed)
176        polygon = [[0,0], [10,0], [10,10], [0,10]]
177        assert inside_polygon( (5, 5), polygon )
178        assert inside_polygon( (7, 7), polygon )
179        assert not inside_polygon( (-17, 7), polygon )
180        assert not inside_polygon( (7, 17), polygon )
181        assert not inside_polygon( (17, 7), polygon )
182        assert not inside_polygon( (27, 8), polygon )
183        assert not inside_polygon( (35, -5), polygon )
184
185
186
187
188        #Multiple polygons
189
190        polygon = [[0,0], [1,0], [1,1], [0,1], [0,0],
191                   [10,10], [11,10], [11,11], [10,11], [10,10]]
192        assert inside_polygon( (0.5, 0.5), polygon )
193        assert inside_polygon( (10.5, 10.5), polygon )
194
195        #FIXME: Fails if point is 5.5, 5.5
196        assert not inside_polygon( (0, 5.5), polygon )
197
198        #Polygon with a hole
199        polygon = [[-1,-1], [2,-1], [2,2], [-1,2], [-1,-1],
200                   [0,0], [1,0], [1,1], [0,1], [0,0]]
201
202        assert inside_polygon( (0, -0.5), polygon )
203        assert not inside_polygon( (0.5, 0.5), polygon )
204
205    def test_inside_polygon_vector_version(self):
206        #Now try the vector formulation returning indices
207        polygon = [[0,0], [1,0], [0.5,-1], [2, -1], [2,1], [0,1]]
208        points = [ [0.5, 0.5], [1, -0.5], [1.5, 0], [0.5, 1.5], [0.5, -0.5]]
209        res = inside_polygon( points, polygon, verbose=False )
210
211        assert allclose( res, [0,1,2] )
212
213    def test_outside_polygon(self):
214        U = [[0,0], [1,0], [1,1], [0,1]] #Unit square   
215
216        assert not outside_polygon( [0.5, 0.5], U )
217        #evaluate to False as the point 0.5, 0.5 is inside the unit square
218       
219        assert outside_polygon( [1.5, 0.5], U )
220        #evaluate to True as the point 1.5, 0.5 is outside the unit square
221       
222        indices = outside_polygon( [[0.5, 0.5], [1, -0.5], [0.3, 0.2]], U )
223        assert allclose( indices, [1] )
224       
225        #One more test of vector formulation returning indices
226        polygon = [[0,0], [1,0], [0.5,-1], [2, -1], [2,1], [0,1]]
227        points = [ [0.5, 0.5], [1, -0.5], [1.5, 0], [0.5, 1.5], [0.5, -0.5]]
228        res = outside_polygon( points, polygon )
229
230        assert allclose( res, [3, 4] )
231
232
233
234        polygon = [[0,0], [1,0], [0.5,-1], [2, -1], [2,1], [0,1]]
235        points = [ [0.5, 1.4], [0.5, 0.5], [1, -0.5], [1.5, 0], [0.5, 1.5], [0.5, -0.5]]
236        res = outside_polygon( points, polygon )
237
238        assert allclose( res, [0, 4, 5] )       
239     
240    def test_outside_polygon2(self):
241        U = [[0,0], [1,0], [1,1], [0,1]] #Unit square   
242   
243        assert not outside_polygon( [0.5, 1.0], U, closed = True )
244        #evaluate to False as the point 0.5, 1.0 is inside the unit square
245       
246        assert outside_polygon( [0.5, 1.0], U, closed = False )
247        #evaluate to True as the point 0.5, 1.0 is outside the unit square
248
249    def test_separate_points_by_polygon(self):
250        U = [[0,0], [1,0], [1,1], [0,1]] #Unit square   
251
252        indices, count = separate_points_by_polygon( [[0.5, 0.5], [1, -0.5], [0.3, 0.2]], U )
253        assert allclose( indices, [0,2,1] )
254        assert count == 2
255       
256        #One more test of vector formulation returning indices
257        polygon = [[0,0], [1,0], [0.5,-1], [2, -1], [2,1], [0,1]]
258        points = [ [0.5, 0.5], [1, -0.5], [1.5, 0], [0.5, 1.5], [0.5, -0.5]]
259        res, count = separate_points_by_polygon( points, polygon )
260
261        assert allclose( res, [0,1,2,4,3] )
262        assert count == 3
263
264
265        polygon = [[0,0], [1,0], [0.5,-1], [2, -1], [2,1], [0,1]]
266        points = [ [0.5, 1.4], [0.5, 0.5], [1, -0.5], [1.5, 0], [0.5, 1.5], [0.5, -0.5]]
267        res, count = separate_points_by_polygon( points, polygon )
268
269        assert allclose( res, [1,2,3,5,4,0] )       
270        assert count == 3
271       
272
273    def test_populate_polygon(self):
274
275        polygon = [[0,0], [1,0], [1,1], [0,1]]
276        points = populate_polygon(polygon, 5)
277
278        assert len(points) == 5
279        for point in points:
280            assert inside_polygon(point, polygon)
281
282
283        #Very convoluted polygon
284        polygon = [[0,0], [10,10], [15,5], [20, 10], [25,0], [30,10], [40,-10]]
285
286        points = populate_polygon(polygon, 5)
287
288        assert len(points) == 5
289        for point in points:
290            assert inside_polygon(point, polygon)
291
292
293    def test_populate_polygon_with_exclude(self):
294       
295
296        polygon = [[0,0], [1,0], [1,1], [0,1]]
297        ex_poly = [[0,0], [0.5,0], [0.5, 0.5], [0,0.5]] #SW quarter
298        points = populate_polygon(polygon, 5, exclude = [ex_poly])
299
300        assert len(points) == 5
301        for point in points:
302            assert inside_polygon(point, polygon)
303            assert not inside_polygon(point, ex_poly)           
304
305
306        #overlap
307        polygon = [[0,0], [1,0], [1,1], [0,1]]
308        ex_poly = [[-1,-1], [0.5,0], [0.5, 0.5], [-1,0.5]]
309        points = populate_polygon(polygon, 5, exclude = [ex_poly])
310
311        assert len(points) == 5
312        for point in points:
313            assert inside_polygon(point, polygon)
314            assert not inside_polygon(point, ex_poly)                       
315       
316        #Multiple
317        polygon = [[0,0], [1,0], [1,1], [0,1]]
318        ex_poly1 = [[0,0], [0.5,0], [0.5, 0.5], [0,0.5]] #SW quarter
319        ex_poly2 = [[0.5,0.5], [0.5,1], [1, 1], [1,0.5]] #NE quarter       
320       
321        points = populate_polygon(polygon, 20, exclude = [ex_poly1, ex_poly2])
322
323        assert len(points) == 20
324        for point in points:
325            assert inside_polygon(point, polygon)
326            assert not inside_polygon(point, ex_poly1)
327            assert not inside_polygon(point, ex_poly2)                               
328       
329
330        #Very convoluted polygon
331        polygon = [[0,0], [10,10], [15,5], [20, 10], [25,0], [30,10], [40,-10]]
332        ex_poly = [[-1,-1], [5,0], [5, 5], [-1,5]]
333        points = populate_polygon(polygon, 20, exclude = [ex_poly])
334       
335        assert len(points) == 20
336        for point in points:
337            assert inside_polygon(point, polygon)
338            assert not inside_polygon(point, ex_poly), '%s' %str(point)                       
339
340
341
342#-------------------------------------------------------------
343if __name__ == "__main__":
344    suite = unittest.makeSuite(Test_Polygon,'test')
345    runner = unittest.TextTestRunner()
346    runner.run(suite)
347
348
349
350
Note: See TracBrowser for help on using the repository browser.