geometry
trigonometry
angle calculation
coordinate geometry
mathematics

Angle between points?

Master System Design with Codemia

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

Introduction

The phrase "angle between points" can refer to different calculations, and mixing them is a common source of bugs. Sometimes you need the direction from one point to another, and sometimes you need the angle formed by three points at a vertex. Choosing the right formula and output range is more important than the specific programming language.

Core Sections

1. Identify the exact angle definition

There are three common cases:

  • Direction angle from point A to point B in two dimensions.
  • Angle between two vectors that share an origin.
  • Interior angle at point B in triangle A-B-C.

Each case has a different input and expected range. Direction angles usually use signed ranges with orientation, while interior angles are non-negative and bounded.

2. Direction from one point to another with atan2

For directional heading in two dimensions, use atan2(delta_y, delta_x). This handles all quadrants and avoids division-by-zero issues that appear with plain atan.

python
1import math
2from typing import Tuple
3
4Point = Tuple[float, float]
5
6
7def direction_angle_deg(a: Point, b: Point) -> float:
8    dx = b[0] - a[0]
9    dy = b[1] - a[1]
10    angle = math.degrees(math.atan2(dy, dx))
11    return angle
12
13
14print(direction_angle_deg((0, 0), (1, 1)))
15print(direction_angle_deg((0, 0), (-1, 1)))

If your UI needs compass-style output from zero to three hundred sixty degrees, normalize negative results by adding three hundred sixty.

3. Angle between vectors with dot product

When you need the smallest angle between vectors u and v, use the dot product relation:

cos(theta) = dot(u, v) / (|u| * |v|)

Then compute theta = arccos(cos(theta)). Clamp cosine value to valid numeric range before arccos to protect against floating-point drift.

python
1import math
2from typing import Tuple
3
4Vec = Tuple[float, float]
5
6
7def angle_between_vectors_deg(u: Vec, v: Vec) -> float:
8    dot = u[0] * v[0] + u[1] * v[1]
9    nu = math.hypot(u[0], u[1])
10    nv = math.hypot(v[0], v[1])
11    if nu == 0 or nv == 0:
12        raise ValueError("Zero-length vector")
13    c = dot / (nu * nv)
14    c = max(-1.0, min(1.0, c))
15    return math.degrees(math.acos(c))
16
17
18print(angle_between_vectors_deg((1, 0), (0, 1)))

This gives the smallest non-oriented angle, which is often what geometry and ML applications need.

4. Interior angle at a point in a polyline

For three points A, B, and C, interior angle at B is the angle between vectors BA and BC. Build vectors from the shared vertex and reuse the vector-angle function.

python
1def interior_angle_deg(a: Point, b: Point, c: Point) -> float:
2    ba = (a[0] - b[0], a[1] - b[1])
3    bc = (c[0] - b[0], c[1] - b[1])
4    return angle_between_vectors_deg(ba, bc)
5
6
7print(interior_angle_deg((0, 0), (1, 0), (1, 1)))

This approach is robust and reusable for polygon analysis, path smoothing, and corner detection.

5. Coordinate systems and orientation conventions

Game engines, CAD tools, and mapping systems use different axis orientations. Screen coordinates often have vertical axis increasing downward, which flips intuitive orientation compared with Cartesian math. Convert coordinates into one consistent system before comparing angles across modules.

Also document unit expectations. Mixing radians and degrees in the same pipeline causes silent but severe errors.

6. Validation and tolerance handling

Exact equality checks are unsafe with floating-point trigonometry. Use tolerances in tests and clamp edge values before inverse trig functions.

Good test cases include:

  • orthogonal vectors
  • identical vectors
  • opposite vectors
  • very small vectors near machine precision
  • random vectors compared against reference implementation

These tests catch most geometry regressions quickly.

Common Pitfalls

  • Using atan instead of atan2 and getting wrong quadrants.
  • Forgetting to guard against zero-length vectors in dot-product methods.
  • Mixing radians and degrees across modules.
  • Computing interior angle with wrong vector direction from vertex.
  • Skipping numeric clamping before acos, causing occasional domain errors.

Summary

  • Start by defining which angle concept your feature actually needs.
  • Use atan2 for direction angles and dot product for vector-to-vector angles.
  • Reuse vector-angle logic to compute interior angles at polyline vertices.
  • Standardize coordinate orientation and angle units in the full pipeline.
  • Add tolerance-based tests and numeric clamping for stable production behavior.

Course illustration
Course illustration

All Rights Reserved.