Arrowhead Coordinates
Geometry
Vector Mathematics
Coordinate Calculation
Arrow Design

How to calculate the coordinates of a arrowhead based on the arrow?

Master System Design with Codemia

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

Introduction

To draw an arrowhead, you need more than the start and end points of the arrow shaft. You also need two extra points that form the base corners of the arrowhead. The standard geometric solution uses the arrow direction vector, normalizes it, moves backward from the tip to the arrowhead base, and then offsets perpendicular to the shaft.

The Geometry Behind The Arrowhead

Suppose the arrow starts at (x1, y1) and ends at (x2, y2). The tip of the arrowhead is the end point (x2, y2).

The direction vector is:

dx = x2 - x1

dy = y2 - y1

Its length is:

length = sqrt(dx*dx + dy*dy)

From there, compute a unit direction vector:

ux = dx / length

uy = dy / length

Now you can move backward from the tip by the arrowhead length and sideways by half the arrowhead width.

Compute The Base Center And Side Points

If the arrowhead length is L and the full arrowhead width is W, the center of the arrowhead base is:

base_x = x2 - ux * L

base_y = y2 - uy * L

A vector perpendicular to the arrow direction is:

px = -uy

py = ux

Scale that perpendicular vector by W / 2 to get the two base corners.

The arrowhead points become:

  • tip: (x2, y2)
  • left base corner: (base_x + px * W/2, base_y + py * W/2)
  • right base corner: (base_x - px * W/2, base_y - py * W/2)

A Runnable Python Function

python
1import math
2
3
4def arrowhead_points(x1, y1, x2, y2, head_length=20.0, head_width=12.0):
5    dx = x2 - x1
6    dy = y2 - y1
7    length = math.hypot(dx, dy)
8
9    if length == 0:
10        raise ValueError("Arrow length must be greater than zero")
11
12    ux = dx / length
13    uy = dy / length
14
15    base_x = x2 - ux * head_length
16    base_y = y2 - uy * head_length
17
18    px = -uy
19    py = ux
20    half_width = head_width / 2.0
21
22    left = (base_x + px * half_width, base_y + py * half_width)
23    right = (base_x - px * half_width, base_y - py * half_width)
24    tip = (x2, y2)
25
26    return tip, left, right
27
28
29print(arrowhead_points(0, 0, 10, 0))
30print(arrowhead_points(1, 1, 5, 5))

The first example produces a horizontal arrowhead. The second works for a diagonal arrow because the geometry is based on the normalized direction vector, not on special-case axis logic.

Drawing The Full Arrow

Most drawing systems use the shaft plus the three arrowhead points. For example, if you were building a polygon for a triangular arrowhead, you would render:

  • shaft from (x1, y1) to (x2, y2)
  • triangle connecting tip, left, and right

That is enough for canvas APIs, SVG, game engines, and chart overlays.

Why The Perpendicular Vector Matters

The perpendicular vector gives the arrowhead width. Without it, moving backward from the tip only tells you where the arrowhead base center is, not where its two corners are.

For a 2D vector (ux, uy), one perpendicular direction is (-uy, ux). The opposite direction is (uy, -ux). Using plus and minus around the base center gives you both sides of the arrowhead symmetrically.

Common Pitfalls

The most common mistake is forgetting to normalize the direction vector before using it. If you skip normalization, the arrowhead size will depend on the arrow shaft length, which is usually wrong.

Another issue is not handling the zero-length case. If the start and end points are identical, division by zero is unavoidable unless you guard against it.

It is also easy to mix up full width and half width. The perpendicular offset should usually use head_width / 2.

Finally, watch your coordinate system. In many graphics APIs, the y-axis increases downward, but the vector math still works as long as you stay consistent.

Summary

  • Compute the direction vector from the arrow start and end points.
  • Normalize it so the arrowhead size stays independent of shaft length.
  • Move backward from the tip to find the base center.
  • Use a perpendicular vector to calculate the two base corners.
  • Guard against zero-length arrows before dividing by the vector length.

Course illustration
Course illustration

All Rights Reserved.