[258] | 1 | #!/usr/bin/env python |
---|
| 2 | # |
---|
| 3 | |
---|
| 4 | import unittest |
---|
| 5 | from Numeric import zeros, array, allclose |
---|
| 6 | from math import sqrt, pi |
---|
| 7 | |
---|
| 8 | from util import * |
---|
| 9 | from config import epsilon |
---|
| 10 | |
---|
[664] | 11 | |
---|
| 12 | def test_function(x, y): |
---|
| 13 | return x+y |
---|
| 14 | |
---|
[258] | 15 | class TestCase(unittest.TestCase): |
---|
| 16 | def setUp(self): |
---|
| 17 | pass |
---|
| 18 | |
---|
| 19 | def tearDown(self): |
---|
| 20 | pass |
---|
| 21 | |
---|
| 22 | |
---|
| 23 | def test_gradient(self): |
---|
| 24 | x0 = 0.0; y0 = 0.0; z0 = 0.0 |
---|
| 25 | x1 = 1.0; y1 = 0.0; z1 = -1.0 |
---|
| 26 | x2 = 0.0; y2 = 1.0; z2 = 0.0 |
---|
| 27 | |
---|
| 28 | zx, zy = gradient(x0, y0, x1, y1, x2, y2, z0, z1, z2) |
---|
| 29 | |
---|
| 30 | assert zx == -1.0 |
---|
| 31 | assert zy == 0.0 |
---|
| 32 | |
---|
| 33 | |
---|
| 34 | |
---|
| 35 | |
---|
| 36 | def test_gradient2(self): |
---|
| 37 | |
---|
| 38 | from util import gradient |
---|
| 39 | x0 = 2.0/3; y0 = 2.0/3 |
---|
| 40 | x1= 8.0/3; y1 = 2.0/3 |
---|
| 41 | x2 = 2.0/3; y2 = 8.0/3 |
---|
| 42 | |
---|
| 43 | q0 = 2.0+2.0/3 |
---|
| 44 | q1 = 8.0+2.0/3 |
---|
| 45 | q2 = 2.0+8.0/3 |
---|
| 46 | |
---|
| 47 | #Gradient of fitted pwl surface |
---|
| 48 | a, b = gradient(x0, y0, x1, y1, x2, y2, q0, q1, q2) |
---|
| 49 | |
---|
| 50 | assert abs(a - 3.0) < epsilon |
---|
| 51 | assert abs(b - 1.0) < epsilon |
---|
| 52 | |
---|
| 53 | |
---|
| 54 | |
---|
| 55 | def test_that_C_extension_compiles(self): |
---|
| 56 | FN = 'util_ext.c' |
---|
| 57 | try: |
---|
| 58 | import util_ext |
---|
| 59 | except: |
---|
| 60 | from compile import compile |
---|
| 61 | |
---|
| 62 | try: |
---|
| 63 | compile(FN) |
---|
| 64 | except: |
---|
| 65 | raise 'Could not compile %s' %FN |
---|
| 66 | else: |
---|
| 67 | import util_ext |
---|
| 68 | |
---|
| 69 | |
---|
| 70 | def test_gradient_C_extension(self): |
---|
| 71 | from util_ext import gradient as gradient_c |
---|
| 72 | |
---|
| 73 | x0 = 2.0/3; y0 = 2.0/3 |
---|
| 74 | x1= 8.0/3; y1 = 2.0/3 |
---|
| 75 | x2 = 2.0/3; y2 = 8.0/3 |
---|
| 76 | |
---|
| 77 | q0 = 2.0+2.0/3 |
---|
| 78 | q1 = 8.0+2.0/3 |
---|
| 79 | q2 = 2.0+8.0/3 |
---|
| 80 | |
---|
| 81 | #Gradient of fitted pwl surface |
---|
| 82 | a, b = gradient_c(x0, y0, x1, y1, x2, y2, q0, q1, q2) |
---|
| 83 | |
---|
| 84 | assert abs(a - 3.0) < epsilon |
---|
| 85 | assert abs(b - 1.0) < epsilon |
---|
| 86 | |
---|
| 87 | |
---|
| 88 | def test_gradient_C_extension3(self): |
---|
| 89 | from util_ext import gradient as gradient_c |
---|
| 90 | |
---|
| 91 | from RandomArray import uniform, seed |
---|
| 92 | seed(17, 53) |
---|
| 93 | |
---|
| 94 | x0, x1, x2, y0, y1, y2 = uniform(0.0,3.0,6) |
---|
| 95 | |
---|
| 96 | q0 = uniform(0.0, 10.0, 4) |
---|
| 97 | q1 = uniform(1.0, 3.0, 4) |
---|
| 98 | q2 = uniform(7.0, 20.0, 4) |
---|
| 99 | |
---|
| 100 | |
---|
| 101 | for i in range(4): |
---|
| 102 | #Gradient of fitted pwl surface |
---|
| 103 | from util import gradient_python |
---|
| 104 | a_ref, b_ref = gradient(x0, y0, x1, y1, x2, y2, |
---|
| 105 | q0[i], q1[i], q2[i]) |
---|
| 106 | |
---|
| 107 | #print a_ref, b_ref |
---|
| 108 | a, b = gradient_c(x0, y0, x1, y1, x2, y2, |
---|
| 109 | q0[i], q1[i], q2[i]) |
---|
| 110 | |
---|
| 111 | #print a, a_ref, b, b_ref |
---|
| 112 | assert abs(a - a_ref) < epsilon |
---|
| 113 | assert abs(b - b_ref) < epsilon |
---|
| 114 | |
---|
| 115 | |
---|
| 116 | |
---|
| 117 | #Geometric |
---|
| 118 | #def test_distance(self): |
---|
| 119 | # from util import distance# |
---|
| 120 | # |
---|
| 121 | # self.failUnless( distance([4,2],[7,6]) == 5.0, |
---|
| 122 | # 'Distance is wrong!') |
---|
| 123 | # self.failUnless( allclose(distance([7,6],[9,8]), 2.82842712475), |
---|
| 124 | # 'distance is wrong!') |
---|
| 125 | # self.failUnless( allclose(distance([9,8],[4,2]), 7.81024967591), |
---|
| 126 | # 'distance is wrong!') |
---|
| 127 | # |
---|
| 128 | # self.failUnless( distance([9,8],[4,2]) == distance([4,2],[9,8]), |
---|
| 129 | # 'distance is wrong!') |
---|
| 130 | |
---|
| 131 | def test_angle(self): |
---|
| 132 | from util import angle |
---|
| 133 | |
---|
| 134 | assert allclose(angle([1.0, 1.0])/pi*180, 45.0) |
---|
| 135 | |
---|
| 136 | |
---|
| 137 | def test_anglediff(self): |
---|
| 138 | from util import anglediff |
---|
| 139 | |
---|
| 140 | assert allclose(anglediff([0.0, 1.], [1.0, 1.0])/pi*180, 45.0) |
---|
| 141 | |
---|
| 142 | |
---|
| 143 | |
---|
[623] | 144 | |
---|
| 145 | def test_file_function_time(self): |
---|
| 146 | """Test that File function interpolates correctly |
---|
| 147 | between given times. No x,y dependency here. |
---|
| 148 | """ |
---|
| 149 | |
---|
| 150 | #Write file |
---|
| 151 | import os, time |
---|
| 152 | from config import time_format |
---|
| 153 | from math import sin, pi |
---|
| 154 | |
---|
| 155 | finaltime = 1200 |
---|
| 156 | filename = 'test_file_function.txt' |
---|
| 157 | fid = open(filename, 'w') |
---|
| 158 | start = time.mktime(time.strptime('2000', '%Y')) |
---|
| 159 | dt = 60 #One minute intervals |
---|
| 160 | t = 0.0 |
---|
| 161 | while t <= finaltime: |
---|
| 162 | t_string = time.strftime(time_format, time.gmtime(t+start)) |
---|
| 163 | fid.write('%s, %f %f %f\n' %(t_string, 2*t, t**2, sin(t*pi/600))) |
---|
| 164 | t += dt |
---|
| 165 | |
---|
| 166 | fid.close() |
---|
| 167 | |
---|
| 168 | F = File_function(filename) |
---|
| 169 | |
---|
| 170 | #Now try interpolation |
---|
| 171 | for i in range(20): |
---|
| 172 | t = i*10 |
---|
| 173 | q = F(t) |
---|
| 174 | |
---|
| 175 | #Exact linear intpolation |
---|
| 176 | assert allclose(q[0], 2*t) |
---|
| 177 | if i%6 == 0: |
---|
| 178 | assert allclose(q[1], t**2) |
---|
| 179 | assert allclose(q[2], sin(t*pi/600)) |
---|
| 180 | |
---|
| 181 | #Check non-exact |
---|
| 182 | |
---|
| 183 | t = 90 #Halfway between 60 and 120 |
---|
| 184 | q = F(t) |
---|
| 185 | assert allclose( (120**2 + 60**2)/2, q[1] ) |
---|
| 186 | assert allclose( (sin(120*pi/600) + sin(60*pi/600))/2, q[2] ) |
---|
| 187 | |
---|
| 188 | |
---|
| 189 | t = 100 #Two thirds of the way between between 60 and 120 |
---|
| 190 | q = F(t) |
---|
| 191 | assert allclose( 2*120**2/3 + 60**2/3, q[1] ) |
---|
| 192 | assert allclose( 2*sin(120*pi/600)/3 + sin(60*pi/600)/3, q[2] ) |
---|
| 193 | |
---|
| 194 | |
---|
| 195 | |
---|
| 196 | |
---|
| 197 | def test_file_function_time_with_domain(self): |
---|
| 198 | """Test that File function interpolates correctly |
---|
| 199 | between given times. No x,y dependency here. |
---|
| 200 | Use domain with starttime |
---|
| 201 | """ |
---|
| 202 | |
---|
| 203 | #Write file |
---|
| 204 | import os, time, calendar |
---|
| 205 | from config import time_format |
---|
| 206 | from math import sin, pi |
---|
| 207 | from domain import Domain |
---|
| 208 | |
---|
| 209 | finaltime = 1200 |
---|
| 210 | filename = 'test_file_function.txt' |
---|
| 211 | fid = open(filename, 'w') |
---|
| 212 | start = time.mktime(time.strptime('2000', '%Y')) |
---|
| 213 | dt = 60 #One minute intervals |
---|
| 214 | t = 0.0 |
---|
| 215 | while t <= finaltime: |
---|
| 216 | t_string = time.strftime(time_format, time.gmtime(t+start)) |
---|
| 217 | fid.write('%s, %f %f %f\n' %(t_string, 2*t, t**2, sin(t*pi/600))) |
---|
| 218 | t += dt |
---|
| 219 | |
---|
| 220 | fid.close() |
---|
| 221 | |
---|
| 222 | a = [0.0, 0.0] |
---|
| 223 | b = [4.0, 0.0] |
---|
| 224 | c = [0.0, 3.0] |
---|
| 225 | |
---|
| 226 | points = [a, b, c] |
---|
| 227 | vertices = [[0,1,2]] |
---|
| 228 | domain = Domain(points, vertices) |
---|
| 229 | |
---|
| 230 | #Check that domain.starttime is updated if non-existing |
---|
| 231 | F = File_function(filename, domain) |
---|
| 232 | assert allclose(domain.starttime, start) |
---|
| 233 | |
---|
| 234 | #Check that domain.starttime is updated if too early |
---|
| 235 | domain.starttime = start - 1 |
---|
| 236 | F = File_function(filename, domain) |
---|
| 237 | assert allclose(domain.starttime, start) |
---|
| 238 | |
---|
| 239 | #Check that domain.starttime isn't updated if later |
---|
[629] | 240 | #domain.starttime = start + 1 |
---|
| 241 | #F = File_function(filename, domain) |
---|
| 242 | #assert allclose(domain.starttime, start+1) |
---|
[623] | 243 | |
---|
| 244 | |
---|
| 245 | |
---|
| 246 | #Now try interpolation |
---|
| 247 | for i in range(20): |
---|
| 248 | t = i*10 |
---|
| 249 | q = F(t) |
---|
| 250 | |
---|
| 251 | #Exact linear intpolation |
---|
| 252 | assert allclose(q[0], 2*t) |
---|
| 253 | if i%6 == 0: |
---|
| 254 | assert allclose(q[1], t**2) |
---|
| 255 | assert allclose(q[2], sin(t*pi/600)) |
---|
| 256 | |
---|
| 257 | #Check non-exact |
---|
| 258 | |
---|
| 259 | t = 90 #Halfway between 60 and 120 |
---|
| 260 | q = F(t) |
---|
| 261 | assert allclose( (120**2 + 60**2)/2, q[1] ) |
---|
| 262 | assert allclose( (sin(120*pi/600) + sin(60*pi/600))/2, q[2] ) |
---|
| 263 | |
---|
| 264 | |
---|
| 265 | t = 100 #Two thirds of the way between between 60 and 120 |
---|
| 266 | q = F(t) |
---|
| 267 | assert allclose( 2*120**2/3 + 60**2/3, q[1] ) |
---|
| 268 | assert allclose( 2*sin(120*pi/600)/3 + sin(60*pi/600)/3, q[2] ) |
---|
| 269 | |
---|
[629] | 270 | |
---|
| 271 | |
---|
| 272 | def test_file_function_time_with_domain_different_start(self): |
---|
| 273 | """Test that File function interpolates correctly |
---|
| 274 | between given times. No x,y dependency here. |
---|
| 275 | Use domain with a starttime later than that of file |
---|
| 276 | """ |
---|
| 277 | |
---|
| 278 | #Write file |
---|
| 279 | import os, time, calendar |
---|
| 280 | from config import time_format |
---|
| 281 | from math import sin, pi |
---|
| 282 | from domain import Domain |
---|
| 283 | |
---|
| 284 | finaltime = 1200 |
---|
| 285 | filename = 'test_file_function.txt' |
---|
| 286 | fid = open(filename, 'w') |
---|
| 287 | start = time.mktime(time.strptime('2000', '%Y')) |
---|
| 288 | dt = 60 #One minute intervals |
---|
| 289 | t = 0.0 |
---|
| 290 | while t <= finaltime: |
---|
| 291 | t_string = time.strftime(time_format, time.gmtime(t+start)) |
---|
| 292 | fid.write('%s, %f %f %f\n' %(t_string, 2*t, t**2, sin(t*pi/600))) |
---|
| 293 | t += dt |
---|
| 294 | |
---|
| 295 | fid.close() |
---|
| 296 | |
---|
| 297 | a = [0.0, 0.0] |
---|
| 298 | b = [4.0, 0.0] |
---|
| 299 | c = [0.0, 3.0] |
---|
| 300 | |
---|
| 301 | points = [a, b, c] |
---|
| 302 | vertices = [[0,1,2]] |
---|
| 303 | domain = Domain(points, vertices) |
---|
| 304 | |
---|
| 305 | #Check that domain.starttime isn't updated if later |
---|
| 306 | delta = 23 |
---|
| 307 | domain.starttime = start + delta |
---|
| 308 | F = File_function(filename, domain) |
---|
| 309 | assert allclose(domain.starttime, start+delta) |
---|
| 310 | |
---|
| 311 | |
---|
| 312 | |
---|
| 313 | |
---|
| 314 | #Now try interpolation with delta offset |
---|
| 315 | for i in range(20): |
---|
| 316 | t = i*10 |
---|
| 317 | q = F(t-delta) |
---|
| 318 | |
---|
| 319 | #Exact linear intpolation |
---|
| 320 | assert allclose(q[0], 2*t) |
---|
| 321 | if i%6 == 0: |
---|
| 322 | assert allclose(q[1], t**2) |
---|
| 323 | assert allclose(q[2], sin(t*pi/600)) |
---|
| 324 | |
---|
| 325 | #Check non-exact |
---|
| 326 | |
---|
| 327 | t = 90 #Halfway between 60 and 120 |
---|
| 328 | q = F(t-delta) |
---|
| 329 | assert allclose( (120**2 + 60**2)/2, q[1] ) |
---|
| 330 | assert allclose( (sin(120*pi/600) + sin(60*pi/600))/2, q[2] ) |
---|
| 331 | |
---|
| 332 | |
---|
| 333 | t = 100 #Two thirds of the way between between 60 and 120 |
---|
| 334 | q = F(t-delta) |
---|
| 335 | assert allclose( 2*120**2/3 + 60**2/3, q[1] ) |
---|
| 336 | assert allclose( 2*sin(120*pi/600)/3 + sin(60*pi/600)/3, q[2] ) |
---|
| 337 | |
---|
[656] | 338 | |
---|
| 339 | |
---|
[664] | 340 | def test_polygon_function_constants(self): |
---|
[656] | 341 | p1 = [[0,0], [10,0], [10,10], [0,10]] |
---|
| 342 | p2 = [[0,0], [10,10], [15,5], [20, 10], [25,0], [30,10], [40,-10]] |
---|
| 343 | |
---|
| 344 | f = Polygon_function( [(p1, 1.0)] ) |
---|
| 345 | z = f([5, 5, 27, 35], [5, 9, 8, -5]) #Two first inside p1 |
---|
| 346 | assert allclose(z, [1,1,0,0]) |
---|
| 347 | |
---|
| 348 | |
---|
| 349 | f = Polygon_function( [(p2, 2.0)] ) |
---|
| 350 | z = f([5, 5, 27, 35], [5, 9, 8, -5]) #First and last inside p2 |
---|
| 351 | assert allclose(z, [2,0,0,2]) |
---|
| 352 | |
---|
| 353 | |
---|
| 354 | #Combined |
---|
| 355 | f = Polygon_function( [(p1, 1.0), (p2, 2.0)] ) |
---|
| 356 | z = f([5, 5, 27, 35], [5, 9, 8, -5]) |
---|
| 357 | assert allclose(z, [2,1,0,2]) |
---|
| 358 | |
---|
| 359 | |
---|
[664] | 360 | def test_polygon_function_callable(self): |
---|
| 361 | """Check that values passed into Polygon_function can be callable |
---|
| 362 | themselves. |
---|
| 363 | """ |
---|
| 364 | p1 = [[0,0], [10,0], [10,10], [0,10]] |
---|
| 365 | p2 = [[0,0], [10,10], [15,5], [20, 10], [25,0], [30,10], [40,-10]] |
---|
[656] | 366 | |
---|
[664] | 367 | f = Polygon_function( [(p1, test_function)] ) |
---|
| 368 | z = f([5, 5, 27, 35], [5, 9, 8, -5]) #Two first inside p1 |
---|
| 369 | assert allclose(z, [10,14,0,0]) |
---|
| 370 | |
---|
| 371 | #Combined |
---|
| 372 | f = Polygon_function( [(p1, test_function), (p2, 2.0)] ) |
---|
| 373 | z = f([5, 5, 27, 35], [5, 9, 8, -5]) |
---|
| 374 | assert allclose(z, [2,14,0,2]) |
---|
| 375 | |
---|
| 376 | |
---|
| 377 | #Combined w default |
---|
| 378 | f = Polygon_function( [(p1, test_function), (p2, 2.0)], default = 3.14) |
---|
| 379 | z = f([5, 5, 27, 35], [5, 9, 8, -5]) |
---|
| 380 | assert allclose(z, [2,14,3.14,2]) |
---|
| 381 | |
---|
| 382 | |
---|
| 383 | #Combined w default func |
---|
| 384 | f = Polygon_function( [(p1, test_function), (p2, 2.0)], |
---|
| 385 | default = test_function) |
---|
| 386 | z = f([5, 5, 27, 35], [5, 9, 8, -5]) |
---|
| 387 | assert allclose(z, [2,14,35,2]) |
---|
| 388 | |
---|
| 389 | |
---|
[655] | 390 | def test_point_on_line(self): |
---|
[659] | 391 | |
---|
[655] | 392 | #Endpoints first |
---|
[671] | 393 | assert point_on_line( 0, 0, 0,0, 1,0 ) |
---|
| 394 | assert point_on_line( 1, 0, 0,0, 1,0 ) |
---|
[655] | 395 | |
---|
| 396 | #Then points on line |
---|
[671] | 397 | assert point_on_line( 0.5, 0, 0,0, 1,0 ) |
---|
| 398 | assert point_on_line( 0, 0.5, 0,1, 0,0 ) |
---|
| 399 | assert point_on_line( 1, 0.5, 1,1, 1,0 ) |
---|
| 400 | assert point_on_line( 0.5, 0.5, 0,0, 1,1 ) |
---|
[629] | 401 | |
---|
[655] | 402 | #Then points not on line |
---|
[671] | 403 | assert not point_on_line( 0.5, 0, 0,1, 1,1 ) |
---|
| 404 | assert not point_on_line( 0, 0.5, 0,0, 1,1 ) |
---|
[655] | 405 | |
---|
[659] | 406 | #From real example that failed |
---|
[671] | 407 | assert not point_on_line( 40,50, 40,20, 40,40 ) |
---|
[655] | 408 | |
---|
| 409 | |
---|
[659] | 410 | #From real example that failed |
---|
[671] | 411 | assert not point_on_line( 40,19, 40,20, 40,40 ) |
---|
[659] | 412 | |
---|
| 413 | |
---|
| 414 | |
---|
| 415 | |
---|
[655] | 416 | def test_inside_polygon(self): |
---|
[659] | 417 | |
---|
| 418 | |
---|
[655] | 419 | #Simplest case: Polygon is the unit square |
---|
| 420 | polygon = [[0,0], [1,0], [1,1], [0,1]] |
---|
| 421 | |
---|
[656] | 422 | assert inside_polygon( (0.5, 0.5), polygon ) |
---|
| 423 | assert not inside_polygon( (0.5, 1.5), polygon ) |
---|
| 424 | assert not inside_polygon( (0.5, -0.5), polygon ) |
---|
| 425 | assert not inside_polygon( (-0.5, 0.5), polygon ) |
---|
| 426 | assert not inside_polygon( (1.5, 0.5), polygon ) |
---|
[655] | 427 | |
---|
| 428 | #Try point on borders |
---|
| 429 | assert inside_polygon( (1., 0.5), polygon, closed=True) |
---|
| 430 | assert inside_polygon( (0.5, 1), polygon, closed=True) |
---|
| 431 | assert inside_polygon( (0., 0.5), polygon, closed=True) |
---|
| 432 | assert inside_polygon( (0.5, 0.), polygon, closed=True) |
---|
| 433 | |
---|
| 434 | assert not inside_polygon( (0.5, 1), polygon, closed=False) |
---|
| 435 | assert not inside_polygon( (0., 0.5), polygon, closed=False) |
---|
| 436 | assert not inside_polygon( (0.5, 0.), polygon, closed=False) |
---|
| 437 | assert not inside_polygon( (1., 0.5), polygon, closed=False) |
---|
[659] | 438 | |
---|
| 439 | |
---|
| 440 | |
---|
| 441 | #From real example (that failed) |
---|
| 442 | polygon = [[20,20], [40,20], [40,40], [20,40]] |
---|
| 443 | points = [ [40, 50] ] |
---|
| 444 | res = inside_polygon(points, polygon) |
---|
| 445 | assert len(res) == 0 |
---|
[655] | 446 | |
---|
[659] | 447 | polygon = [[20,20], [40,20], [40,40], [20,40]] |
---|
| 448 | points = [ [25, 25], [30, 20], [40, 50], [90, 20], [40, 90] ] |
---|
| 449 | res = inside_polygon(points, polygon) |
---|
| 450 | assert len(res) == 2 |
---|
| 451 | assert allclose(res, [0,1]) |
---|
| 452 | |
---|
| 453 | |
---|
[629] | 454 | |
---|
[655] | 455 | #More convoluted and non convex polygon |
---|
| 456 | polygon = [[0,0], [1,0], [0.5,-1], [2, -1], [2,1], [0,1]] |
---|
| 457 | assert inside_polygon( (0.5, 0.5), polygon ) |
---|
| 458 | assert inside_polygon( (1, -0.5), polygon ) |
---|
| 459 | assert inside_polygon( (1.5, 0), polygon ) |
---|
| 460 | |
---|
| 461 | assert not inside_polygon( (0.5, 1.5), polygon ) |
---|
| 462 | assert not inside_polygon( (0.5, -0.5), polygon ) |
---|
| 463 | |
---|
| 464 | #Now try the vector formulation returning indices |
---|
| 465 | points = [ [0.5, 0.5], [1, -0.5], [1.5, 0], [0.5, 1.5], [0.5, -0.5]] |
---|
| 466 | res = inside_polygon( points, polygon ) |
---|
| 467 | |
---|
| 468 | assert allclose( res, [0,1,2] ) |
---|
| 469 | |
---|
[656] | 470 | #Very convoluted polygon |
---|
| 471 | polygon = [[0,0], [10,10], [15,5], [20, 10], [25,0], [30,10], [40,-10]] |
---|
| 472 | assert inside_polygon( (5, 5), polygon ) |
---|
| 473 | assert inside_polygon( (17, 7), polygon ) |
---|
| 474 | assert inside_polygon( (27, 2), polygon ) |
---|
| 475 | assert inside_polygon( (35, -5), polygon ) |
---|
| 476 | assert not inside_polygon( (15, 7), polygon ) |
---|
| 477 | assert not inside_polygon( (24, 3), polygon ) |
---|
| 478 | assert not inside_polygon( (25, -10), polygon ) |
---|
[655] | 479 | |
---|
[656] | 480 | |
---|
| 481 | |
---|
| 482 | #Another combination (that failed) |
---|
| 483 | polygon = [[0,0], [10,0], [10,10], [0,10]] |
---|
| 484 | assert inside_polygon( (5, 5), polygon ) |
---|
| 485 | assert inside_polygon( (7, 7), polygon ) |
---|
| 486 | assert not inside_polygon( (-17, 7), polygon ) |
---|
| 487 | assert not inside_polygon( (7, 17), polygon ) |
---|
| 488 | assert not inside_polygon( (17, 7), polygon ) |
---|
| 489 | assert not inside_polygon( (27, 8), polygon ) |
---|
| 490 | assert not inside_polygon( (35, -5), polygon ) |
---|
| 491 | |
---|
| 492 | |
---|
| 493 | |
---|
| 494 | |
---|
| 495 | #Multiple polygons |
---|
| 496 | |
---|
| 497 | polygon = [[0,0], [1,0], [1,1], [0,1], [0,0], |
---|
| 498 | [10,10], [11,10], [11,11], [10,11], [10,10]] |
---|
| 499 | assert inside_polygon( (0.5, 0.5), polygon ) |
---|
| 500 | assert inside_polygon( (10.5, 10.5), polygon ) |
---|
| 501 | |
---|
[664] | 502 | #FIXME: Fails if point is 5.5, 5.5 |
---|
| 503 | assert not inside_polygon( (0, 5.5), polygon ) |
---|
[655] | 504 | |
---|
[656] | 505 | #Polygon with a hole |
---|
| 506 | polygon = [[-1,-1], [2,-1], [2,2], [-1,2], [-1,-1], |
---|
| 507 | [0,0], [1,0], [1,1], [0,1], [0,0]] |
---|
| 508 | |
---|
| 509 | assert inside_polygon( (0, -0.5), polygon ) |
---|
[664] | 510 | assert not inside_polygon( (0.5, 0.5), polygon ) |
---|
[656] | 511 | |
---|
| 512 | |
---|
[655] | 513 | |
---|
[258] | 514 | #------------------------------------------------------------- |
---|
| 515 | if __name__ == "__main__": |
---|
| 516 | suite = unittest.makeSuite(TestCase,'test') |
---|
| 517 | runner = unittest.TextTestRunner() |
---|
| 518 | runner.run(suite) |
---|
| 519 | |
---|
| 520 | |
---|
| 521 | |
---|
| 522 | |
---|
| 523 | |
---|