# Interpolating vertex colors with trilinear coordinates instead of barycentric

In 3D graphics, vertex attributes like vertex normals, texture coordinates, and vertex colors are interpolated over the surface of triangles using barycentric coordinates. In actual fact it’s more complex than this and there’s a rabbit hole of perspective correct adjustment and all sorts, but indulge me for a moment. Here’s what this looks like for vertex colors, and Mathematica handles everything about the interpolation behind the scenes:

vtxs = {{0, 0}, {0, 1}, {1, 0}}; cols = {Red, Green, Blue}; tri = Polygon[vtxs, VertexColors -> cols]; pt = {1, 1/2}/2; Graphics[{tri,   {Yellow, PointSize[Large], Point[pt], Line[{pt, #}] & /@ vtxs},   MapThread[    Text[Style[#1, FontWeight -> Bold, FontSize -> 24], #2] &,      {{"R", "G", "B"}, vtxs}],   Style[{Text["u", {.3, .1}], Text["v", {.2, .65}],      Text["1-u-v", {.7, .1}],      Text[TraditionalForm[p], pt + {1, 1}*0.04]}, White, FontSize -> 24]   }]

The color at $$p$$ is a weighted combination $$p_c=Rw + Gv + Bu$$ where $$(u,v,w=1-u-v)$$ are the relative areas of the subtriangles such that $$u+v+w=1$$.

I want to find a reasonably efficient way to interpolate the colors for any triangle without using barycentric coordinates, but using trilinear coordinates instead, and see what images this creates.

That is, we drop a perpendicular to the nearest edge and get a point on that edge, possibly indexing into the $$RG,GB,RB$$ gradients along the edges, and then weighting the combination of these colors by the trilinear distances or areas of the three regions – whatever is more appropriate as it’s all experimental. Any other suggestions for how to interpolate vertex colors using trilinears is welcome.

This is my code so far. The next step is to interpolate the corner colors over a pixel grid and make an image, instead of a Graphics with a single point:

SeedRandom[123456789]; poly = RandomPolygon[3]; shell = RegionUnion[MeshPrimitives[poly, 1]]; nfs = RegionNearest /@ MeshPrimitives[poly, 1]; rds = RegionDistance /@ MeshPrimitives[poly, 1]; centroid = Mean[First[poly /. Polygon -> List]]; Manipulate[  Graphics[{FaceForm[None], EdgeForm[Thick], poly, Orange,     Line[{p, #[p]}] & /@ nfs, Point[centroid]}], {{p, centroid},    Locator}]