Changeset 7690 for anuga_core/source/anuga/utilities/polygon.py
- Timestamp:
- Apr 21, 2010, 1:48:09 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
anuga_core/source/anuga/utilities/polygon.py
r7687 r7690 322 322 return False 323 323 324 324 325 def is_complex(polygon, verbose=False): 325 """Check if a polygon is complex (self-intersecting) 326 """ 327 326 """Check if a polygon is complex (self-intersecting). 327 Uses a sweep algorithm that is O(n^2) in the worst case, but 328 for most normal looking polygons it'll be O(n log n). 329 330 polygon is a list of points that define a closed polygon. 331 verbose will print a list of the intersection points if true 332 333 Return True if polygon is complex. 334 """ 335 336 def key_xpos(item): 337 return (item[0][0]) 338 339 def segments_joined(seg0, seg1): 340 for i in seg0: 341 for j in seg1: 342 if i == j: return True 343 return False 344 328 345 polygon = ensure_numeric(polygon, num.float) 329 346 347 # build a list of discrete segments from the polygon 348 unsorted_segs = [] 330 349 for i in range(0, len(polygon)-1): 331 for j in range(i+1, len(polygon)-1): 332 (type, point) = intersection([polygon[i], polygon[i+1]], [polygon[j], polygon[j+1]]) 333 334 if (abs(i-j) > 1 and type == 1) or (type == 2 and list(point[0]) != list(point[1])) or (type == 3) and type != 4: 350 unsorted_segs.append([list(polygon[i]), list(polygon[i+1])]) 351 unsorted_segs.append([list(polygon[0]), list(polygon[-1])]) 352 353 # all segments must point in same direction 354 for val in unsorted_segs: 355 if val[0][0] > val[1][0]: 356 val[0], val[1] = val[1], val[0] 357 358 l_x = sorted(unsorted_segs, key=key_xpos) 359 360 comparisons = 0 361 362 # loop through, only comparing lines that partially overlap in x 363 for index, leftmost in enumerate(l_x): 364 cmp = index+1 365 while cmp < len(l_x) and leftmost[1][0] > l_x[cmp][0][0]: 366 if not segments_joined(leftmost, l_x[cmp]): 367 (type, point) = intersection(leftmost, l_x[cmp]) 368 comparisons += 1 369 if type != 0 and type != 4 or (type == 2 and list(point[0]) != list(point[1])): 335 370 if verbose: 336 print 'Self-intersecting polygon found, type ', type, ' point', point, 'vertex indices ', i, j 337 return True 371 print 'Self-intersecting polygon found, type ', type, ' point', point, 372 print 'vertices: ', leftmost, ' - ', l_x[cmp] 373 return True 374 cmp += 1 338 375 339 376 return False 377 340 378 341 379 def is_inside_polygon_quick(point, polygon, closed=True, verbose=False): … … 996 1034 polygon.append([float(fields[0]), float(fields[1])]) 997 1035 998 # check this is a valid polygon 999 # if is_complex(polygon):1000 # msg = 'ERROR: Self-intersecting polygon detected in file' + filename +'. '1001 # msg += 'Please fix.'1002 # log.critical(msg)1003 # #raise Exception, msg1036 # check this is a valid polygon. 1037 if is_complex(polygon, verbose=True): 1038 msg = 'ERROR: Self-intersecting polygon detected in file ' + filename +'. ' 1039 msg += 'A complex polygon will not necessarily break the algorithms within ANUGA, ' 1040 msg += 'but it usually signifies pathological data. Please fix this file.' 1041 raise Exception, msg 1004 1042 1005 1043 return polygon
Note: See TracChangeset
for help on using the changeset viewer.