Skip to content

What if Bézier surfaces define colormaps within the RGB cube?

Notifications You must be signed in to change notification settings

dirediredock/RGB_ColorSpline_Cube

Repository files navigation

RGB_ColorSpline_Cube

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

About

What if Bézier surfaces define colormaps within the RGB cube?

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Languages