Changeset 655
- Timestamp:
- Dec 2, 2004, 10:58:26 AM (20 years ago)
- Location:
- inundation/ga/storm_surge/pyvolution
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
inundation/ga/storm_surge/pyvolution/mesh.py
r648 r655 130 130 self.build_tagged_elements_dictionary(tagged_elements) 131 131 132 #Update boundary indices 132 #Update boundary indices FIXME: OBSOLETE 133 133 #self.build_boundary_structure() 134 134 … … 313 313 """ 314 314 315 #FIXME: Maybe obsolete 315 #FIXME: Now Obsolete - maybe use some comments from here in 316 #domain.set_boundary 316 317 317 318 if self.boundary is None: -
inundation/ga/storm_surge/pyvolution/test_util.py
r629 r655 332 332 assert allclose( 2*sin(120*pi/600)/3 + sin(60*pi/600)/3, q[2] ) 333 333 334 def test_point_on_line(self): 335 336 #Endpoints first 337 assert point_on_line( (0, 0), [(0,0), (1,0)] ) 338 assert point_on_line( (1, 0), [(0,0), (1,0)] ) 339 340 #Then points on line 341 assert point_on_line( (0.5, 0), [(0,0), (1,0)] ) 342 assert point_on_line( (0, 0.5), [(0,1), (0,0)] ) 343 assert point_on_line( (1, 0.5), [(1,1), (1,0)] ) 344 assert point_on_line( (0.5, 0.5), [(0,0), (1,1)] ) 345 346 #Then points not on line 347 assert not point_on_line( (0.5, 0), [(0,1), (1,1)] ) 348 assert not point_on_line( (0, 0.5), [(0,0), (1,1)] ) 349 350 351 352 def test_inside_polygon(self): 353 354 #Simplest case: Polygon is the unit square 355 polygon = [[0,0], [1,0], [1,1], [0,1]] 356 357 x = y = 0.5 358 assert inside_polygon( (x, y), polygon ) 359 360 y = 1.5 361 assert not inside_polygon( (x, y), polygon ) 362 #Try point on borders 363 assert inside_polygon( (1., 0.5), polygon, closed=True) 364 assert inside_polygon( (0.5, 1), polygon, closed=True) 365 assert inside_polygon( (0., 0.5), polygon, closed=True) 366 assert inside_polygon( (0.5, 0.), polygon, closed=True) 367 368 assert not inside_polygon( (0.5, 1), polygon, closed=False) 369 assert not inside_polygon( (0., 0.5), polygon, closed=False) 370 assert not inside_polygon( (0.5, 0.), polygon, closed=False) 371 assert not inside_polygon( (1., 0.5), polygon, closed=False) 334 372 335 373 374 #More convoluted and non convex polygon 375 polygon = [[0,0], [1,0], [0.5,-1], [2, -1], [2,1], [0,1]] 376 assert inside_polygon( (0.5, 0.5), polygon ) 377 assert inside_polygon( (1, -0.5), polygon ) 378 assert inside_polygon( (1.5, 0), polygon ) 379 380 assert not inside_polygon( (0.5, 1.5), polygon ) 381 assert not inside_polygon( (0.5, -0.5), polygon ) 382 383 384 385 #Now try the vector formulation returning indices 386 points = [ [0.5, 0.5], [1, -0.5], [1.5, 0], [0.5, 1.5], [0.5, -0.5]] 387 res = inside_polygon( points, polygon ) 388 389 assert allclose( res, [0,1,2] ) 390 391 392 393 336 394 #------------------------------------------------------------- 337 395 if __name__ == "__main__": -
inundation/ga/storm_surge/pyvolution/util.py
r630 r655 47 47 48 48 49 50 def point_on_line(point, line): 51 """Determine whether a point is on a line segment 52 53 Input: 54 point: (x, y) 55 line: [ (x0, y0), (x1, y1) ] 56 57 """ 58 59 #FIXME: Could do with some optimisation 60 61 from Numeric import array, dot, allclose 62 from math import sqrt 63 64 x = point[0] 65 y = point[1] 66 67 x0 = line[0][0] 68 x1 = line[1][0] 69 y0 = line[0][1] 70 y1 = line[1][1] 71 72 73 a = array([x - x0, y - y0]) 74 b = array([x1 - x0, y1 - y0]) 75 76 len_a = sqrt(sum(a**2)) 77 len_b = sqrt(sum(b**2)) 78 79 if len_a == 0 or len_a == len_b: 80 return True 81 else: 82 x = dot(a, b)/len_b 83 return allclose(x, len_a) 84 85 86 87 def inside_polygon(point, polygon, closed = True): 88 """Determine whether points are inside or outside a polygon 89 90 Input: 91 point - Tuple of (x, y) coordinates, or list of tuples 92 polygon - list of vertices of polygon 93 94 Output: 95 If one point is considered, True or False is returned. 96 If multiple points are passed in, the function returns indices 97 of those points that fall inside the polygon 98 99 Examples: 100 inside_polygon( [0.5, 0.5], [[0,0], [1,0], [1,1], [0,1]] ) 101 will evaluate to True as the point 0.5, 0.5 is inside the unit square 102 103 inside_polygon( [[0.5, 0.5], [1, -0.5], [0.3, 0.2]] ) 104 will return the indices [0, 2] as only the first and the last point 105 is inside the unit square 106 107 Remarks: 108 <Copy from source Franklins code > 109 110 111 points at a vertex are considered to be inside 112 113 Algorithm due to Darel Finley, http://www.alienryderflex.com/polygon/ 114 115 116 FIXME: More comments about algoritm 117 FIXME: Deal with case where point on border of polygon (closed) 118 119 """ 120 121 from Numeric import array, Float, reshape 122 123 124 #Input checks 125 try: 126 point = array(point).astype(Float) 127 except: 128 msg = 'Point %s could not be converted to Numeric array' %point 129 raise msg 130 131 try: 132 polygon = array(polygon).astype(Float) 133 except: 134 msg = 'Polygon %s could not be converted to Numeric array' %polygon 135 raise msg 136 137 assert len(polygon.shape) == 2,\ 138 'Polygon array must be a 2d array of vertices: %s' %polygon 139 140 141 assert polygon.shape[1] == 2,\ 142 'Polygon array must have two columns: %s' %polygon 143 144 145 if len(point.shape) == 1: 146 one_point = True 147 points = reshape(point, (1,2)) 148 else: 149 one_point = False 150 points = point 151 152 N = polygon.shape[0] #Number of vertices in polygon 153 154 px = polygon[:,0] 155 py = polygon[:,1] 156 157 #Begin algorithm 158 indices = [] 159 for k in range(points.shape[0]): 160 #for each point 161 x = points[k, 0] 162 y = points[k, 1] 163 164 165 inside = False 166 for i in range(N): 167 j = (i+1)%N 168 169 #Check for case where point is contained in line segment 170 if point_on_line( (x,y), [ [px[i], py[i]], [px[j], py[j]] ]): 171 if closed: 172 inside = True 173 else: 174 inside = False 175 break 176 177 #Check truly inside polygon 178 if px[i] < y and py[j] >= y or\ 179 py[j] < y and py[i] >= y: 180 if px[i] + (y-py[i])/(py[j]-py[i])*(px[j]-px[i]) < x: 181 inside = not inside 182 183 if inside: indices.append(k) 184 185 if one_point: 186 return inside 187 else: 188 return indices 189 49 190 50 191 class File_function:
Note: See TracChangeset
for help on using the changeset viewer.