【问题标题】:Python : Ramer-Douglas-Peucker (RDP) algorithm with number of points instead of epsilonPython:具有点数而不是 epsilon 的 Ramer-Douglas-Peucker (RDP) 算法
【发布时间】:2016-06-21 14:09:36
【问题描述】:

我想为RDP algorithm修改以下python脚本,目的是不使用epsilon,而是选择我想在决赛中保留的点数:

class DPAlgorithm():

    def distance(self,  a, b):
        return  sqrt((a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2)

    def point_line_distance(self,  point, start, end):
        if (start == end):
            return self.distance(point, start)
        else:
            n = abs(
                (end[0] - start[0]) * (start[1] - point[1]) - (start[0] - point[0]) * (end[1] - start[1])
            )
            d = sqrt(
                (end[0] - start[0]) ** 2 + (end[1] - start[1]) ** 2
            )
            return n / d

    def rdp(self, points, epsilon):
        """
        Reduces a series of points to a simplified version that loses detail, but
        maintains the general shape of the series.
        """
        dmax = 0.0
        index = 0
        i=1
        for i in range(1, len(points) - 1):
            d = self.point_line_distance(points[i], points[0], points[-1])
            if d > dmax :
                index = i
                dmax = d

        if dmax >= epsilon :
            results = self.rdp(points[:index+1], epsilon)[:-1] + self.rdp(points[index:], epsilon)
        else:
            results = [points[0], points[-1]]
        return results

我发现了一个具有这种精神的 Java 脚本:https://gist.github.com/msbarry/9152218

有人知道 Python 3.X 的版本吗?

谢谢 妈咪

【问题讨论】:

    标签: python algorithm computational-geometry simplification


    【解决方案1】:

    将以上链接中的 JS 代码移植到 Python [2.7]:

    # -*- coding: utf-8 -*-
    
    import math
    import time
    
    
    def timenow():
        return int(time.time() * 1000)
    
    def sqr(x):
        return x*x
    
    def distSquared(p1, p2):
        return sqr(p1[0] - p2[0]) + sqr(p1[1] - p2[1])
    
    class Line(object):
        def __init__(self, p1, p2):
            self.p1 = p1
            self.p2 = p2
            self.lengthSquared = distSquared(self.p1, self.p2)
    
        def getRatio(self, point):
            segmentLength = self.lengthSquared
            if segmentLength == 0:
                return distSquared(point, p1);
            return ((point[0] - self.p1[0]) * (self.p2[0] - self.p1[0]) + \
            (point[1] - self.p1[1]) * (self.p2[1] - self.p1[1])) / segmentLength
    
        def distanceToSquared(self, point):
            t = self.getRatio(point)
    
            if t < 0:
                return distSquared(point, self.p1)
            if t > 1:
                return distSquared(point, self.p2)
    
            return distSquared(point, [
                self.p1[0] + t * (self.p2[0] - self.p1[0]),
                self.p1[1] + t * (self.p2[1] - self.p1[1])
            ])
    
        def distanceTo(self, point):
            return math.sqrt(self.distanceToSquared(point))
    
    
    def simplifyDouglasPeucker(points, pointsToKeep):
        weights = []
        length = len(points)
    
        def douglasPeucker(start, end):
            if (end > start + 1):
                line = Line(points[start], points[end])
                maxDist = -1
                maxDistIndex = 0
    
                for i in range(start + 1, end):
                    dist = line.distanceToSquared(points[i])
                    if dist > maxDist:
                        maxDist = dist
                        maxDistIndex = i
    
                weights.insert(maxDistIndex, maxDist)
    
                douglasPeucker(start, maxDistIndex)
                douglasPeucker(maxDistIndex, end)
    
        douglasPeucker(0, length - 1)
        weights.insert(0, float("inf"))
        weights.append(float("inf"))
    
        weightsDescending = weights
        weightsDescending = sorted(weightsDescending, reverse=True)
    
        maxTolerance = weightsDescending[pointsToKeep - 1]
        result = [
            point for i, point in enumerate(points) if weights[i] >= maxTolerance
        ]
    
        return result
    

    【讨论】:

      猜你喜欢
      • 2018-11-18
      • 2015-03-08
      • 1970-01-01
      • 2021-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-27
      • 2016-05-19
      相关资源
      最近更新 更多