Changeset 1217 for inundation/ga/storm_surge
- Timestamp:
- Apr 11, 2005, 6:23:47 PM (20 years ago)
- Location:
- inundation/ga/storm_surge/pmesh
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
inundation/ga/storm_surge/pmesh/mesh.py
r1183 r1217 2117 2117 colour = colour) 2118 2118 2119 2120 2119 def weed(self,Vertices,Segments): 2121 2120 #weed out existing duplicates … … 2129 2128 point = (vertex.x,vertex.y) 2130 2129 point_keys[point]=vertex 2130 #inlined would looks very ugly 2131 2131 2132 2132 line_keys = {} … … 2151 2151 return Vertices,Segments 2152 2152 2153 def segs_to_dict(self,segments): 2154 dict={} 2155 for segment in segments: 2156 vertex1 = segment.vertices[0] 2157 vertex2 = segment.vertices[1] 2158 point1 = (vertex1.x,vertex1.y) 2159 point2 = (vertex2.x,vertex2.y) 2160 line = (point1,point2) 2161 dict[line]=segment 2162 return dict 2163 2164 def seg2line(self,s): 2165 return ((s.vertices[0].x,s.vertices[0].y,)\ 2166 (s.vertices[1].x,s.vertices[1].y)) 2167 2168 def line2seg(self,line,tag=None): 2169 point0 = self.ver2point(line[0]) 2170 point1 = self.ver2point(line[1]) 2171 return Segment(point0,point1,tag=tag) 2172 2173 def ver2point(self,vertex): 2174 return (vertex.x,vertex.y) 2175 2176 def point2ver(self,point): 2177 return Vertex(point[0],point[1]) 2178 2153 2179 def triangles_to_polySet(self,setName): 2180 seg2line = self.seg2line 2181 ver2point = self.ver2point 2182 line2seg = self.line2seg 2183 point2ver = self.point2ver 2184 2185 from Numeric import array,allclose 2154 2186 #turn the triangles into a set 2155 2187 Triangles = self.sets[self.setID[setName]] … … 2158 2190 Triangles_dict[triangle]=None 2159 2191 2192 point_keys = {} 2193 userVertices={} 2194 for vertex in self.getUserVertices(): 2195 point = ver2point(vertex) 2196 if not point_keys.has_key(point): 2197 point_keys[point]=vertex 2198 userVertices[vertex]=True 2199 2200 userSegments = self.segs_to_dict(self.userSegments) 2201 affine_lines = Affine_Linespace() 2202 for line in userSegments.keys(): 2203 affine_lines.append(line) 2204 2205 alphaSegments = self.segs_to_dict(self.alphaUserSegments) 2206 for line in alphaSegments.keys(): 2207 affine_lines.append(line) 2208 2209 for triangle in Triangles: 2210 for i in (0,1,2): 2211 #for every triangles neighbour: 2212 if not Triangles_dict.has_key(triangle.neighbors[i]): 2213 #if the neighbour is not in the set: 2214 a = triangle.vertices[i-1] 2215 b = triangle.vertices[i-2] 2216 for vert in (a,b): 2217 point = ver2point(vert) 2218 if not point_keys.has_key(point): 2219 userVertices[vert]=True 2220 point_keys[point]=vert 2221 2222 #Get possible matches: 2223 point_a = ver2point(a) 2224 point_b = ver2point(b) 2225 midpoint = ((a.x+b.x)/2,(a.y+b.y)/2) 2226 line = (point_a,point_b) 2227 tag = None 2228 possible_lines = affine_lines[line] 2229 found = 0 2230 for user_line in possible_lines: 2231 if self.point_on_line(midpoint,user_line): 2232 if user_line in userSegments: 2233 parent_segment = userSegments.pop(user_line) 2234 else: 2235 parent_segment = alphaSegments.pop(user_line) 2236 tag = parent_segment.tag 2237 offspring = [line] 2238 offspring.extend(self.subtract_line(user_line,line)) 2239 affine_lines.remove(user_line) 2240 for newline in offspring: 2241 line_vertices = [] 2242 for point in newline: 2243 if point_keys.has_key(point): 2244 vert = point_keys[point] 2245 else: 2246 vert = Vertex(point[0],point[1]) 2247 userVertices[vert]=True 2248 point_keys[point]=vert 2249 line_vertices.append(vert) 2250 segment = Segment(line_vertices[0],line_vertices[1],tag) 2251 userSegments[newline]=segment 2252 affine_lines.append(newline) 2253 found=1 2254 break 2255 if not found: 2256 line_vertices = [] 2257 for point in line: 2258 if point_keys.has_key(point): 2259 vert = point_keys[point] 2260 else: 2261 vert = Vertex(point[0],point[1]) 2262 userVertices[vert]=True 2263 point_keys[point]=vert 2264 line_vertices.append(vert) 2265 segment = Segment(line_vertices[0],line_vertices[1],tag) 2266 userSegments[line]=segment 2267 affine_lines.append(line) 2268 2269 self.userVerticies = [] 2270 self.userSegments = [] 2271 self.alphaSegments = [] 2272 #for key in userSegments.keys(): 2273 # self.userSegments.append(userSegments[key]) 2274 2275 #for key in alphaSegments.keys(): 2276 # self.userSegments.append(alphaSegments[key]) 2277 #FIXME change alpha to user and sync with pmesh 2278 #ie self.alphaSegments.append(alphaSegments[key]) 2279 2280 return userVertices,userSegments,alphaSegments 2281 2282 def subtract_line(self,parent,child): 2283 #Subtracts child from parent 2284 #Requires that the child is a 2285 #subline of parent to work. 2286 2287 from Numeric import allclose,dot,array 2288 A= parent[0] 2289 B= parent[1] 2290 a = child[0] 2291 b = child[1] 2292 2293 A_array = array(parent[0]) 2294 B_array = array(parent[1]) 2295 a_array = array(child[0]) 2296 b_array = array(child[1]) 2297 2298 assert not A == B 2299 assert not a == b 2300 2301 answer = [] 2302 2303 if not (allclose(A_array,a_array)\ 2304 or allclose(B_array,b_array)\ 2305 or allclose(A_array,b_array)\ 2306 or allclose(a_array,B_array)): 2307 if dot(A_array-a_array,A_array-a_array) \ 2308 < dot(A_array-b_array,A_array-b_array): 2309 sibling1 = (A,a) 2310 sibling2 = (B,b) 2311 return [sibling1,sibling2] 2312 else: 2313 sibling1 = (A,b) 2314 sibling2 = (B,a) 2315 return [sibling1,sibling2] 2316 2317 elif allclose(A_array,a_array): 2318 if allclose(B_array,b_array): 2319 return [] 2320 else: 2321 sibling = (b,B) 2322 return [sibling] 2323 elif allclose(B_array,b_array): 2324 sibling = (a,A) 2325 return [sibling] 2326 2327 elif allclose(A_array,b_array): 2328 if allclose(B,a): 2329 return [] 2330 else: 2331 sibling = (a,B) 2332 return [sibling] 2333 elif allclose(a_array,B_array): 2334 sibling = (b,A) 2335 return [sibling] 2336 2337 2338 def point_on_line(self,point,line): 2339 x=point[0] 2340 y=point[1] 2341 x0=line[0][0] 2342 x1=line[1][0] 2343 y0=line[0][1] 2344 y1=line[1][1] 2345 return point_on_line(x,y,x0,y0,x1,y1) 2346 #a wrapper for the c func. 2347 2348 def line_length(self,line): 2349 x0=line[0][0] 2350 x1=line[1][0] 2351 y0=line[0][1] 2352 y1=line[1][1] 2353 return ((x1-x0)**2-(y1-y0)**2)**0.5 2354 2355 def triangles_to_polySet2(self,setName): 2356 from Numeric import array,allclose 2357 2358 #turn the triangles into a set 2359 Triangles = self.sets[self.setID[setName]] 2360 Triangles_dict = {} 2361 for triangle in Triangles: 2362 Triangles_dict[triangle]=None 2363 2160 2364 userVertices = {} 2161 userSegments = []2365 userSegments = {} 2162 2366 point_keys = {} 2367 affine_lines = {} 2163 2368 for vertex in self.getUserVertices(): 2164 2369 point = (vertex.x,vertex.y) … … 2167 2372 line_keys = {} 2168 2373 for segment in self.getUserSegments(): 2374 #inlined would looks very ugly 2169 2375 vertex1 = segment.vertices[0] 2170 2376 vertex2 = segment.vertices[1] … … 2179 2385 line1 = (point1,point2) 2180 2386 line2 = (point2,point1) 2387 AB = affine_line(point1,point2) 2388 flat_AB_up = ceilAB[0]+AB[1]+AB[2] 2181 2389 if not (line_keys.has_key(line1) \ 2182 2390 or line_keys.has_key(line2)): … … 2209 2417 b=point_keys[(b.x,b.y)] 2210 2418 userVertices[b]=point_keys[(b.x,b.y)] 2211 assert userVertices.has_key(b) 2419 assert userVertices.has_key(b) 2212 2420 2213 2421 if not (line_keys.has_key(((a.x,a.y),(b.x,b.y)))\ … … 2217 2425 assert ((a.x,a.y)!=(b.x,b.y)) 2218 2426 assert a!=b 2219 userSegments.append(Segment(a,b)) 2427 AB = affine_line(a,b) 2428 flat_AB = AB[0]+AB[1]+AB[2] 2429 if affine_lines.has_key(flat_AB): 2430 userSegments[Segment(a,b)]=None 2220 2431 line_keys[((a.x,a.y),(b.x,b.y))]=None 2221 2432 2222 userVertices,userSegments = self.weed(userVertices.keys(),userSegments )2433 userVertices,userSegments = self.weed(userVertices.keys(),userSegments.keys()) 2223 2434 self.userVertices.extend(userVertices) 2224 2435 self.userSegments.extend(userSegments) … … 2296 2507 self.meshTriangles[i]=replacement 2297 2508 assert replacement in self.meshTriangles 2298 2299 2300 2301 2509 2302 2510 def importUngenerateFile(ofile): … … 2834 3042 2835 3043 def repairCaseOne(self): 2836 r = self.r 3044 r = self.rkey 2837 3045 2838 3046 … … 2897 3105 triangle1.neighbors[j]=triangle2 2898 3106 2899 2900 3107 class Discretised_Tuple_Set: 3108 """ 3109 if a={(0.0):[(0.01),(0.02)],(0.2):[(0.17)]} 3110 a[(0.01)]=a[(0.0)]=[(0.01),(0.02)] 3111 a[(10000)]=[] #NOT KEYERROR 3112 3113 a.append[(0.01)] 3114 => {0.0:[(0.01),(0.02),(0.01)],0.2:[(0.17)]} 3115 3116 #NOT IMPLIMENTED 3117 a.remove[(0.01)] 3118 => {(0.0):[(0.02),(0.01)],0.2:[(0.17)]} 3119 3120 a.remove[(0.17)] 3121 => {(0.0):[(0.02),(0.01)],0.2:[]} 3122 #NOT IMPLIMENTED 3123 at a.precision = 2: 3124 a.round_up[0.0]= 3125 a.round_flat[0.0]= 3126 a.round_downp0.0]= 3127 3128 a.up((0.1,2.04))= 3129 3130 If tolerance = 0, nothing gets rounded into 3131 two bins. If tolerance = 0.5, everything does. 3132 3133 Ideally, precision can be set high, so that multiple 3134 entries are rarely in the same bin. And tolerance should 3135 be low (<0.1 for 1 dimension!,<(0.1/n) for small n!!) 3136 so that it is rare to put items in mutiple bins. 3137 3138 Ex bins per entry = product(a,b,c...,n) 3139 a = 1 or 2 s.t. Ex(a) = 1+2*tolerance 3140 b = 1 or 2 ... 3141 3142 BUT!!! to avoid missing the right bin: 3143 (-10)**(precision+1)*tolerance must be greater than the 3144 greatest possible variation that an identical element 3145 can display. 3146 """ 3147 def __init__(self,precision = 6,tolerance = 0.01): 3148 self.__precision__ = precision 3149 self.__tolerance__ = tolerance 3150 assert tolerance <= 0.5 3151 self.__items__ = {} 3152 from math import frexp 3153 self.frexp = frexp 3154 3155 def __repr__(self): 3156 return '%s'%self.__items__ 3157 3158 def rounded_keys(self,key): 3159 key = tuple(key) 3160 keys = [key] 3161 keys = self.__rounded_keys__(key) 3162 return (keys) 3163 3164 def __rounded_keys__(self,key): 3165 keys = [] 3166 up_key=list(key) 3167 for i in range(len(up_key)): 3168 up_key[i]=self.round_up(key[i]) 3169 keys.append(tuple(up_key)) 3170 3171 #round down the value 3172 for i in range(len(up_key)): 3173 if not keys[0][i]==self.round_down(key[i]): 3174 #unless round_up = round_down 3175 #so the keys stay unique 3176 for j in range(len(keys)): 3177 down_key = list(keys[j]) 3178 down_key[i]=self.round_down(key[i]) 3179 down_key=tuple(down_key) 3180 keys.append(down_key) 3181 return keys 3182 3183 def append(self,item): 3184 keys = self.rounded_keys(item) 3185 for key in keys: 3186 if self.__items__.has_key(key): 3187 self.__items__[key].append(item) 3188 else: 3189 self.__items__[key]=[item] 3190 3191 def __getitem__(self,key): 3192 answer = [] 3193 keys = self.rounded_keys(key) 3194 for key in keys: 3195 if self.__items__.has_key(key): 3196 answer.extend(self.__items__[key]) 3197 #if len(answer)==0: 3198 # raise KeyError#FIXME or return KeyError 3199 # #FIXME or just return []? 3200 else: 3201 return answer #FIXME or unique(answer)? 3202 3203 def __delete__(self,item): 3204 keys = self.rounded_keys(item) 3205 answer = False 3206 #if any of the possible keys contains 3207 #a list, return true 3208 for key in keys: 3209 if self.__items__.has_key(key): 3210 if item in self.__items__[key]: 3211 self.__items__[key].remove(item) 3212 3213 def remove(self,item): 3214 self.__delete__(item) 3215 3216 def __contains__(self,item): 3217 3218 keys = self.rounded_keys(item) 3219 answer = False 3220 #if any of the possible keys contains 3221 #a list, return true 3222 for key in keys: 3223 if self.__items__.has_key(key): 3224 if item in self.__items__[key]: 3225 answer = True 3226 return answer 3227 3228 3229 def has_item(self,item): 3230 return self.__contains__(item) 3231 3232 def round_up(self,value): 3233 tolerance=self.__tolerance__ 3234 #Rounding up the value 3235 m,e = self.frexp(value) 3236 #m is the mantissa, e the exponent 3237 # 0.5 < |m| < 1.0 3238 m = m*(1+tolerance*(10**-(self.__precision__+1))/((m**2)**0.5)) 3239 #bump m up, by 5% or whatever 3240 #self.precision dictates 3241 m = round(m,self.__precision__) 3242 #round m off so that the bump up 3243 #will be discernable if and only if 3244 return m*(2.**e) 3245 3246 def round_down(self,value): 3247 tolerance=self.__tolerance__ 3248 #Rounding down the value 3249 m,e = self.frexp(value) 3250 #m is the mantissa, e the exponent 3251 # 0.5 < m < 1.0 3252 m = m*(1-tolerance*(10**-(self.__precision__+1))/((m**2)**0.5)) 3253 #bump the |m| down, by 5% or whatever 3254 #self.precision dictates 3255 m = round(m,self.__precision__) 3256 #round m off so that the bump down 3257 #will be discernable if and only if 3258 return m*(2.**e) 3259 3260 def round_flat(self,value): 3261 #redundant 3262 m,e = self.frexp(value) 3263 m = round(m,self.__precision__) 3264 return m*(2.**e) 3265 3266 def keys(self): 3267 return self.__items__.keys() 3268 3269 3270 3271 3272 class Mapped_Discretised_Tuple_Set(Discretised_Tuple_Set): 3273 """ 3274 This is a discretised tuple set, but 3275 based on a mapping. The mapping MUST 3276 return a sequence. 3277 3278 example: 3279 def weight(animal): 3280 return [animal.weight] 3281 3282 a = Mapped_Discretised_Tuple_Set(weight) 3283 a.append[cow] 3284 a.append[fox] 3285 a.append[horse] 3286 3287 a[horse] -> [cow,horse] 3288 a[dog] -> [fox] 3289 a[elephant] -> [] 3290 """ 3291 def __init__(self,mapping,precision = 6, tolerance=0.01): 3292 Discretised_Tuple_Set.__init__\ 3293 (self,precision,tolerance = tolerance) 3294 self.mapping = mapping 3295 3296 def rounded_keys(self,key): 3297 mapped_key = tuple(self.mapping(key)) 3298 keys = self.__rounded_keys__(mapped_key) 3299 return keys 3300 3301 class Affine_Linespace(Mapped_Discretised_Tuple_Set): 3302 """ 3303 The affine linespace creates a way to record and compare lines. 3304 Precision is a bit of a hack, but it creates a way to avoid 3305 misses caused by round offs (between two lines of different 3306 lenghts, the short one gets rounded off more). 3307 I am starting to think that a quadratic search would be faster. 3308 Nearly. 3309 """ 3310 def __init__(self,precision = 4,tolerance=0.04): 3311 Mapped_Discretised_Tuple_Set.__init__\ 3312 (self,self.affine_line,\ 3313 precision=precision,tolerance=tolerance) 3314 3315 def affine_line(self,line): 3316 point_1 = line[0] 3317 point_2 = line[1] 3318 #returns the equation of a line 3319 #between two points, in the from 3320 #(a,b,-c), as in ax+by-c=0 3321 #or line *dot* (x,y,1) = (0,0,0) 3322 3323 #Note that it normalises the line 3324 #(a,b,-c) so Line*Line = 1. 3325 #This does not change the mathematical 3326 #properties, but it makes comparism 3327 #easier. 3328 3329 #There are probably better algorithms. 3330 x1 = point_1[0] 3331 x2 = point_2[0] 3332 y1 = point_1[1] 3333 y2 = point_2[1] 3334 dif_x = x1-x2 3335 dif_y = y1-y2 3336 3337 if dif_x == dif_y == 0: 3338 msg = 'points are the same' 3339 raise msg 3340 elif abs(dif_x)>=abs(dif_y): 3341 alpha = (-dif_y)/dif_x 3342 #a = alpha * b 3343 b = 1. 3344 c = (x1*alpha+x2*alpha+y1+y2)/2. 3345 a = alpha*b 3346 else: 3347 beta = dif_x/(-dif_y) 3348 #b = beta * a 3349 a = 1. 3350 c = (x1+x2+y1*beta+y2*beta)/2. 3351 b = beta*a 3352 3353 mag = (a**2+b**2+c**2)**(0.5) 3354 3355 if a == 0: 3356 sign_a = 1. 3357 else: 3358 sign_a = a/((a**2)**0.5) 3359 if b == 0: 3360 sign_b = 1. 3361 else: 3362 sign_b = b/((b**2)**0.5) 3363 if c == 0: 3364 sign_c = 1. 3365 else: 3366 sign_c = c/((c**2)**0.5) 3367 a = a/mag*sign_a 3368 b = b/mag*sign_b 3369 c = c/mag*sign_c 3370 return a,b,c 3371 3372 2901 3373 if __name__ == "__main__": 2902 3374 #from mesh import * -
inundation/ga/storm_surge/pmesh/pmesh.py
r1177 r1217 339 339 340 340 def triangles_to_polySet(self,parent): 341 self.mesh.triangles_to_polySet(self.selSet) 342 #event = None 343 #for v in vertices.keys(): 344 # if vertices[v] is True: 345 # x = v.x*self.SCALE 346 # y = v.y*self.SCALE 347 # vertices[v]=self.drawVertex(x,y,event) 348 #print 'segments' 349 #print segments 350 #print 'vertices.keys()' 351 #print vertices.keys() 352 #for s in segments: 353 # v0 = vertices[s[0]] 354 # v1 = vertices[s[1]] 355 # self.drawSegment(v0,v1) 341 userVertices,userSegments,alphaSegments = \ 342 self.mesh.triangles_to_polySet(self.selSet) 343 356 344 self.canvas.delete(ALL) 345 346 self.Vertices = visualmesh.vPoints(mesh.Vertex) 347 self.Segments = visualmesh.vSegments(mesh.Segment) 348 349 event = None 350 print 'len(userVertices.keys())' 351 print len(userVertices.keys()) 352 print 'len(userSegments.keys())' 353 print len(userSegments.keys()) 354 print 'len(alphaSegments.keys())' 355 print len(alphaSegments.keys()) 356 for v in userVertices.keys(): 357 if userVertices[v] is True: 358 x = v.x*self.SCALE 359 y = v.y*self.SCALE 360 userVertices[(v.x,v.y)]=self.drawVertex(x,y,event) 361 362 for line in userSegments.keys(): 363 v0 = userVertices[line[0]] 364 v1 = userVertices[line[1]] 365 segment = self.drawSegment(v0,v1) 366 segment.set_tag(userSegments[line].tag) 367 368 for line in alphaSegments.keys(): 369 v0 = userVertices[line[0]] 370 v1 = userVertices[line[1]] 371 segment = self.drawSegment(v0,v1) 372 segment.set_tag(alphaSegments[line].tag) 357 373 self.visualiseMesh(self.mesh) 358 374 … … 458 474 region = self.drawRegion(x_origin, y_origin, 0) 459 475 region.setTag("setheight5") 476 477 460 478 461 479 x_origin = 30
Note: See TracChangeset
for help on using the changeset viewer.