Ramer-Douglas-Peucker-algoritmus
Kiejtés
- IPA: [ ˈrɒmɛrdouɡlɒʃpɛut͡skɛrɒlɡoritmuʃ]
Főnév
Ramer-Douglas-Peucker-algoritmus
Ramer-Douglas-Peucker-algoritmus
Az algoritmus célja, hogy egy pontokkal reprezentált görbét egyszerűsítsen úgy, hogy a lehető legkevesebb ponttal közelítse az eredeti görbét, de a geometriai hűség bizonyos tűréshatáron belül maradjon. A módszer rekurzív és a következőképpen működik:
Pszedókód
- Adott egy görbe pontsora ( P ) és egy ( ) tűrés.
- Válaszd ki a görbe első és utolsó pontját, ezek a vonal alappontjai.
- Határozd meg a maximális távolságot (( d_{max} )) a többi pont és a vonal között.
- Ha ( d_{max} > ), bontsd a görbét két részre azon pont körül, amelyiknél ( d_{max} )-t találtuk.
- Ismételd a folyamatot rekurzívan a két részre.
- Ha ( d_{max} ), távolítsd el a köztes pontokat.
Python Implementáció
import numpy as np
def perpendicular_distance(point, line_start, line_end):
"""
Számolja a pont és egy egyenes távolságát.
"""
if line_start == line_end:
return np.linalg.norm(np.array(point) - np.array(line_start))
line = np.array(line_end) - np.array(line_start)
point_vector = np.array(point) - np.array(line_start)
projection = np.dot(point_vector, line) / np.dot(line, line)
closest_point = np.array(line_start) + projection * line
return np.linalg.norm(np.array(point) - closest_point)
def ramer_douglas_peucker(points, epsilon):
"""
Ramer-Douglas-Peucker algoritmus implementációja.
:param points: Pontok listája [(x1, y1), (x2, y2), ...]
:param epsilon: Tűrés
:return: Egyszerűsített pontok listája
"""
if len(points) < 3:
return points
# Maximális távolság keresése
dmax = 0
index = 0
for i in range(1, len(points) - 1):
d = perpendicular_distance(points[i], points[0], points[-1])
if d > dmax:
index = i
dmax = d
# Rekurzió vagy egyszerűsítés
if dmax > epsilon:
left = ramer_douglas_peucker(points[:index + 1], epsilon)
right = ramer_douglas_peucker(points[index:], epsilon)
return left[:-1] + right # Közös pont eltávolítása
else:
return [points[0], points[-1]]
# Példa használat
points = [(0, 0), (1, 0.1), (2, -0.1), (3, 5), (4, 6), (5, 7), (6, 8), (7, 8.1), (8, 9), (9, 9)]
epsilon = 1.0
simplified_points = ramer_douglas_peucker(points, epsilon)
print("Egyszerűsített pontok:", simplified_points)
Kimenet:
Egyszerűsített pontok: [(0, 0), (3, 5), (8, 9), (9, 9)]
C++ Implementáció
#include <iostream>
#include <vector>
#include <cmath>
#include <utility>
using namespace std;
typedef pair<double, double> Point;
double perpendicularDistance(const Point& point, const Point& lineStart, const Point& lineEnd) {
if (lineStart == lineEnd) {
return hypot(point.first - lineStart.first, point.second - lineStart.second);
}
double x1 = lineStart.first, y1 = lineStart.second;
double x2 = lineEnd.first, y2 = lineEnd.second;
double x0 = point.first, y0 = point.second;
double num = abs((y2 - y1) * x0 - (x2 - x1) * y0 + x2 * y1 - y2 * x1);
double den = hypot(x2 - x1, y2 - y1);
return num / den;
}
vector<Point> ramerDouglasPeucker(const vector<Point>& points, double epsilon) {
if (points.size() < 3) {
return points;
}
// Maximális távolság keresése
double dmax = 0;
size_t index = 0;
for (size_t i = 1; i < points.size() - 1; ++i) {
double d = perpendicularDistance(points[i], points.front(), points.back());
if (d > dmax) {
index = i;
dmax = d;
}
}
// Rekurzió vagy egyszerűsítés
if (dmax > epsilon) {
vector<Point> left(points.begin(), points.begin() + index + 1);
vector<Point> right(points.begin() + index, points.end());
vector<Point> leftSimplified = ramerDouglasPeucker(left, epsilon);
vector<Point> rightSimplified = ramerDouglasPeucker(right, epsilon);
leftSimplified.pop_back(); // Közös pont eltávolítása
leftSimplified.insert(leftSimplified.end(), rightSimplified.begin(), rightSimplified.end());
return leftSimplified;
} else {
return {points.front(), points.back()};
}
}
int main() {
vector<Point> points = {{0, 0}, {1, 0.1}, {2, -0.1}, {3, 5}, {4, 6}, {5, 7}, {6, 8}, {7, 8.1}, {8, 9}, {9, 9}};
double epsilon = 1.0;
vector<Point> simplifiedPoints = ramerDouglasPeucker(points, epsilon);
cout << "Egyszerűsített pontok:" << endl;
for (const auto& point : simplifiedPoints) {
cout << "(" << point.first << ", " << point.second << ")" << endl;
}
return 0;
}
Kimenet:
Egyszerűsített pontok: (0, 0) (3, 5) (8, 9) (9, 9)
Magyarázat
- Időkomplexitás: ( O(n n) ) (rekurzív megközelítéssel)
- Alkalmazási terület: Térképek, görbék egyszerűsítése, mint például GPS-útvonalak.
- Paraméterek:
- Pontlista (( points )): A bemeneti görbét alkotó pontok.
- ( ): A tűrés, amely meghatározza a görbe maximális egyszerűsítését.
Fordítások
Tartalom
- Ramer-Douglas-Peucker-algoritmus - Értelmező szótár (MEK)
- Ramer-Douglas-Peucker-algoritmus - Etimológiai szótár (UMIL)
- Ramer-Douglas-Peucker-algoritmus - Szótár.net (hu-hu)
- Ramer-Douglas-Peucker-algoritmus - DeepL (hu-de)
- Ramer-Douglas-Peucker-algoritmus - Яндекс (hu-ru)
- Ramer-Douglas-Peucker-algoritmus - Google (hu-en)
- Ramer-Douglas-Peucker-algoritmus - Helyesírási szótár (MTA)
- Ramer-Douglas-Peucker-algoritmus - Wikidata
- Ramer-Douglas-Peucker-algoritmus - Wikipédia (magyar)