Barycentric Coordinates

affine geometry
observablejs
triangles
interactive
visualization
Author

Apurva Nakade

Published

May 11, 2025

Barycentric coordinates are a coordinate system for describing points inside a triangle.

For a triangle with vertices \(A\), \(B\), and \(C\), any point \(P\) inside the triangle can be expressed as a weighted sum of the vertices: \[ P = iA + jB + kC \] where \(i\), \(j\), and \(k\) are the barycentric coordinates, satisfying \(i + j + k = 1\) and \(i, j, k \geq 0\). The barycentric coordinates can be interpreted as the relative areas of the sub-triangles formed with the point \(P\) and the vertices of the triangle.

There are many ways to see why this representation is valid. Here’s one visual interpretation: first, consider the triangle with vertices \((0, 0)\), \((1, 0)\), and \((0, 1)\). A point \((x, y)\) lies inside this triangle exactly when: \[ 0 \le x, \quad 0 \le y, \quad \text{and} \quad x + y \le 1 \] In this case, we can write the point \((x, y)\) as: \[ \begin{bmatrix} x \\ y \end{bmatrix} = (1 - x - y) \begin{bmatrix} 0 \\ 0 \end{bmatrix} + x \begin{bmatrix} 1 \\ 0 \end{bmatrix} + y \begin{bmatrix} 0 \\ 1 \end{bmatrix} \] So the barycentric coordinates of \((x, y)\) are \((1 - x - y, x, y)\), all of which are non-negative and sum to 1.

Now all you need to do is map \((0, 0)\), \((1, 0)\), and \((0, 1)\) to the vertices \(A\), \(B\), and \(C\), respectively, via an affine transformation. The barycentric coordinates of a point \(P\) inside the triangle with vertices \(A\), \(B\), and \(C\) are given by the same formula as above, with the standard triangle’s vertices replaced by \(A\), \(B\), and \(C\).

In the app above, you can see this in action: move the blue point around the triangle and watch how the barycentric coordinates change. You can also move the vertices of the red triangle and observe how the coordinates adapt.


This post was an excuse for me to learn how to use ObservableJS. I was initially planning to use Python and Plotly, but Plotly is absurdly immature in terms of interactivity. Most of the code was generated by ChatGPT—I merely edited it to fit my needs.

Back to top