Point reduction algorithm Ramer – Douglas – Peuker

💡 Let C be a path created by a set of consecutive line segments of a set of points. Given a certain error rate, reduce the number of points in this set so that the shape of the original path C is still maintained.

This algorithm is also known as Ramer–Douglas–Peucker. The algorithm was developed independently by Urs Ramer in 1972 and by David Douglas and Thomas Peucker in 1973.

Given C be a path by set of n ordered points:

C={P1,P2,,Pn} and an tolerance rate δ>0

We define function fReduce(points,start,end,δ) is the function to reduce points in points from start index to end index as following:

  • Let i=[(start+1)(end1)]

  • Calculate di=d(Pi,PstartPend) inwhich:

    • PstartPend is the line segment that connects Pstart and Pend

    • function d(Pi,PiPj) is the function to measure the Euclidean distance from Pi to PiPj

  • Find dmax=maxd(Pi,PstartPend)

  • If dmaxδ: remove all points [Pstart+1Pend1]

  • If dmax>δ at the kth index, we split the points at k and makes 2 recursive calls:

    • fReduce(points,start,k,δ)

    • fReduce(points,k,end,δ)

Illustration

Source Code

 
				
					// pointIndices is the array to store points after reduction process
function fReduce(points, firstPoint, lastPoint, tolerance, pointIndices){
    let maxD = 0;
    let indexFurthest = 0;

    for (let i=firstPoint + 1; i< lastPoint - 1; i++){
        let distance = dPointLine(points[i], points[firstPoint], points[lastPoint]);
        if (distance > maxD){
            maxD = distance;
            // lưu index của điểm xa nhất 
            indexFurthest = i;
        }
    }

    if ((maxD > tolerance) && (indexFurthest != 0)){
        pointIndices.push(indexFurthest);
        // recursive calls
        fReduce(points, firstPoint, indexFurthest, tolerance, pointIndices)
        fReduce(points, indexFurthest, lastPoint, tolerance, pointIndices)
    }
}

				
			

Distance from A to BC is the length of AH. Knowing:

SABC=AH×BC2AH=2×SABCBC

SABC can be calculated by the cross product of those vectors AB and AC:

2×SABC=|AB||AC||sinθ|=|AB×AC|AH=|AB×AC|2

With θ is the angle by AB and AC.

Souce code

				
					// calculate distance from point p1 to line p2p3
function dPointLine(p1, p2, p3){
    let area = Math.abs(0.5 * (p2.x * p3.y + p3.x * p1.y + p1.x * p2.y - p3.x * p2.y - p1.x * p3.y - p2.x * p1.y))    

    let bottom = p2.dist(p3);
    let height = area / bottom * 2.0;

    return height;
}
				
			

Subscribe to SkyGLab

Scroll to Top