107 lines
4.1 KiB
Java
107 lines
4.1 KiB
Java
/*This is a Java Program to implement Douglas-Peucker Algorithm. The Ramer–Douglas–Peucker algorithm (RDP) is an algorithm for reducing the number of points in a curve that is approximated by a series of points. This algorithm is also known under the names Douglas–Peucker algorithm, iterative end-point fit algorithm and split-and-merge algorithm. The purpose of the algorithm is, given a curve composed of line segments, to find a similar curve with fewer points. The algorithm defines ‘dissimilar’ based on the maximum distance between the original curve and the simplified curve. The simplified curve consists of a subset of the points that defined the original curve.*/
|
||
|
||
//This is a java program to filter out points using Douglas Peucker Algorithm
|
||
import static java.lang.Math.abs;
|
||
import static java.lang.Math.pow;
|
||
import static java.lang.Math.sqrt;
|
||
|
||
import java.util.Random;
|
||
|
||
class RamerDouglasPeuckerFilter
|
||
{
|
||
|
||
private double epsilon;
|
||
|
||
public RamerDouglasPeuckerFilter(double epsilon)
|
||
{
|
||
if (epsilon <= 0)
|
||
{
|
||
throw new IllegalArgumentException("Epsilon nust be > 0");
|
||
}
|
||
this.epsilon = epsilon;
|
||
}
|
||
|
||
public double[] filter(double[] data)
|
||
{
|
||
return ramerDouglasPeuckerFunction(data, 0, data.length - 1);
|
||
}
|
||
|
||
public double getEpsilon()
|
||
{
|
||
return epsilon;
|
||
}
|
||
|
||
protected double[] ramerDouglasPeuckerFunction(double[] points,
|
||
int startIndex, int endIndex)
|
||
{
|
||
double dmax = 0;
|
||
int idx = 0;
|
||
double a = endIndex - startIndex;
|
||
double b = points[endIndex] - points[startIndex];
|
||
double c = -(b * startIndex - a * points[startIndex]);
|
||
double norm = sqrt(pow(a, 2) + pow(b, 2));
|
||
for (int i = startIndex + 1; i < endIndex; i++)
|
||
{
|
||
double distance = abs(b * i - a * points[i] + c) / norm;
|
||
if (distance > dmax)
|
||
{
|
||
idx = i;
|
||
dmax = distance;
|
||
}
|
||
}
|
||
if (dmax >= epsilon)
|
||
{
|
||
double[] recursiveResult1 = ramerDouglasPeuckerFunction(points,
|
||
startIndex, idx);
|
||
double[] recursiveResult2 = ramerDouglasPeuckerFunction(points,
|
||
idx, endIndex);
|
||
double[] result = new double[(recursiveResult1.length - 1)
|
||
+ recursiveResult2.length];
|
||
System.arraycopy(recursiveResult1, 0, result, 0,
|
||
recursiveResult1.length - 1);
|
||
System.arraycopy(recursiveResult2, 0, result,
|
||
recursiveResult1.length - 1, recursiveResult2.length);
|
||
return result;
|
||
}
|
||
else
|
||
{
|
||
return new double[] { points[startIndex], points[endIndex] };
|
||
}
|
||
}
|
||
|
||
public void setEpsilon(double epsilon)
|
||
{
|
||
if (epsilon <= 0)
|
||
{
|
||
throw new IllegalArgumentException("Epsilon nust be > 0");
|
||
}
|
||
this.epsilon = epsilon;
|
||
}
|
||
|
||
}
|
||
|
||
public class Douglas_Peucker_Algorithm
|
||
{
|
||
public static void main(String args[])
|
||
{
|
||
Random random = new Random();
|
||
double[] points = new double[20];
|
||
double[] fpoints;
|
||
for (int i = 0; i < points.length; i++)
|
||
points[i] = random.nextInt(10);
|
||
RamerDouglasPeuckerFilter rdpf = new RamerDouglasPeuckerFilter(1);
|
||
fpoints = rdpf.filter(points);
|
||
System.out.println("Orginal points");
|
||
for (int i = 0; i < points.length; i++)
|
||
System.out.print(points[i] + " ");
|
||
System.out.println("\nFiltered points");
|
||
for (int i = 0; i < fpoints.length; i++)
|
||
System.out.print(fpoints[i] + " ");
|
||
}
|
||
}
|
||
|
||
/*
|
||
Orginal points
|
||
5.0 0.0 8.0 7.0 2.0 9.0 4.0 4.0 0.0 7.0 4.0 1.0 9.0 6.0 8.0 9.0 6.0 6.0 9.0 6.0
|
||
Filtered points
|
||
5.0 0.0 8.0 2.0 9.0 0.0 7.0 1.0 9.0 6.0 9.0 6.0 9.0 6.0 |