geometry
mathematics
coordinate-geometry
point-on-line
linear-algebra

How to check if a point lies on a line between 2 other points

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

To check whether a point lies on the line segment between two other points, you need to answer two separate questions. First, is the point collinear with the segment endpoints? Second, if it is collinear, does it fall within the segment bounds rather than somewhere farther along the infinite line?

The Robust Two-Step Test

The safest approach in two dimensions is:

  1. use a cross product check for collinearity
  2. use a dot product or bounding-box check for “between-ness”

This is usually better than comparing slopes because slope formulas become awkward for vertical lines and floating-point rounding.

Suppose the endpoints are A, B, and the candidate point is P.

Collinearity can be tested with the 2D cross-product expression:

text
(P - A) x (B - A)

If that value is zero, the points are collinear.

Then you can check whether P lies between A and B using either:

  • coordinate bounds
  • or a dot product test

A Practical Python Implementation

Here is a simple Python function using cross product plus bounding-box checks:

python
1def on_segment(ax, ay, bx, by, px, py):
2    cross = (px - ax) * (by - ay) - (py - ay) * (bx - ax)
3    if cross != 0:
4        return False
5
6    within_x = min(ax, bx) <= px <= max(ax, bx)
7    within_y = min(ay, by) <= py <= max(ay, by)
8    return within_x and within_y
9
10
11print(on_segment(0, 0, 4, 4, 2, 2))
12print(on_segment(0, 0, 4, 4, 5, 5))
13print(on_segment(0, 0, 4, 4, 2, 3))

This returns:

  • 'True for (2, 2) because it lies on the segment'
  • 'False for (5, 5) because it lies on the same line but outside the segment'
  • 'False for (2, 3) because it is not collinear'

That distinction between line and segment is essential.

Why Slope Comparison Is Weaker

A common first idea is to compare slopes:

  • slope from A to P
  • slope from A to B

If they match, the points are collinear.

This can work in simple cases, but it has drawbacks:

  • division by zero for vertical lines
  • more floating-point sensitivity
  • more awkward special-case handling

The cross-product form avoids those issues and is the standard computational-geometry approach for many segment tests.

Dot Product Alternative

Instead of bounding-box checks, you can also use the dot product to test whether P falls between A and B.

If the point is already known to be collinear, then P is on the segment when the dot product indicates it is not before A or beyond B.

python
1def on_segment_dot(ax, ay, bx, by, px, py):
2    cross = (px - ax) * (by - ay) - (py - ay) * (bx - ax)
3    if cross != 0:
4        return False
5
6    dot = (px - ax) * (bx - ax) + (py - ay) * (by - ay)
7    if dot < 0:
8        return False
9
10    squared_length = (bx - ax) ** 2 + (by - ay) ** 2
11    if dot > squared_length:
12        return False
13
14    return True

This version is especially useful when you want a vector-based reasoning style instead of separate x and y bounds.

Floating-Point Coordinates

If your coordinates are floating-point values instead of exact integers, testing with cross != 0 can be too strict. Small rounding errors may make a point that should be on the line look slightly off.

In that case, use a tolerance:

python
1def on_segment_float(ax, ay, bx, by, px, py, eps=1e-9):
2    cross = (px - ax) * (by - ay) - (py - ay) * (bx - ax)
3    if abs(cross) > eps:
4        return False
5
6    within_x = min(ax, bx) - eps <= px <= max(ax, bx) + eps
7    within_y = min(ay, by) - eps <= py <= max(ay, by) + eps
8    return within_x and within_y

This is often the right version for graphics, simulation, or geometry derived from measurements rather than exact integer grids.

Endpoint Inclusion

Most segment tests include the endpoints. That means if P equals A or B, the answer is usually true.

The implementations above already behave that way because the boundary checks are inclusive.

If your use case needs “strictly between” instead of “on the closed segment,” change the checks to exclude equality.

Common Pitfalls

The most common pitfall is checking only collinearity and forgetting to check whether the point lies within the segment bounds. That answers “on the infinite line,” not “between the two points.”

Another mistake is using slope comparison and then running into divide-by-zero or floating-point issues.

A third issue is testing floating-point coordinates with exact equality when the data naturally contains tiny rounding errors.

Finally, developers sometimes forget to decide whether endpoints should count as being on the segment. That rule should be explicit.

Summary

  • To test whether a point lies on a segment, check both collinearity and segment bounds.
  • A cross-product check is usually better than slope comparison.
  • Bounding-box or dot-product tests can determine whether the point is actually between the endpoints.
  • Use a tolerance for floating-point coordinates.
  • Decide explicitly whether endpoints should be treated as valid segment points.

Course illustration
Course illustration

All Rights Reserved.