Java Douglas Peucker点计数公差

Java Douglas Peucker点计数公差,java,algorithm,compression,Java,Algorithm,Compression,我正在尝试用点计数容差实现Douglas Peucker算法。我的意思是我指定我想要50%的压缩。我在Douglas Peucker N.的网页上找到了这个算法,但我不确定这个算法是如何工作的。这个版本的算法是否有java实现或者一些好的规范 从psimpl的解释中我不明白的是,在我们选择第一个点进行简化之后会发生什么?我们将把边分成两条新边,对所有点进行排序,并从两条边中选择最佳点 DP在多段线中搜索距离基线最远的顶点。如果该顶点大于公差,则多段线将在此处拆分,并递归应用该过程 不幸的是,这个

我正在尝试用点计数容差实现Douglas Peucker算法。我的意思是我指定我想要50%的压缩。我在Douglas Peucker N.的网页上找到了这个算法,但我不确定这个算法是如何工作的。这个版本的算法是否有java实现或者一些好的规范


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

DP在多段线中搜索距离基线最远的顶点。如果该顶点大于公差,则多段线将在此处拆分,并递归应用该过程


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

< P>将Douglas peucker算法与迭代相结合,并将剩余点作为判断准则。 这是我的算法,数组“points”存储轨迹的点。整数“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);  

           }  
    } 
公共静态点[]divi(点[]点,双d)
{
系统输出打印项次(“阈值”+d);
System.out.println(“第n次divi迭代”);
int i=0;
点[]p1=新点[点.长度];
对于(i=0;i200)
返回分区(p1,d+d/2.0);
其他的
返回分区(点数,d/2.0);
}
公共静态无效压缩(点[]点,int m,int n,双D)
{  
系统输出打印项次(“阈值”+D);
系统输出打印项次(“startIndex”+m);
System.out.println(“endIndex”+n);
while(点[m]==null)
m++;
起点=点[m];
while(点[n]==null)
n--;
点对点=点[n];
双A=(从.x()-到.x())/(从.y()-到.y());
/** -
* 由起始点和终止点构成的直线方程一般式的系数 
*/  
双B=-1;
双C=from.x()-A*from.y();
双d=0;
双dmax=0;
如果(n==m+1)
返回;
列表距离=新的ArrayList();
对于(int i=m+1;im;i--)
点[i]=null;
其他的
{  
int middle=距离。indexOf(dmax)+m+1;
压缩(点,m,中间,D);
压缩(点、中间、n、D);
}  
} 

在google上搜索时发现了这一点,这可能会有所帮助。这是算法的正常版本。我正在寻找的版本,您可以指定的结果点数。查看上面提到的链接,您将看到此算法的正常版本使用阈值,第二个版本使用点数。您可以只需编辑主数组。它不应该太难。如果您对使用Douglas Peucker算法不太挑剔,肯定会给您此控制。请看一些比较。我有类似的要求张贴在这里。代码上面提到的功能几乎相同。但在你们找到距离基线最远的顶点后,你们把它添加到新的图形中,并把基线分成两条基线。再一次,你们找到离这两条基线最远的点,把其中一条基线分成两条。现在你有了三条基线。利用这一原理,您可以选择在新图形中有多少点。但我不确定这个算法是否“正确”或理解是否正确。@user1816532:将其分成三部分而不是两部分是没有帮助的。