Changeset 1420


Ignore:
Timestamp:
May 18, 2005, 2:02:07 PM (19 years ago)
Author:
duncan
Message:

dsg added comments and moved some code around

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

Legend:

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

    r1381 r1420  
    1 """Alpha shape   
     1"""Alpha shape
     2Determine the shape of a set of points.
     3
     4As mentionned in Edelsbrunner's and Mucke's paper, one can
     5intuitively think of an alpha-shape as the following:
     6test
     7Imagine a huge mass of ice-cream making up the space and containing
     8the points S as ``hard'' chocolate pieces. Using one of these
     9sphere-formed ice-cream spoons we carve out all parts of the ice-cream
     10block we can reach without bumping into chocolate pieces, thereby even
     11carving out holes in the inside (eg. parts not reachable by simply
     12moving the spoon from the outside). We will eventually end up with a
     13(not necessarily convex) object bounded by caps, arcs and points. If
     14we now straighten all ``round'' faces to triangles and line segments,
     15we have an intuitive description of what is called the alpha-shape.
    216"""
    317
     
    1428
    1529def alpha_shape_via_files(point_file, boundary_file, alpha= None):
    16    
     30    """
     31    Load a point file and return the alpha shape boundary as a boundary file.
     32   
     33    Inputs:
     34    point_file: File location of the input file, points format (.xya or .pts)
     35    boundary_file: File location of the generated output file
     36    alpha: The alpha value can be optionally specified.  If it is not specified
     37    the optimum alpha value will be used.
     38"""
    1739    point_dict = import_points_file(point_file)
    1840    points = point_dict['pointlist']
    19     #title_string = point_dict['title']
    2041   
    2142    alpha = Alpha_Shape(points)
     
    2546
    2647    def __init__(self, points, alpha = None):
    27 
    28         """
    29         Inputs:
    30        
     48        """
     49        alpha_shape inputs a set of points and can return the alpha
     50        shape boundary.
     51       
     52        Inputs:       
    3153          points: List of coordinate pairs [[x1, y1],[x2, y2]..]
    32 
    33           alpha: alpha shape parameter
    34          
     54          alpha: The alpha value can be optionally specified.  If it is
     55          not specified the optimum alpha value will be used.
    3556        """
    3657        self._set_points(points)
    37         self._alpha_shape_algorithm(alpha)
     58        self._alpha_shape_algorithm(alpha=alpha)
    3859
    3960    def _set_points(self, points):
    4061        """
     62        Create self.points array, do Error checking
     63        Inputs:       
     64          points: List of coordinate pairs [[x1, y1],[x2, y2]..]
    4165        """
    4266        # print "setting points"
     
    6791    def get_boundary(self):
    6892        """
     93        Return a list of tuples.  Each tuples represents a segment,
     94        by giving the index of the segments two end points.
     95        The list of tuple represents the alpha shape.
    6996        """
    7097        return self.boundary
     
    76103                          boundary_points_fraction=0.2):
    77104        """
    78         Use the flags to set constraints on the boundary
     105        Use the flags to set constraints on the boundary:
    79106        raw_boundary   Return raw boundary i.e. the regular edges
    80107        remove_holes   filter to remove small holes
     
    111138    def get_alpha(self):
    112139        """
    113         Return current alpha value
     140        Return current alpha value.
    114141        """
    115142        return self.alpha
     
    125152   
    126153           
    127     def _alpha_shape_algorithm(self,alpha):
    128        
    129         # A python style guide suggests using _[function name] to
    130         # specify internal functions
    131         # - this is the first time I've used it though - DSG
     154    def _alpha_shape_algorithm(self, alpha=None):
     155        """
     156        Given a set of points (self.points) and an optional alpha value
     157        determines the alpha shape (stored in self.boundary,
     158        accessed by get_boundary).
     159       
     160        Inputs:
     161          alpha: The alpha value can be optionally specified.  If it is
     162          not specified the optimum alpha value will be used.
     163        """
    132164
    133165        #print "starting alpha shape algorithm"
     
    189221
    190222    def _tri_circumradius(self):
    191 
    192         # compute circumradii of the delaunay triangles
     223        """
     224        Compute circumradii of the delaunay triangles
     225        """
     226       
    193227        x = self.points[:,0]
    194228        y = self.points[:,1]
     
    244278        except ZeroDivisionError:
    245279            print "There are serious problems with the delaunay triangles"
    246             raise
     280            raise  #DSG maybe don't catch this error? Is recovery possible?
    247281 
    248282           
    249283        self.triradius = 0.5*sqrt(dx*dx + dy*dy)
    250284        #print "triangle radii", self.triradius
    251         return
     285       
    252286
    253287
    254288
    255289    def _edge_intervals(self):
    256         # for each edge, find triples
    257         # (length/2, min_adj_triradius, max_adj_triradius) if unattached
    258         # (min_adj_triradius, min_adj_triradius, max_adj_triradius) if attached.
    259 
    260         # It should be possible to rewrite this routine in an array-friendly form
    261         # like _tri_circumradius()  if we need to speed things up.
     290        """
     291         for each edge, find triples
     292         (length/2, min_adj_triradius, max_adj_triradius) if unattached
     293        (min_adj_triradius, min_adj_triradius, max_adj_triradius) if attached.
     294        """
     295       
     296        # It should be possible to rewrite this routine in an array-friendly
     297        # form like _tri_circumradius()  if we need to speed things up.
    262298
    263299        edges = []
     
    267303            tri = self.deltri[t]
    268304            trinbr = self.deltrinbr[t]
    269             dx = array([self.points[tri[(i+1)%3],0] - self.points[tri[(i+2)%3],0] for i in [0,1,2]])
    270             dy = array([self.points[tri[(i+1)%3],1] - self.points[tri[(i+2)%3],1] for i in [0,1,2]])
     305            dx = array([self.points[tri[(i+1)%3],0] -
     306                        self.points[tri[(i+2)%3],0] for i in [0,1,2]])
     307            dy = array([self.points[tri[(i+1)%3],1] -
     308                        self.points[tri[(i+2)%3],1] for i in [0,1,2]])
    271309            elen = sqrt(dx*dx+dy*dy)
    272310            #angle = array([(-dx[(i+1)%3]*dx[(i+2)%3]-dy[(i+1)%3]*dy[(i+2)%3])/(elen[(i+1)%3]*elen[(i+2)%3]) for i in [0,1,2]])
    273311            #angle = arccos(angle)
    274312            # really only need sign - not angle value:
    275             anglesign = array([(-dx[(i+1)%3]*dx[(i+2)%3]-dy[(i+1)%3]*dy[(i+2)%3]) for i in [0,1,2]])
     313            anglesign = array([(-dx[(i+1)%3]*dx[(i+2)%3]-
     314                                dy[(i+1)%3]*dy[(i+2)%3]) for i in [0,1,2]])
    276315           
    277316            #print "dx ",dx,"\n"
     
    291330                    edgenbrs.append((t, trinbr[i]))
    292331                    edgeinterval.append([0.5*elen[i],\
    293                                          min(self.triradius[t],self.triradius[trinbr[i]]),\
    294                                              max(self.triradius[t],self.triradius[trinbr[i]]) ])
     332                       min(self.triradius[t],self.triradius[trinbr[i]]),\
     333                          max(self.triradius[t],self.triradius[trinbr[i]]) ])
    295334                else:
    296335                    continue
     
    307346
    308347    def _vertex_intervals(self):
    309         # for each vertex find pairs
    310         # (min_adj_triradius, max_adj_triradius)
     348        """
     349        for each vertex find pairs
     350        (min_adj_triradius, max_adj_triradius)
     351        """
    311352        nv = len(self.points)
    312353        vertexnbrs = [ [] for i in range(nv)]
     
    331372                # print "nbr radii: ",radii
    332373                # vertexinterval[i] = [0,INF]
     374
     375                #DSG is it ok to catch this error and continue?
    333376                pass
    334377
     
    354397        """
    355398        def reg_edge(k):
    356             return self.edgeinterval[k][1]<=alpha and self.edgeinterval[k][2]>alpha
     399            return self.edgeinterval[k][1]<=alpha and \
     400                   self.edgeinterval[k][2]>alpha
    357401
    358402        return filter(reg_edge, range(len(self.edgeinterval)))
     
    364408        """
    365409        def exp_vert(k):
    366             return self.vertexinterval[k][0]<=alpha and self.vertexinterval[k][1]>alpha
     410            return self.vertexinterval[k][0]<=alpha and \
     411                   self.vertexinterval[k][1]>alpha
    367412
    368413        return filter(exp_vert, range(len(self.vertexinterval)))       
     
    562607            # an acute angle spanned by two edges along the boundary..
    563608            # MUST FIX.
     609            #DSG - should this be fixed?
    564610            if anglesign[tind[1]] > 0:
    565611                acutetri.append(tind[0])
     
    646692    import os, sys
    647693    usage = "usage: %s point_file.xya boundary_file.bnd [alpha]"%os.path.basename(sys.argv[0])
    648     # I made up the .bnd affix. Other ideas welcome. -DSG
    649694    if len(sys.argv) < 3:
    650695        print usage
  • inundation/ga/storm_surge/alpha_shape/test_alpha_shape.py

    r1364 r1420  
    346346(126.437678428,28.0083464873), \
    347347(133.639824668,50.0149044415), \
    348 (176.852702105,43.612996673), \alpha = Alpha_Shape(
     348(176.852702105,43.612996673), \
    349349(123.636843779,-24.4072733675), \
    350350(73.6219393379,35.2104927268), \
Note: See TracChangeset for help on using the changeset viewer.