Changeset 956


Ignore:
Timestamp:
Feb 25, 2005, 11:59:06 AM (19 years ago)
Author:
duncan
Message:

update from vanessa

Location:
inundation/ga/storm_surge/alpha_shape
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • inundation/ga/storm_surge/alpha_shape/alpha_shape.py

    r855 r956  
    1212INF = pow(10,9)
    1313
    14 def alpha_shape_via_files(point_file, boundary_file, alpha= None):
     14def alpha_shape_via_files(point_file, boundary_file, alpha= None):   
    1515   
    1616    point_dict = load_points_file(point_file)
     
    6969        """
    7070        return self.boundary
     71
     72    def set_boundary_type(self,flag=0):
     73        """
     74        Use the flag to set constraints on the boundary
     75        0   Return raw boundary i.e. the regular edges
     76        1   filter to remove small holes
     77        2   (includes 1) plus remove sharp indents in boundary
     78        3   (includes 2) plus test for pinch-off i.e. boundary vertex with more than two edges.
     79        """
     80        reg_edge = self.get_regular_edges(self.alpha)
     81        bdry = [self.edge[k] for k in reg_edge]
     82
     83        if flag>=1 :
     84            #remove holes
     85            bdry = self._remove_holes(bdry)
     86        if flag>=2:
     87            #remove sharp indents
     88            bdry = self._smooth_indents(bdry)
     89        if flag>=3:
     90            #deal with pinch-off
     91            bdry = self._expand_pinch(bdry)
     92       
     93        self.boundary = bdry
     94       
    7195
    7296    def get_delaunay(self):
     
    220244            print "There are serious problems with the delaunay triangles"
    221245            raise
    222             # really need to take care of cases when denom = 0.
    223             # eg: something like:
    224             # print "Handling degenerate triangles."
    225             # ... add some random displacments to trouble points?
     246 
    226247           
    227248        self.triradius = 0.5*sqrt(dx*dx + dy*dy)
     
    406427        return filter(reg_edge, range(len(self.edgeinterval)))
    407428
    408        
     429    def get_exposed_vertices(self,alpha):
     430        """
     431        Given an alpha value,
     432        return the vertices on the boundary of the alpha-shape
     433        """
     434        def exp_vert(k):
     435            return self.vertexinterval[k][0]<=alpha and self.vertexinterval[k][1]>alpha
     436
     437        return filter(exp_vert, range(len(self.vertexinterval)))       
     438
     439       
     440    def _remove_holes(self,bdry):
     441        """
     442        Given the edges in bdry, find the largest exterior components.
     443        """
     444        def findroot(i):
     445            if vptr[i] < 0:
     446                return i
     447            k = findroot(vptr[i])
     448            vptr[i] = k
     449            return k
     450
     451
     452
     453        # get a list of unique vertex labels:
     454        v1 = [bdry[k][0] for k in range(len(bdry))]
     455        v2 = [bdry[k][1] for k in range(len(bdry))]
     456        v = v1+v2
     457        v.sort()
     458        verts = [v[k] for k in range(len(v)) if v[k]!=v[k-1] ]
     459        #print "verts ", verts, "\n"
     460
     461        #initialise vptr and eptr to negative number outside range
     462        EMPTY = -max(verts) - len(bdry)
     463        vptr = [EMPTY for k in range(len(verts))]
     464        eptr = [EMPTY for k in range(len(bdry))]
     465        #print "vptr init: ", vptr, "\n"
     466
     467        #add edges and maintain union tree
     468        for i in range(len(bdry)):
     469            #print "edge ",i,"\t",bdry[i]
     470            vl = verts.index(bdry[i][0])
     471            vr = verts.index(bdry[i][1])
     472            #rvl = vl, rvr = vr
     473            rvl = findroot(vl)
     474            rvr = findroot(vr)
     475            #print "roots:  ",rvl, rvr
     476            if not(rvl==rvr):
     477                if (vptr[vl]==EMPTY):
     478                    if (vptr[vr]==EMPTY):
     479                        vptr[vl] = -2
     480                        vptr[vr] = vl
     481                        #eprt[i] = vl
     482                    else:
     483                        vptr[vl] = rvr
     484                        vptr[rvr] -= 1
     485                else:
     486                    if (vptr[vr]==EMPTY):
     487                        vptr[vr] = rvl
     488                        vptr[rvl] -= 1
     489                    else:
     490                        if vptr[rvl] > vptr[rvr]:
     491                            vptr[rvl] = rvr
     492                            vptr[rvr] += vptr[rvl]
     493                        else:
     494                            vptr[rvr] = rvl
     495                            vptr[rvl] += vptr[rvr]
     496                #print "vptr: ", vptr, "\n"
     497
     498        # end edge loop
     499
     500        #print "vertex component tree: ", vptr, "\n"
     501
     502        # discard the edges in the little components
     503        # (i.e. those components with less than twenty percent of bdry points)
     504        cutoff = round(0.2*len(verts))
     505        littleind = [k for k in range(len(vptr)) if (vptr[k]<0 and vptr[k]>-cutoff)]
     506        if littleind:
     507            littlecomp = [k for k in range(len(vptr)) if findroot(k) in littlecomp]
     508            vdiscard = [verts[k] for k in littlecomp]
     509            newbdry = [e for e in bdry if not((e[0] in vdiscard) or (e[1] in vdiscard))]
     510        else:
     511            newbdry = bdry
     512
     513        return newbdry
     514
     515
     516
     517    def _smooth_indents(self,bdry):
     518        """
     519        Given edges in bdry, test for acute-angle indents and remove them.
     520        """
     521        return newbdry
     522
     523    def _expand_pinch(self,bdry):
     524        """
     525        Given edges in bdry, test for vertices with more than 4 incident edges.
     526        Expand by adding back in associated triangles...
     527       
     528        """
     529        return newbdry
    409530   
    410531#-------------------------------------------------------------
  • inundation/ga/storm_surge/alpha_shape/test_alpha_shape.py

    r709 r956  
    9797
    9898
    99    
    100     def test_alpha_optional_alpha(self):
    101         #print "test_alpha"
     99    def test_boundary(self):
    102100        a = [0.0, 0.0]
    103         b = [1.0, 0.0]
    104         c = [2.0, 0.0]
    105         d = [2.0, 2.0]
    106         e = [1.0, 2.0]
    107         f = [0.0, 2.0]
     101        b = [2.0, 0.0]
     102        c = [4.0, 0.0]
     103        cd = [3.0,2.0]
     104        d = [4.0, 4.0]
     105        e = [2.0, 4.0]
     106        f = [0.0, 4.0]
    108107
    109         shape = Alpha_Shape([a,b,c,d,e,f])
    110         result = shape.get_boundary()
     108        alpha = Alpha_Shape([a,b,c,cd,d,e,f])
     109        alpha.set_boundary_type(1)
     110        result = alpha.get_boundary()
    111111        #print "result",result
    112         answer = [(5, 0), (0, 1), (4, 5), (2, 3), (3, 4), (1, 2)]
    113         assert allclose(answer, result)
     112        answer = [(0, 3), (3, 6), (0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]
     113        assert allclose(answer, result)
     114        pass
     115
    114116       
    115         optimum_alpha = shape.get_optimum_alpha()
    116         alpha = shape.get_alpha()
    117        
    118         self.failUnless( optimum_alpha == alpha,
    119                         'alpha is wrong!')
    120 
    121         #New instance, setting optional alpha
    122         shape = Alpha_Shape([a,b,c,d,e,f], alpha = optimum_alpha)
    123         result = shape.get_boundary()
    124         #print "result",result
    125         answer = [(5, 0), (0, 1), (4, 5), (2, 3), (3, 4), (1, 2)]
    126         assert allclose(answer, result)
    127 
    128         shape.set_alpha(optimum_alpha)
    129         result = shape.get_boundary()
    130         #print "result",result
    131         answer = [(5, 0), (0, 1), (4, 5), (2, 3), (3, 4), (1, 2)]
    132         assert allclose(answer, result)
    133        
    134        
    135            
    136117    def test_not_enough_points(self):
    137118        #print "test_not_enought_points"
     
    156137        #(h,fileName) = tempfile.mkstemp(".xya")
    157138        file = open(fileName,"w")
    158         file.write("title row \n\
     139        file.write("\n\
    1591400.0, 0.0\n\
    1601411.0, 0.0\n\
Note: See TracChangeset for help on using the changeset viewer.