Skip to content

Instantly share code, notes, and snippets.

@facelessuser
Last active August 23, 2026 20:13
Show Gist options
  • Select an option

  • Save facelessuser/03fa7645c98d005fe4bad95a78300bd6 to your computer and use it in GitHub Desktop.

Select an option

Save facelessuser/03fa7645c98d005fe4bad95a78300bd6 to your computer and use it in GitHub Desktop.
DLM
"""
DLM color space.
This is a prototype of the space as described here: https://prototypestudios.neocities.org/dlm
We have not bothered to see exactly how they do their space, but have instead just implemented it as described.
Any errors in implementation are likely our own.
"""
from __future__ import annotations
import math
from coloraide.spaces import Space, Prism, Luminant
from coloraide.channels import Channel
from coloraide.cat import WHITES
from coloraide import util
from coloraide.types import Vector
from coloraide import algebra as alg
from coloraide.spectrum import closest_wavelength, wavelength_to_color
from coloraide.everything import ColorAll as Base
# Fixed primary
FP = util.xyz_to_xyY(wavelength_to_color(650))[:-1]
class DLM(Luminant, Prism, Space):
"""The xyY class."""
BASE = "xyy"
NAME = "dlm"
SERIALIZE = ("--dlm",)
CHANNELS = (
Channel("d", 360, 830),
Channel("l", 0.0, 1.0),
Channel("m", 0.0, 1.0)
)
WHITE = WHITES['2deg']['D65']
def to_base(self, coords: Vector) -> Vector:
"""To XYZ."""
d, l, m = coords
dx, dy = util.xyz_to_xyY(wavelength_to_color(alg.clamp(d, 360, 830)))[:-1]
fx, fy = FP
x = alg.lerp(fx, dx, m)
y = alg.lerp(fy, dy, m)
return [x, y, l]
def from_base(self, coords: Vector) -> Vector:
"""From XYZ."""
x, y, Y = coords
# We don't want the rounded wavelength, so don't get the "closest",
# but get the raw, interpolated value.
w = closest_wavelength([x, y], FP, closest=False)
xf, yf = FP
xd, yd = w[1]
d = w[0]
# On the line of purples, use 440 instead
if d < 0 or math.isnan(d):
d = 440
xd, yd = util.xyz_to_xyY(wavelength_to_color(d))[:-1]
# We could clamp this to a smaller subset, but I don't think it matters.
d = alg.clamp(d, 360, 830)
# Calculate the mix
dx = xd - xf
dy = yd - yf
m = alg.zdiv(x - xf, dx) if dx - dy else alg.zdiv(y - yf, dy)
# If mix exceeds the range, return the dominant wavelength
if m < 0 or m > 1:
d = closest_wavelength([x, y], closest=False)[0]
m = 1
return [d, Y, m]
def lightness_name(self) -> str:
"""Get lightness name."""
return "l"
class Color(Base): ...
Color.register(DLM())
Color.interpolate(['#002185', '#FCD200'], space='dlm')
Color.interpolate(['black', 'white'], space='dlm')
Color.interpolate([Color('dlm', [650, 0.5, 1]), Color('dlm', [520, 0.5, 1])], space='dlm')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment