Skip to content

Barycentric coordinates

Jean-Milost Reymond edited this page Nov 21, 2025 · 5 revisions

Description

Barycentric coordinates are a way to express any point inside or outside a triangle as a weighted combination of the triangle three vertices.

barycentric_coords

For a triangle with vertices A, B, and C, any point P can be expressed as:

P = W0 · A + W1 · B + W2 · C

Where:

  • W0, W1, W2 are the barycentric coordinates (weights)
  • W0 + W1 + W2 = 1 (the weights always sum to 1)

The resulting weights will also be useful for several future operations like texture wrapping.

Usage for the rendering

During the rendering, each pixels of the portion where the triangle is located on the canvas need to be iterated. To determine the portion, the triangle bounding box calculated in the previous step.

// calculate bounding box
const Geometry::Rect bbox = triangle.GetBoundingRect();

// clamp to screen bounds
const std::size_t x0 = (std::size_t)std::max(0.0f,              std::floorf(bbox.m_Min.m_X));
const std::size_t x1 = (std::size_t)std::min((float)(m_Width),  std::floorf(bbox.m_Max.m_X));
const std::size_t y0 = (std::size_t)std::max(0.0f,              std::floorf(bbox.m_Min.m_Y));
const std::size_t y1 = (std::size_t)std::min((float)(m_Height), std::floorf(bbox.m_Max.m_Y));

// rasterize triangle
for (std::size_t y = y0; y <= y1; ++y)
    for (std::size_t x = x0; x <= x1; ++x)
    {
        const Math::Vector2F         pixelSample(x + 0.5f, y + 0.5f);
        Geometry::Triangle::IWeights weights;

        if (triangle.BarycentricInside(pixelSample, weights))
        {
            ...
        }

For each iterated pixel, the barycentric coordinates are calculated:

float CalculateSignedArea(const Math::Vector2F& v1,
                          const Math::Vector2F& v2,
                          const Math::Vector2F& v3)
{
    return (v2.m_X - v1.m_X) * (v3.m_Y - v1.m_Y) - (v2.m_Y - v1.m_Y) * (v3.m_X - v1.m_X);
}

bool BarycentricInside(const Math::Vector2F& point, IWeights& weights) const
{
    // whole triangle area
    const float areaABC = CalculateSignedArea(m_Vertex[0], m_Vertex[1], m_Vertex[2]);

    // sub-triangles areas
    const float areaPBC = CalculateSignedArea(point,       m_Vertex[1], m_Vertex[2]);
    const float areaAPC = CalculateSignedArea(m_Vertex[0], point,       m_Vertex[2]);
    const float areaABP = CalculateSignedArea(m_Vertex[0], m_Vertex[1], point);

    // barycentric coordinates
    weights.m_W0 = areaPBC / areaABC;
    weights.m_W1 = areaAPC / areaABC;
    weights.m_W2 = areaABP / areaABC;

    return (weights.m_W0 >= 0 && weights.m_W1 >= 0 && weights.m_W2 >= 0);
}

The BarycentricInside() function will return true if the point is located inside the triangle. If it is located outside, it will be discarded.

demo

There is an available demo which shows explicitly how the barycentric coordinates are calculated inside a triangle.

BarycentricCoords

Return to Home

Clone this wiki locally