Cho đường polyline C được tạo bởi tập hợp các đoạn thẳng nối tiếp nhau của một tập hợp điểm. Cho trước một độ error rate nhất định, rút gọn số lượng điểm của tập hợp này sao cho vẫn giữ được hình dạng của đường C ban đầu.
Thuật toán này còn được biết đến với tên là Ramer–Douglas–Peucker.Thuật toán được phát triển độc lập bởi Urs Ramer vào năm 1972 và bởi David Douglas và Thomas Peucker vào năm 1973.
Cho đường dưới dạng tập hợp của điểm sắp xếp thứ tự: và một giá trị độ sai .
Ta định nghĩa hàm là hàm lược bỏ các điểm trong tập điểm từ index đến như sau:
Cho lần lượt nhận giá trị từ đến :
Tính , với:
là đoạn thẳng nối và
Hàm là hàm đo khoảng cách từ điểm đến
Tìm
Nếu : tất cả các điểm từ đến đều có thể lược bỏ
Nếu tại index thứ , ta chia đoạn thẳng thành 2 phần để thực hiện gọi đệ quy như sau:
Minh họa

Source Code
// pointIndices là mảng để lưu trữ các index được giữ lại sau quá trình thu gọn
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;
}
}
// tolerance là giá trị delta
if ((maxD > tolerance) && (indexFurthest != 0)){
pointIndices.push(indexFurthest);
fReduce(points, firstPoint, indexFurthest, tolerance, pointIndices)
fReduce(points, indexFurthest, lastPoint, tolerance, pointIndices)
}
}
Khoảng cách từ điểm đến đoạn là chiều dài đoạn
Ta có:
Tuy nhiên, có thể được tính bởi công thức cross product của vector và như sau:
Với là góc tạo bởi vector
Source code
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;
}No comments yet. Be the first to comment!