# Using LineSegment Class for Point-to-Segment Distance Calculations in pybind11-rdp

> Calculate point-to-segment distance with the C++ LineSegment class in pybind11-rdp. Get optimized Euclidean and squared distances for 3D points effortlessly.

- Repository: [cubao/pybind11-rdp](https://github.com/cubao/pybind11-rdp)
- Tags: how-to-guide
- Published: 2026-02-28

---

**The `LineSegment` class in cubao/pybind11-rdp provides optimized `distance()` and `distance2()` methods to calculate Euclidean and squared distances from any 3D point to a line segment, using vector projection algorithms implemented in C++ and exposed via pybind11.**

The `LineSegment` class is a lightweight C++ utility wrapped for Python that encapsulates a 3-D line segment between two endpoints. When you need to perform point-to-segment distance calculations efficiently, this class eliminates redundant mathematical operations by pre-computing vector components and providing both exact distance and squared distance methods for maximum performance flexibility.

## Understanding the LineSegment Implementation

### Data Structure and Pre-computed Values

In [`src/main.cpp`](https://github.com/cubao/pybind11-rdp/blob/main/src/main.cpp), the `LineSegment` struct stores the two endpoints `A` and `B` along with pre-calculated values that optimize repeated distance queries. The implementation stores the vector `AB = B - A`, its squared length `len2`, and the reciprocal `inv_len2`. 

Storing these values during construction eliminates redundant calculations when testing multiple points against the same segment. This design pattern is particularly efficient when integrating with algorithms like Ramer-Douglas-Peucker that recursively test many points against the same line segments.

### Distance Algorithm and Projection Logic

The `distance2()` method implements the classic vector projection test to determine point-to-segment distance. According to the source code in [`src/main.cpp`](https://github.com/cubao/pybind11-rdp/blob/main/src/main.cpp) lines 28-38, the algorithm first computes the dot product `dot = (P - A) · AB`.

If `dot <= 0` or `dot >= len2`, the point projects before endpoint `A` or after endpoint `B`, respectively. In these cases, the squared distance is simply the Euclidean distance to the nearest endpoint. Otherwise, the closest point lies on the segment interior, and the method returns the squared perpendicular distance calculated using the pre-computed `inv_len2` value.

The `distance()` method defined at lines 40-44 wraps `distance2()` with `std::sqrt()` to return the actual Euclidean distance, providing convenience when the exact metric is required.

## Using LineSegment for Point-to-Segment Distance Calculations

### Basic Distance Queries in Python

The `LineSegment` class is exposed to Python via pybind11 bindings located around line 98 in [`src/main.cpp`](https://github.com/cubao/pybind11-rdp/blob/main/src/main.cpp). You can instantiate the class with two 3-element vectors representing the segment endpoints, then call `distance()` to compute point-to-segment distances.

```python
from pybind11_rdp import LineSegment

# Create a segment from (0,0,0) to (10,0,0)

seg = LineSegment([0, 0, 0], [10, 0, 0])

# Distance from a point directly above the middle of the segment

print(seg.distance([5.0, 4.0, 0.0]))   # → 4.0

# Distance from a point left of the segment, outside the end point

print(seg.distance([-4.0, 3.0, 0.0]))  # → 5.0

```

These examples correspond to the test cases found in [`tests/test_basic.py`](https://github.com/cubao/pybind11-rdp/blob/main/tests/test_basic.py) lines 11-19, which validate the mathematical correctness of the distance calculations.

### Working with Squared Distances for Performance

When performing batch operations or comparisons where you only need relative distances, use `distance2()` to avoid the computational cost of square root operations. This method returns the squared Euclidean distance, which preserves ordering since the square root function is monotonically increasing.

```python

# Compare distances without sqrt overhead

dist_sq = seg.distance2([5.0, 3.0, 0.0])
print(f"Squared distance: {dist_sq}")

```

The implementation in [`src/main.cpp`](https://github.com/cubao/pybind11-rdp/blob/main/src/main.cpp) lines 28-38 handles all edge cases including zero-length segments, ensuring numerical stability across the full input domain.

### Handling Degenerate Segments

When the two endpoints are identical, the `LineSegment` represents a single point. The distance calculation correctly degenerates to point-to-point distance, as verified by the test suite:

```python

# Degenerate segment (both ends equal) – behaves like distance to a single point

deg = LineSegment([0, 0, 0], [0, 0, 0])
print(deg.distance([3.0, 4.0, 0.0]))   # → 5.0

```

## Integration with RDP Algorithm Workflows

The `LineSegment` class serves as the geometric foundation for the Ramer-Douglas-Peucker (RDP) polyline simplification algorithm implemented in this repository. The `douglas_simplify` routine internally constructs `LineSegment` instances between the first and last points of sub-arrays, then calls `distance2()` for every intermediate point to determine which points to retain.

You can leverage this same pattern for custom geometric processing:

```python
import numpy as np
from pybind11_rdp import rdp, LineSegment

pts = np.array([[0, 0, 0],
                [5, 2, 0],
                [10, 0, 0]])

# Simplify with a large epsilon

simplified = rdp(pts, epsilon=5.0)

# Manually examine the segment that RDP uses for the first recursion

seg = LineSegment(pts[0], pts[-1])
for p in pts[1:-1]:
    print('dist² to segment:', seg.distance2(p))

```

## Summary

- The **`LineSegment`** class in `cubao/pybind11-rdp` provides optimized C++ implementations of point-to-segment distance calculations exposed via pybind11.
- **`distance2()`** returns squared distances using vector projection logic with pre-computed segment parameters, avoiding square root overhead for performance-critical applications.
- **`distance()`** wraps the squared distance calculation with `std::sqrt()` to return actual Euclidean distances, suitable for final output or threshold comparisons.
- The class handles degenerate cases (zero-length segments) correctly and serves as the geometric primitive for the RDP polyline simplification algorithm.
- Implementation resides in [`src/main.cpp`](https://github.com/cubao/pybind11-rdp/blob/main/src/main.cpp) with Python bindings around line 98, while [`tests/test_basic.py`](https://github.com/cubao/pybind11-rdp/blob/main/tests/test_basic.py) provides validation examples.

## Frequently Asked Questions

### How does LineSegment handle points that project outside the segment endpoints?

When the vector projection of a point onto the line falls outside the segment bounds, the `distance2()` method returns the squared Euclidean distance to the nearest endpoint. Specifically, if the dot product `(P-A)·AB` is less than or equal to zero, the distance is to point `A`; if greater than or equal to `len2`, the distance is to point `B`. This ensures geometric correctness for finite line segments rather than infinite lines.

### What is the performance benefit of using distance2() over distance()?

The `distance2()` method avoids the computationally expensive `std::sqrt()` operation required by `distance()`, providing approximately 10-20% performance improvement in tight loops. Since square root is a monotonic function, comparing squared distances preserves the same ordering as actual distances, making `distance2()` ideal for threshold checks, nearest-neighbor searches, and the internal RDP algorithm that only needs relative distance comparisons.

### Can LineSegment be used with 2D coordinates or only 3D?

While the `LineSegment` class stores points as 3D vectors, you can use it for 2D calculations by setting the third coordinate (z-axis) to zero for all inputs. The distance calculations operate correctly in the XY plane when z=0, effectively performing 2D point-to-segment distance calculations. The underlying C++ implementation does not distinguish between 2D and 3D usage; it simply computes Euclidean distances in the full vector space.

### Where can I find the source code implementation for the distance calculations?

The core distance logic resides in [`src/main.cpp`](https://github.com/cubao/pybind11-rdp/blob/main/src/main.cpp) within the `cubao/pybind11-rdp` repository. The `distance2()` implementation appears at lines 28-38, handling the vector projection and endpoint distance logic. The `distance()` wrapper that adds the square root operation appears at lines 40-44. The pybind11 Python bindings exposing these methods are located around lines 98-103 in the same file.