data simplification
line reduction
point reduction
geometry optimization
data compression

Reduce number of points in line

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

Reducing points in a polyline is a tradeoff between geometric fidelity and computational cost. This problem appears in map rendering, telemetry compression, and graphics pipelines where raw point streams are too large to store or draw efficiently. A good simplification strategy makes tolerance and error behavior explicit.

Core Sections

Define simplification target and tolerance

Before choosing an algorithm, decide what you optimize for: visual similarity, metric accuracy, or transmission size. Tolerance should be tied to domain units, not arbitrary constants.

For map data, tolerance might be meters. For UI drawing, it might be pixels. For sensor streams, it might be maximum allowed positional deviation.

Douglas-Peucker for shape-preserving simplification

Douglas-Peucker recursively keeps points with high perpendicular distance and removes low-impact points. It is widely used when shape preservation is important.

python
1from math import hypot
2
3
4def point_line_distance(p, a, b):
5    ax, ay = a
6    bx, by = b
7    px, py = p
8
9    if a == b:
10        return hypot(px - ax, py - ay)
11
12    t = ((px - ax) * (bx - ax) + (py - ay) * (by - ay)) / ((bx - ax) ** 2 + (by - ay) ** 2)
13    t = max(0.0, min(1.0, t))
14    proj = (ax + t * (bx - ax), ay + t * (by - ay))
15    return hypot(px - proj[0], py - proj[1])
16
17
18def douglas_peucker(points, eps):
19    if len(points) <= 2:
20        return points
21
22    a, b = points[0], points[-1]
23    idx, max_dist = 0, -1.0
24
25    for i in range(1, len(points) - 1):
26        d = point_line_distance(points[i], a, b)
27        if d > max_dist:
28            idx, max_dist = i, d
29
30    if max_dist > eps:
31        left = douglas_peucker(points[:idx + 1], eps)
32        right = douglas_peucker(points[idx:], eps)
33        return left[:-1] + right
34    return [a, b]

This algorithm usually provides strong visual results at moderate computational cost.

Visvalingam-Whyatt for smooth progressive reduction

Visvalingam-Whyatt removes points with smallest effective area first. It can produce smoother reductions when you need progressive simplification levels.

It is often used in GIS workflows where cartographic smoothness matters as much as maximum distance error.

Radial-distance preprocessing for streaming workloads

For high-frequency data streams, run a quick radial-distance filter before expensive algorithms. This removes obviously redundant points and reduces downstream compute.

python
1from math import hypot
2
3
4def radial_simplify(points, min_dist):
5    if not points:
6        return []
7    out = [points[0]]
8    for p in points[1:]:
9        if hypot(p[0] - out[-1][0], p[1] - out[-1][1]) >= min_dist:
10            out.append(p)
11    if out[-1] != points[-1]:
12        out.append(points[-1])
13    return out

Combining radial filtering with Douglas-Peucker is a common production pattern.

Measure error after simplification

Never evaluate simplification only by point count reduction. Measure geometric error against baseline polyline and validate against application thresholds.

Track metrics such as maximum deviation, mean deviation, and retained point ratio. A smaller file that violates downstream tolerance is not a valid optimization.

Tune per use case, not globally

One tolerance value rarely fits all datasets. Urban GPS traces, mountain contours, and handwriting strokes have very different curvature characteristics.

A practical approach is to define profile-based settings and select tolerance by data source. Keep these settings versioned and test with representative samples.

Keep topology and endpoint constraints in mind

Some workflows require preserving important vertices such as segment boundaries, junction points, or route endpoints. Pure geometric simplification can remove these unless constraints are applied. Add a protected-point list or post-process to reinsert required anchors.

Constraint-aware simplification is especially important for routing, cadastral boundaries, and engineering drawings.

Common Pitfalls

  • Choosing tolerance values without mapping them to domain units.
  • Evaluating success only by compression ratio and ignoring geometric error.
  • Applying one global tolerance across very different data types.
  • Running expensive simplification directly on noisy raw streams.
  • Forgetting to preserve end points when algorithm or preprocessing changes.

Summary

  • Start with explicit fidelity goals and unit-aware tolerance values.
  • Use Douglas-Peucker when shape preservation is the primary goal.
  • Add radial prefiltering for high-volume streaming data.
  • Validate simplification quality with geometric error metrics.
  • Tune algorithm settings per dataset profile, then version those settings.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.