What if Bézier surfaces define colormaps within the RGB cube?
We get a lot of benefits. First, minimal data storage, because we only save the coordinates of the control points. Second, everything is uniformly parametrized, so the rate of change within the colormap is perceptually uniform. Third, interpolation at arbitrary resolution allows colormaps to be discretely segmented or infinitely smooth. Fourth, this is a robust method to create bivariate colormaps, from four-point bilinear patches to a highly complex surface or mosaic of surfaces. Fifth, 1D splines (t parameter) are a special case of Bézier surfaces (u and v parameters), so this method generalizes for all 3D splines out-of-the-box. Finally, existing manually-crafted colormaps can be approximated with this method, and then edited to increase smoothness and perceptual uniformity.
Let's look at this example of a Bézier bilinear patch approximating and interpolating an example bivariate chloropleth colormap (source: https://cartographicperspectives.org/index.php/journal/article/view/1538/1819). We can approximate a zero-torsion bilinear patch for this bivaraiate colormap by having the four control points be [[0, 0.5, 1], [0, 0, 0]], [[1, 1, 1], [1, 0.5, 0]]
.
The bivariate colormap above is a low-torsion bilinear patch in RGB space. Below are the six possible bilinear patches that have maximum torsion (and therefore the most comprehensive color ranges within RGB space).
patch_1A = np.array(
[
[[0, 0, 0], [1, 0, 1]],
[[0, 1, 1], [1, 1, 0]],
]
)
patch_1B = np.array(
[
[[1, 1, 1], [0, 1, 0]],
[[1, 0, 0], [0, 0, 1]],
]
)
surface_control_points = np.array(
[
[[0, 1, 1], [0, 0, 0]],
[[1, 0, 1], [1, 1, 0]],
]
)
surface_control_points = np.array(
[
[[0, 1, 0], [1, 0, 0]],
[[0, 0, 1], [1, 1, 1]],
]
)
surface_control_points = np.array(
[
[[0, 0, 0], [1, 0, 1]],
[[1, 1, 0], [0, 1, 1]],
]
)
surface_control_points = np.array(
[
[[1, 0, 0], [0, 0, 1]],
[[0, 1, 0], [1, 1, 1]],
]
)
Approximating Google's turbo
colormap with a handful of control points
Celebrity colormaps (parula
, viridis
, turbo
) within the RGB cube
Event Horizon Telescope used the afmhot
colormap to visualize the M87 black hole
Other surfaces
Sampling the spline surface into a flat matrix to generate an image.
Unit Circle (Trigonometric) Unit Circle (Parametric)
3D Spiral (plt.scatter) 3D Spiral (plt.plot)
Bezier Spline Bezier Surface
Barycentric Coordinates
Bezier Subdivision Quadratic corner cutting (Chaikin) Cubic corner cutting 4-point scheme
Spline parametrization, curvature, normal, tangent
OBJ meshes