Douglas-Peucker点数容差

时间:2016-02-24 17:47:35

标签: java algorithm compression

我正在尝试使用点数容差来实现Douglas-Peucker算法。我的意思是我指定我想要50%的压缩。我在Douglas-Peucker N下的http://psimpl.sourceforge.net/douglas-peucker.html页面上找到了这个算法。但我不确定这个算法是如何工作的。在java中是否有任何实现或关于此版本算法的一些良好规范?

我从psimpl中解释的是,在我们选择简化点之后会发生什么?我们将边缘分成两个新边缘并对所有点进行排名并从两个边缘选择最佳点?

2 个答案:

答案 0 :(得分:1)

DP在折线中搜索离基线最远的顶点。如果此顶点比公差更远,则会在那里拆分折线并递归应用该过程。

不幸的是,这个距离与要保留的点数之间没有关系。通常“压缩”优于50%,因此您可以尝试更深入地继续递归。但实现点密度的良好平衡看起来具有挑战性。

答案 1 :(得分:0)

将Douglas-peucker算法与迭代相结合,并将剩余点视为判断标准。 这是我的算法,数组'points'存储轨迹的点.Integer'd'是阈值。

public static Point[] divi(Point[] points,double d)
    {
    System.out.println("threshold"+d);
    System.out.println("the nth divi iteration");
    int i = 0;
    Point[] p1 = new Point[points.length];
    for (i = 0;i<points.length;i++)
        p1[i] = points[i];
    compress(p1, 0,p1.length - 1,d); //first compression
    int size = 0;                
    for (Point p : p1)    //trajectory after compression
        if(p != null)
        size ++;
    System.out.println("size of points"+size);
    if(size<=200 && size>=100)
        return p1;
    else if(size>200)
        return divi(p1,d + d/2.0);
    else
        return divi(points,d/2.0);
   }
public static void compress(Point[] points,int m, int n,double D) 
   {  
        System.out.println("threshold"+D);
        System.out.println("startIndex"+m);
        System.out.println("endIndex"+n);

        while (points[m] == null)
            m ++;

        Point from = points[m];
        while(points[n] == null)
            n--;

        Point to = points[n];

        double A = (from.x() - to.x()) /(from.y() - to.y());
        /** -
         * 由起始点和终止点构成的直线方程一般式的系数 
         */  
        double B = -1;

        double C = from.x() - A *from.y();
        double d = 0;  
        double dmax = 0;  
        if (n == m + 1)  
            return;    
       List<Double> distance = new ArrayList<Double>(); 
       for (int i = m + 1; i < n; i++) {
        if (points[i] ==null)
        {
            distance.add(0.0);
            continue; 
        }
        else
        {
         Point p = points[i];
       d = Math.abs(A * (p.y()) + B * (p.x()) + C)  / Math.sqrt(Math.pow(A, 2) + Math.pow(B, 2));  
       distance.add(d); 
        }
        }  
        dmax= Collections.max(distance);    

        if (dmax < D) 
            for(int i = n-1;i > m;i--)  
                 points[i] = null;
        else  
           {  
            int  middle = distance.indexOf(dmax) + m + 1;

            compress(points,m, middle,D);  

            compress(points,middle, n,D);  

           }  
    }