Changeset 1228 for inundation/ga/storm_surge/pmesh/mesh.py
- Timestamp:
- Apr 15, 2005, 6:38:14 PM (20 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
inundation/ga/storm_surge/pmesh/mesh.py
r1221 r1228 327 327 def rotate(self,offset): 328 328 """ 329 permute the order of the sides of the triangle 329 330 offset must be 0,1 or 2 330 331 """ … … 358 359 return abs((bx*ay-ax*by)+(cx*by-bx*cy)+(ax*cy-cx*ay))/2 359 360 361 def calcP(self): 362 #calculate the perimeter 363 ax = self.vertices[0].x 364 ay = self.vertices[0].y 365 366 bx = self.vertices[1].x 367 by = self.vertices[1].y 368 369 cx = self.vertices[2].x 370 cy = self.vertices[2].y 371 372 a = ((cx-bx)**2+(cy-by)**2)**0.5 373 b = ((ax-cx)**2+(ay-cy)**2)**0.5 374 c = ((bx-ax)**2+(by-ay)**2)**0.5 375 376 return a+b+c 377 360 378 def setNeighbors(self,neighbor1 = None, neighbor2 = None, neighbor3 = None): 361 379 """ … … 481 499 self.sets=[[]] 482 500 501 self.visualise_graph = True 502 483 503 if userSegments is None: 484 504 self.userSegments=[] … … 1441 1461 #In [3]: kinds.default_float_kind.M 1442 1462 #kinds.default_float_kind.MAX kinds.default_float_kind.MIN 1443 #kinds.default_float_kind.MAX_10_EXP kinds.default_fl oat_kind.MIN_10_EXP1463 #kinds.default_float_kind.MAX_10_EXP kinds.default_fltesting oat_kind.MIN_10_EXP 1444 1464 #kinds.default_float_kind.MAX_EXP kinds.default_float_kind.MIN_EXP 1445 1465 … … 1469 1489 Structure: [xmin, ymin, xmax, ymax] 1470 1490 """ 1471 # FIXME dsg!!! large is a hack 1491 # FIXME dsg!!! large is a hacktesting 1472 1492 #You want the kinds package, part of Numeric: 1473 1493 #In [2]: import kinds … … 2167 2187 2168 2188 def line2seg(self,line,tag=None): 2169 point0 = self. ver2point(line[0])2170 point1 = self. ver2point(line[1])2189 point0 = self.point2ver(line[0]) 2190 point1 = self.point2ver(line[1]) 2171 2191 return Segment(point0,point1,tag=tag) 2172 2192 … … 2177 2197 return Vertex(point[0],point[1]) 2178 2198 2199 def smooth_polySet(self,min_radius=0.05): 2200 #for all pairs of connecting segments: 2201 # propose a new segment that replaces the 2 2202 2203 # If the difference between the new segment 2204 # and the old lines is small: replace the 2205 # old lines. 2206 2207 seg2line = self.seg2line 2208 ver2point= self.ver2point 2209 line2seg = self.line2seg 2210 point2ver= self.point2ver 2211 2212 #create dictionaries of lines -> segments 2213 userSegments = self.segs_to_dict(self.userSegments) 2214 alphaSegments = self.segs_to_dict(self.alphaUserSegments) 2215 2216 #lump user and alpha segments 2217 for key in alphaSegments.keys(): 2218 userSegments[key]=alphaSegments[key] 2219 2220 #point_keys = tuple -> vertex 2221 #userVertices = vertex -> [line,line] - lines from that node 2222 point_keys = {} 2223 userVertices={} 2224 for vertex in self.getUserVertices(): 2225 point = ver2point(vertex) 2226 if not point_keys.has_key(point): 2227 point_keys[point]=vertex 2228 userVertices[vertex]=[] 2229 for key in userSegments.keys(): 2230 line = key 2231 point_0 = key[0] 2232 point_1 = key[1] 2233 userVertices[point_keys[point_0]].append(line) 2234 userVertices[point_keys[point_1]].append(line) 2235 2236 for point in point_keys.keys(): 2237 try: 2238 #removed keys can cause keyerrors 2239 vertex = point_keys[point] 2240 lines = userVertices[vertex] 2241 2242 #if there are 2 lines on the node 2243 if len(lines)==2: 2244 line_0 = lines[0] 2245 line_1 = lines[1] 2246 2247 #if the tags are the the same on the 2 lines 2248 if userSegments[line_0].tag == userSegments[line_1].tag: 2249 tag = userSegments[line_0].tag 2250 2251 #point_a is one of the next nodes, point_b is the other 2252 if point==line_0[0]: 2253 point_a = line_0[1] 2254 if point==line_0[1]: 2255 point_a = line_0[0] 2256 if point==line_1[0]: 2257 point_b = line_1[1] 2258 if point==line_1[1]: 2259 point_b = line_1[0] 2260 2261 2262 #line_2 is proposed 2263 line_2 = (point_a,point_b) 2264 2265 #calculate the area of the triangle between 2266 #the two existing segments and the proposed 2267 #new segment 2268 ax = point_a[0] 2269 ay = point_a[1] 2270 bx = point_b[0] 2271 by = point_b[1] 2272 cx = point[0] 2273 cy = point[1] 2274 area=abs((bx*ay-ax*by)+(cx*by-bx*cy)+(ax*cy-cx*ay))/2 2275 2276 #calculate the perimeter 2277 len_a = ((cx-bx)**2+(cy-by)**2)**0.5 2278 len_b = ((ax-cx)**2+(ay-cy)**2)**0.5 2279 len_c = ((bx-ax)**2+(by-ay)**2)**0.5 2280 perimeter = len_a+len_b+len_c 2281 2282 #calculate the radius 2283 r = area/(2*perimeter) 2284 2285 #if the radius is small: then replace the existing 2286 #segments with the new one 2287 if r < min_radius: 2288 if len_c < min_radius: append = False 2289 else: append = True 2290 #if the new seg is also time, don't add it 2291 if append: 2292 segment = self.line2seg(line_2,tag=tag) 2293 2294 list_a=userVertices[point_keys[point_a]] 2295 list_b=userVertices[point_keys[point_b]] 2296 2297 if line_0 in list_a: 2298 list_a.remove(line_0) 2299 else: 2300 list_a.remove(line_1) 2301 2302 if line_0 in list_b: 2303 list_b.remove(line_0) 2304 else: 2305 list_b.remove(line_1) 2306 2307 if append: 2308 list_a.append(line_2) 2309 list_b.append(line_2) 2310 else: 2311 if len(list_a)==0: 2312 userVertices.pop(point_keys[point_a]) 2313 point_keys.pop(point_a) 2314 if len(list_b)==0: 2315 userVertices.pop(point_keys[point_b]) 2316 point_keys.pop(point_b) 2317 2318 userVertices.pop(point_keys[point]) 2319 point_keys.pop(point) 2320 userSegments.pop(line_0) 2321 userSegments.pop(line_1) 2322 2323 if append: 2324 userSegments[line_2]=segment 2325 except: 2326 pass 2327 2328 #self.userVerticies = userVertices.keys() 2329 #self.userSegments = [] 2330 #for key in userSegments.keys(): 2331 # self.userSegments.append(userSegments[key]) 2332 #self.alphaUserSegments = [] 2333 2334 self.userVerticies = [] 2335 self.userSegments = [] 2336 self.alphaUserSegments = [] 2337 2338 return userVertices,userSegments,alphaSegments 2339 2179 2340 def triangles_to_polySet(self,setName): 2341 #self.smooth_polySet() 2342 2180 2343 seg2line = self.seg2line 2181 2344 ver2point= self.ver2point … … 2191 2354 2192 2355 2356 #create a dict of points to vertexes (tuple -> object) 2357 #also create a set of vertexes (object -> True) 2193 2358 point_keys = {} 2194 2359 userVertices={} … … 2199 2364 userVertices[vertex]=True 2200 2365 2201 ####### 2202 for vert in userVertices.keys(): 2203 assert point_keys[(vert.x,vert.y)]==vert 2204 assert len(point_keys.keys())==len(userVertices.keys()) 2205 ####### 2206 2207 2366 #create a dict of lines to segments (tuple -> object) 2208 2367 userSegments = self.segs_to_dict(self.userSegments) 2368 #append the userlines in an affine linespace 2209 2369 affine_lines = Affine_Linespace() 2210 2370 for line in userSegments.keys(): 2211 2371 affine_lines.append(line) 2212 2213 2372 alphaSegments = self.segs_to_dict(self.alphaUserSegments) 2214 2373 for line in alphaSegments.keys(): … … 2228 2387 line = (point_a,point_b) 2229 2388 tag = None 2389 2390 2391 #this bit checks for matching lines 2230 2392 possible_lines = affine_lines[line] 2393 possible_lines = unique(possible_lines) 2231 2394 found = 0 2232 2395 for user_line in possible_lines: 2233 2396 if self.point_on_line(midpoint,user_line): 2397 found+=1 2398 assert found<2 2234 2399 if userSegments.has_key(user_line): 2235 2400 parent_segment = userSegments.pop(user_line) 2236 else:2401 if alphaSegments.has_key(user_line): 2237 2402 parent_segment = alphaSegments.pop(user_line) 2238 2403 tag = parent_segment.tag … … 2253 2418 userSegments[newline]=segment 2254 2419 affine_lines.append(newline) 2255 found=1 2256 break 2420 #break 2421 assert found<2 2422 2423 2424 2425 #if no matching lines 2257 2426 if not found: 2258 2427 line_vertices = [] … … 2269 2438 affine_lines.append(line) 2270 2439 2271 #######2272 for vert in userVertices.keys():2273 assert point_keys[(vert.x,vert.y)]==vert2274 assert len(point_keys.keys())==len(userVertices.keys())2275 #######2276 2440 self.userVerticies = [] 2277 2441 self.userSegments = [] 2278 self.alphaSegments = [] 2279 #for key in userSegments.keys(): 2280 # self.userSegments.append(userSegments[key]) 2281 2282 #for key in alphaSegments.keys(): 2283 # self.userSegments.append(alphaSegments[key]) 2284 #FIXME change alpha to user and sync with pmesh 2285 #ie self.alphaSegments.append(alphaSegments[key]) 2286 #print point_keys.keys() 2287 #print userVertices.keys() 2288 #print userVertices.keys() 2442 self.alphaUserSegments = [] 2443 2289 2444 return userVertices,userSegments,alphaSegments 2290 2445 … … 2310 2465 answer = [] 2311 2466 2467 #if the new line does not share a 2468 #vertex with the old one 2312 2469 if not (allclose(A_array,a_array)\ 2313 2470 or allclose(B_array,b_array)\ … … 2344 2501 return [sibling] 2345 2502 2346 2347 2503 def point_on_line(self,point,line): 2504 #returns true within a tolerance of 3 degrees 2348 2505 x=point[0] 2349 2506 y=point[1] … … 2354 2511 from Numeric import array, dot, allclose 2355 2512 from math import sqrt 2513 tol = 3. #DEGREES 2514 tol = tol*3.1415/180 2356 2515 2357 2516 a = array([x - x0, y - y0]) 2358 a_normal = array([a[1], -a[0]]) 2359 2360 b = array([x1 - x0, y1 - y0]) 2361 2362 if allclose(dot(a_normal, b),0): 2517 a_normal = array([a[1], -a[0]]) 2518 len_a_normal = sqrt(sum(a_normal**2)) 2519 2520 b = array([x1 - x0, y1 - y0]) 2521 len_b = sqrt(sum(b**2)) 2522 2523 if abs(dot(a_normal, b)/(len_b*len_a_normal))< tol: 2363 2524 #Point is somewhere on the infinite extension of the line 2364 2525 2365 len_a = sqrt(sum(a**2)) 2366 len_b = sqrt(sum(b**2)) 2526 len_a = sqrt(sum(a**2)) 2367 2527 if dot(a, b) >= 0 and len_a <= len_b: 2368 2528 return True … … 2370 2530 return False 2371 2531 else: 2372 return False 2532 return False 2373 2533 2374 2534 def line_length(self,line): … … 2379 2539 return ((x1-x0)**2-(y1-y0)**2)**0.5 2380 2540 2381 def triangles_to_polySet2(self,setName):2382 from Numeric import array,allclose2383 2384 #turn the triangles into a set2385 Triangles = self.sets[self.setID[setName]]2386 Triangles_dict = {}2387 for triangle in Triangles:2388 Triangles_dict[triangle]=None2389 2390 userVertices = {}2391 userSegments = {}2392 point_keys = {}2393 affine_lines = {}2394 for vertex in self.getUserVertices():2395 point = (vertex.x,vertex.y)2396 point_keys[point]=vertex2397 2398 line_keys = {}2399 for segment in self.getUserSegments():2400 #inlined would looks very ugly2401 vertex1 = segment.vertices[0]2402 vertex2 = segment.vertices[1]2403 point1 = (vertex1.x,vertex1.y)2404 point2 = (vertex2.x,vertex2.y)2405 #segment.vertices[0]=point_keys[point1]2406 #segment.vertices[1]=point_keys[point2]2407 #vertex1 = segment.vertices[0]2408 #vertex2 = segment.vertices[1]2409 #point1 = (vertex1.x,vertex1.y)2410 #point2 = (vertex2.x,vertex2.y)2411 line1 = (point1,point2)2412 line2 = (point2,point1)2413 AB = affine_line(point1,point2)2414 flat_AB_up = ceilAB[0]+AB[1]+AB[2]2415 if not (line_keys.has_key(line1) \2416 or line_keys.has_key(line2)):2417 line_keys[line1]=segment2418 2419 for triangle in Triangles:2420 for i in (0,1,2):2421 #for every triangles neighbour:2422 2423 if not Triangles_dict.has_key(triangle.neighbors[i]):2424 #if the neighbour is not in the set:2425 a = triangle.vertices[i-1]2426 b = triangle.vertices[i-2]2427 if not point_keys.has_key((a.x,a.y)):2428 #if point a does not already exist2429 #then add it to the points.2430 userVertices[a]=True2431 point_keys[(a.x,a.y)]=a2432 else:2433 a=point_keys[(a.x,a.y)]2434 userVertices[a]=point_keys[(a.x,a.y)]2435 assert userVertices.has_key(a)2436 2437 if not point_keys.has_key((b.x,b.y)):2438 #if point b does not already exist2439 #then add it to the points.2440 userVertices[b]=True2441 point_keys[(b.x,b.y)]=b2442 else:2443 b=point_keys[(b.x,b.y)]2444 userVertices[b]=point_keys[(b.x,b.y)]2445 assert userVertices.has_key(b)2446 2447 if not (line_keys.has_key(((a.x,a.y),(b.x,b.y)))\2448 or line_keys.has_key(((b.x,b.y),(a.x,a.y)))):2449 #if the segment does not already exist then2450 #add it to the segments2451 assert ((a.x,a.y)!=(b.x,b.y))2452 assert a!=b2453 AB = affine_line(a,b)2454 flat_AB = AB[0]+AB[1]+AB[2]2455 if affine_lines.has_key(flat_AB):2456 userSegments[Segment(a,b)]=None2457 line_keys[((a.x,a.y),(b.x,b.y))]=None2458 2459 userVertices,userSegments = self.weed(userVertices.keys(),userSegments.keys())2460 self.userVertices.extend(userVertices)2461 self.userSegments.extend(userSegments)2462 self.userVertices,self.userSegments = \2463 self.weed(self.userVertices,self.userSegments)2464 2465 2541 def threshold(self,setName,min=None,max=None,attribute_name = 'elevation'): 2466 2542 """ … … 2472 2548 if attribute_name in self.attributeTitles: 2473 2549 i = self.attributeTitles.index(attribute_name) 2550 else: i = -1#no attribute 2474 2551 if not max == None: 2475 2552 for t in triangles: … … 2482 2559 self.sets[self.setID[setName]] = A 2483 2560 2484 def general_threshold(self,setName,min=None,max=None,attribute_name = 'elevation',function = None): 2485 """ 2486 threshold using d 2487 """ 2561 def general_threshold(self,setName,min=None,max=None\ 2562 ,attribute_name = 'elevation',function=None): 2563 """ 2564 Thresholds the triangles 2565 """ 2566 from visual.graph import arange,ghistogram,color as colour 2488 2567 triangles = self.sets[self.setID[setName]] 2489 2568 A = [] 2569 data=[] 2570 #data is for the graph 2490 2571 2491 2572 if attribute_name in self.attributeTitles: 2492 2573 i = self.attributeTitles.index(attribute_name) 2574 else: i = -1 2493 2575 if not max == None: 2494 2576 for t in triangles: 2495 if (min<function(t,i)<max): 2577 value=function(t,i) 2578 if (min<value<max): 2496 2579 A.append(t) 2580 data.append(value) 2497 2581 else: 2498 2582 for t in triangles: 2499 if (min<self.function(t,i)): 2583 value=function(t,i) 2584 if (min<value): 2500 2585 A.append(t) 2586 data.append(value) 2501 2587 self.sets[self.setID[setName]] = A 2502 2588 2589 if self.visualise_graph: 2590 if len(data)>0: 2591 max=data[0] 2592 min=data[0] 2593 for value in data: 2594 if value > max: 2595 max = value 2596 if value < min: 2597 min = value 2598 2599 inc = (max-min)/100 2600 2601 histogram = ghistogram(bins=arange(min,max,inc),\ 2602 color = colour.red) 2603 histogram.plot(data=data) 2604 2503 2605 def av_att(self,triangle,i): 2504 #evaluates the average attribute of the vertices of a triangle. 2505 V = triangle.getVertices() 2506 a0 = (V[0].attributes[i]) 2507 a1 = (V[1].attributes[i]) 2508 a2 = (V[2].attributes[i]) 2509 return (a0+a1+a2)/3 2606 if i==-1: return 1 2607 else: 2608 #evaluates the average attribute of the vertices of a triangle. 2609 V = triangle.getVertices() 2610 a0 = (V[0].attributes[i]) 2611 a1 = (V[1].attributes[i]) 2612 a2 = (V[2].attributes[i]) 2613 return (a0+a1+a2)/3 2510 2614 2511 2615 def Courant_ratio(self,triangle,index): 2512 2616 """ 2513 Not the true Courant ratio, just elevation on area2617 Uses the courant threshold 2514 2618 """ 2515 2619 e = self.av_att(triangle,index) 2516 2620 A = triangle.calcArea() 2517 return e/A 2621 P = triangle.calcP() 2622 r = A/(2*P) 2623 e = max(0.1,abs(e)) 2624 return r/e**0.5 2518 2625 2519 2626 def Gradient(self,triangle,index): … … 3187 3294 from math import frexp 3188 3295 self.frexp = frexp 3296 roundings = [self.round_up_rel,\ 3297 self.round_down_rel,self.round_flat_rel,\ 3298 self.round_down_abs,self.round_up_abs,\ 3299 self.round_flat_abs]# 3300 3301 self.roundings = roundings 3189 3302 3190 3303 def __repr__(self): … … 3202 3315 rounded_values=list(key) 3203 3316 3204 roundings = [self.round_up_rel,\ 3205 self.round_down_rel,self.round_flat_rel,\ 3206 self.round_down_abs,self.round_up_abs,\ 3207 self.round_flat_abs] 3208 3209 3210 roundings = \ 3211 [self.round_up_rel, self.round_down_rel, \ 3212 self.round_up_rel2,self.round_down_rel2,\ 3213 self.round_up_abs, self.round_down_abs] 3317 roundings = list(self.roundings) 3214 3318 3215 3319 #initialise rounded_values … … 3371 3475 return self.__items__.keys() 3372 3476 3373 3374 3375 3477 3376 3478 class Mapped_Discretised_Tuple_Set(Discretised_Tuple_Set): … … 3412 3514 Nearly. 3413 3515 """ 3414 def __init__(self,p_rel = 3,t_rel=0.1):3516 def __init__(self,p_rel=4,t_rel=0.2): 3415 3517 Mapped_Discretised_Tuple_Set.__init__\ 3416 3518 (self,self.affine_line,\ 3417 3519 p_rel=p_rel,t_rel=t_rel) 3520 3521 roundings = \ 3522 [self.round_down_rel,self.round_up_rel,self.round_flat_rel] 3523 self.roundings = roundings 3524 #roundings = \ 3525 #[self.round_down_abs,self.round_up_abs,self.round_flat_abs] 3526 #self.roundings = roundings 3418 3527 3419 3528 def affine_line(self,line): … … 3445 3554 alpha = (-dif_y)/dif_x 3446 3555 #a = alpha * b 3447 b = 1.3556 b = -1. 3448 3557 c = (x1*alpha+x2*alpha+y1+y2)/2. 3449 3558 a = alpha*b … … 3454 3563 c = (x1+x2+y1*beta+y2*beta)/2. 3455 3564 b = beta*a 3456 3457 mag = (a**2+b**2+c**2)**(0.5) 3458 3459 if a == 0: 3460 sign_a = 1. 3461 else: 3462 sign_a = a/((a**2)**0.5) 3565 mag = abs(a)+abs(b) 3463 3566 #This does not change the mathematical 3464 #properties, but it makes comparism 3465 if b == 0: 3466 sign_b = 1. 3467 else: 3468 sign_b = b/((b**2)**0.5) 3469 if c == 0: 3470 sign_c = 1. 3471 else: 3472 sign_c = c/((c**2)**0.5) 3473 a = a/mag*sign_a 3474 b = b/mag*sign_b 3475 c = c/mag*sign_c 3567 #properties, but it makes comparism possible. 3568 3569 #note that the gradient is b/a, or (a/b)**-1. 3570 #so 3571 3572 #if a == 0: 3573 # sign_a = 1. 3574 #else: 3575 # sign_a = a/((a**2)**0.5) 3576 #if b == 0: 3577 # sign_b = 1. 3578 #else: 3579 # sign_b = b/((b**2)**0.5) 3580 #if c == 0: 3581 # sign_c = 1. 3582 #else: 3583 # sign_c = c/((c**2)**0.5) 3584 #a = a/mag*sign_a 3585 #b = b/mag*sign_b 3586 #c = c/mag*sign_c 3587 a = a/mag 3588 b = b/mag 3589 c = c/mag 3476 3590 return a,b,c 3477 3591 3478 3592 3479 3593 3480 3594 if __name__ == "__main__": 3481 3595 #from mesh import * … … 3484 3598 dict = importUngenerateFile("ungen_test.txt") 3485 3599 m.addVertsSegs(dict) 3486 print m 3600 print m3
Note: See TracChangeset
for help on using the changeset viewer.