Line Clipping
2D Geometry
Computational Geometry
Clipping Algorithms
Polygon Clipping

Line clipping to arbitary 2D polygon

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 to Line Clipping

Line clipping is a fundamental operation in computer graphics, where the objective is to determine which portions of a line segment are inside or outside a given polygon. While clipping lines to rectangles, like in the Cohen-Sutherland and Liang-Barsky algorithms, is straightforward due to their symmetry and simple shape, clipping to arbitrary polygons requires more sophisticated techniques due to the complexity of the polygons' edges and vertices.

The Problem Statement

In general, line clipping against an arbitrary polygon involves:

  1. Determining the intersection points of the line segment with the polygon edges.
  2. Identifying the portion of the line segment that lies inside the polygon.
  3. Returning the clipped line segment, if it exists.

Key Concepts

Convex vs. Concave Polygons

  • Convex Polygon: A polygon is convex if a line segment joining any two points within the polygon lies entirely inside it. Algorithms for clipping lines against convex polygons are generally simpler and faster because such polygons have monotonic boundaries.
  • Concave Polygon: This is a polygon that has at least one internal angle greater than 180 degrees. Clipping becomes more complex as lines can intersect the edges multiple times.

Clipping Algorithms

Cyrus-Beck Algorithm

The Cyrus-Beck algorithm is a parametric line-clipping algorithm suitable for convex polygons. It calculates the intersections of a line segment's parametric form with the polygon's edges, leveraging the dot product to determine the entering and leaving points.

  1. Parametric Line Representation: The line is represented as P(t)=P1+t(P2P1)P(t) = P_1 + t(P_2 - P_1), where tt is a parameter ranging from 0 to 1, P1P_1 and P2P_2 are the endpoints of the line segment.
  2. Normal Vectors and Dot Products: Compute the normal vector to each edge and use the dot product to classify intersections as "potentially entering" or "potentially leaving."
  3. Calculate t Values: For each intersection with a polygon edge, compute the parameter tt. Given an edge with a point FF and outward normal n^\hat{n}, the intersection parameter is:

t=n^(P1F)n^(P2P1)t = \frac{-\hat{n} \cdot (P_1 - F)}{\hat{n} \cdot (P_2 - P_1)}

  1. Determine Clipped Line: Collect all entering tt values (where the dot product is negative) and leaving tt values (where the dot product is positive). The clipped segment runs from tenter=max(0,max(tentering))t_{enter} = \max(0, \max(t_{entering})) to tleave=min(1,min(tleaving))t_{leave} = \min(1, \min(t_{leaving})). If tenter>tleavet_{enter} > t_{leave}, the line is entirely outside.

Sutherland-Hodgman Algorithm

Though originally designed for polygon clipping, the Sutherland-Hodgman algorithm can be extended for line clipping to arbitrary polygons, particularly concave ones. This algorithm works by systematically processing each line against each edge of the polygon:

  1. Processing Vertices: For each edge of the polygon, classify each vertex of the line as either inside or outside.
  2. Processing Intersections: Calculate the intersection points for segments crossing the polygon edges.
  3. Output the Clipped Line: By iterating through all edges, extract the line segments that remain inside the polygon.

Intersection Calculation

For both algorithms, efficiently calculating the line-polygon edge intersection is crucial. Given a line segment from AA to BB and a polygon edge from CC to DD, the intersection can be found by solving the system:

A+t(BA)=C+u(DC)A + t(B - A) = C + u(D - C)

where 0t10 \le t \le 1 and 0u10 \le u \le 1 for a valid intersection within both segments. This system yields:

t=(CA)×(DC)(BA)×(DC)t = \frac{(C - A) \times (D - C)}{(B - A) \times (D - C)}

Here ×\times denotes the 2D cross product (scalar result).

Handling Special Cases

  • Collinear Segment: When a line segment is collinear with an edge of the polygon, numerical precision issues can cause complications. Use an epsilon tolerance for floating-point comparisons.
  • Degenerate Cases: Handle zero-length line segments and singular polygon shapes carefully to avoid computational errors.

Comparison of Algorithms

AlgorithmComplexitySuitable forProsCons
Cyrus-BeckO(n)O(n)Convex polygonsFast and precise for convex shapesNot applicable for concave polygons
Sutherland-Hodgman ExtensionO(nm)O(nm)Concave and convex polygonsHandles both convex and concave polygonsPotentially slower for polygons with many vertices

nn represents the number of polygon edges. mm is the number of line-edge intersections.

Implementation Example

Below is a Python implementation of the Cyrus-Beck algorithm for clipping a line segment against a convex polygon:

python
1def cyrus_beck_clip(p1, p2, polygon):
2    """Clip line segment (p1, p2) against a convex polygon."""
3    d = (p2[0] - p1[0], p2[1] - p1[1])
4    t_enter = 0.0
5    t_leave = 1.0
6
7    n = len(polygon)
8    for i in range(n):
9        # Edge from polygon[i] to polygon[(i+1) % n]
10        edge = (polygon[(i+1) % n][0] - polygon[i][0],
11                polygon[(i+1) % n][1] - polygon[i][1])
12        # Outward normal (rotate edge 90 degrees clockwise)
13        normal = (edge[1], -edge[0])
14
15        w = (p1[0] - polygon[i][0], p1[1] - polygon[i][1])
16        num = -(normal[0] * w[0] + normal[1] * w[1])
17        den = normal[0] * d[0] + normal[1] * d[1]
18
19        if den == 0:
20            if num < 0:
21                return None  # Line is outside this edge
22            continue
23
24        t = num / den
25        if den < 0:
26            t_enter = max(t_enter, t)
27        else:
28            t_leave = min(t_leave, t)
29
30        if t_enter > t_leave:
31            return None
32
33    clipped_p1 = (p1[0] + t_enter * d[0], p1[1] + t_enter * d[1])
34    clipped_p2 = (p1[0] + t_leave * d[0], p1[1] + t_leave * d[1])
35    return clipped_p1, clipped_p2

Summary

Line clipping to arbitrary 2D polygons is a foundational problem in computational geometry. For convex polygons, the Cyrus-Beck algorithm provides an efficient O(n)O(n) solution using parametric intersection tests. For concave polygons, extensions of the Sutherland-Hodgman algorithm handle the additional complexity of multiple intersection regions. The choice of algorithm depends on the polygon type and the performance requirements of the application.


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.