Finding centre of a polygon using limited data

前端 未结 3 797
無奈伤痛
無奈伤痛 2021-02-02 03:59

I\'m implementing Voronoi tesselation followed by smoothing. For the smoothing I was going to do Lloyd relaxation, but I\'ve encountered a problem.

I\'m using following

3条回答
  •  北恋
    北恋 (楼主)
    2021-02-02 04:59

    This is @mgamba's answer, rewritten in a bit more of a python style. In particular, it uses itertools.cycle on the points so that "one-plus-the-last-point" can be treated as the first point in a more natural way.

    import itertools as IT
    
    def area_of_polygon(x, y):
        """Calculates the signed area of an arbitrary polygon given its verticies
        http://stackoverflow.com/a/4682656/190597 (Joe Kington)
        http://softsurfer.com/Archive/algorithm_0101/algorithm_0101.htm#2D%20Polygons
        """
        area = 0.0
        for i in xrange(-1, len(x) - 1):
            area += x[i] * (y[i + 1] - y[i - 1])
        return area / 2.0
    
    def centroid_of_polygon(points):
        """
        http://stackoverflow.com/a/14115494/190597 (mgamba)
        """
        area = area_of_polygon(*zip(*points))
        result_x = 0
        result_y = 0
        N = len(points)
        points = IT.cycle(points)
        x1, y1 = next(points)
        for i in range(N):
            x0, y0 = x1, y1
            x1, y1 = next(points)
            cross = (x0 * y1) - (x1 * y0)
            result_x += (x0 + x1) * cross
            result_y += (y0 + y1) * cross
        result_x /= (area * 6.0)
        result_y /= (area * 6.0)
        return (result_x, result_y)
    
    def demo_centroid():
        points = [
            (30,50),
            (200,10),
            (250,50),
            (350,100),
            (200,180),
            (100,140),
            (10,200)
            ]
        cent = centroid_of_polygon(points)
        print(cent)
        # (159.2903828197946, 98.88888888888889)
    
    demo_centroid()
    

提交回复
热议问题