Two ways to make a color, and they run in opposite directions. Light adds — pile it on and you get white. Ink subtracts — pile it on and you get mud. Then there is a third way: NetLogo, which threw both out and numbered its colors from 0 to 139.9. All three are live below. The palette is Melrose, New Mexico: Curry County, 4,406 feet, 622 people.
The Mayor of Melrose is in the room. Mayor — the sliders are yours.Drag the sliders and watch the overlaps. Red and green make yellow. Green and blue make cyan. Red and blue make magenta. All three, at full, make white.
More light = brighter = toward white. Nothing is being covered up; every lamp you turn up adds photons that were not there before.
Now the stage is a sheet of paper and the lamps are ink. The paper starts white — it is already reflecting everything — so every drop of ink can only ever take light away.
More ink = darker = toward black. And this is why K exists.
In theory, cyan + magenta + yellow at full strength subtract everything and leave you black. In practice they leave you this — a muddy brown, because real ink is not a perfect filter. It is close, and close is useless: you cannot print the text you are reading in muddy brown. So printers stop pretending and add a fourth ink that is actually black. That is the K. Press the button and watch the two disagree:
The two mixers above are tied together. Move an RGB slider and the CMYK sliders follow; move a CMYK slider and the RGB sliders follow. Same color, two languages — light on the left, ink on the right.
Curry County sits on the High Plains — flat to gently rolling, semi-arid, sparse, farmed and ranched. The thermometer there has been to 112 °F and to −20 °F. About 16 inches of rain a year, most of it arriving in the June-to-September monsoon, and about 11 inches of snow. That is the whole palette. It was sitting outside the entire time.
He went on to co-found Hanna-Barbera — and cel animation is a color theory lesson with a budget attached. A cel palette is tiny, flat and deliberate: every color mixed as real paint, numbered, and laid down by hand, one cel at a time. You did not "pick a color." You picked from the box, because each new color cost money and time. Turn this on and the mixers snap to a 12-paint box:
Snapping picks the nearest paint by straight-line distance in RGB — which is itself a naive measure, for the same reason the CMYK conversion above is. Precision, out loud: Hanna was born in Melrose. The studio came much later, and elsewhere.
Melrose has a New Deal-era federal art center — and it is, per the record, the smallest town to have such a federal art center. A village of about 600 people has a federal art center. Color theory has been taught here before. We are just the ones running late.
In NetLogo a color is one number, not three. The scale runs 0 to 139.9 — fourteen hue families,
ten units wide each, laid end to end. The name you type (red, sky, lime)
is just a constant sitting at the middle of its family, at n × 10 + 5. Go down from
there and the color walks toward black; go up and it walks toward white.
That is why red - 2 and red + 2 both work and both mean something.
Fourteen rows, one per family. Ten columns, one per whole-number shade. The swatch with the outline is the base — the one with the name. Hover any swatch to read it; click it to load that exact color into the light-and-ink mixers back on tab 1, and see what a NetLogo color costs in RGB and in CMYK.
Hover or click a swatch to inspect it.
black is 0 and white is 9.9 — both special cases, both living at the
ends of the gray family. Every other family is a walk from near-black to near-white through one hue.
The chart shows 140 colors. The scale holds 1,400.
The real scale is continuous at 0.1 steps: red is 15, but 15.1,
15.2 … 15.9 are all real, all distinct, and all legal. 140 whole numbers × 10 tenths
= 1,400 distinct colors, and this chart is showing you exactly one in ten of them. That number matters
on the next tab: 1,400 is the entire world import-pcolors gets to work with, against
16.7 million for RGB.
api/Color.scala) are not the values you get back from
map extract-rgb base-colors; those two disagree inside NetLogo itself. If you have ever had a
color look right on a patch but come out "wrong" through extract-rgb, you were not going crazy —
you found a real inconsistency. Teach it as one.Chart ported from NetLogo's own colormodel.coffee
(Tortoise engine) and api/Color.scala. The shade math is theirs, not mine:
step = (colorTimesTen mod 100 − 50) / 50.48 + 0.012, walking toward 0 below the base and toward
255 above it. Note the + 0.012 — it means even a base color like red is nudged a
hair off its own table entry. That is in the source too. Also in the source: turqoise, misspelled.
It is spelled turquoise here.
import-pcolors vs import-pcolors-rgbNetLogo gives you two ways to pull an image onto the patches, and the difference between them is the whole of this page in one line of code:
import-pcolors
each patch's pcolor becomes the nearest NetLogo
color number. The image is squeezed into ~1,400 colors.
import-pcolors-rgb
each patch's pcolor becomes an RGB list
[r g b]. Nothing is thrown away.
That slider is not a resolution slider — it is
resize-world. Drag it left and you are not blurring the picture, you are running a
coarser world. Both panels always use the same patch grid, so the only difference you can see
between them is the color model.
Black means the two agree exactly. Everything that glows is color
that import-pcolors could not afford. Watch the smooth places — a cheek, a wall, the sky out
the window. Gradients are where quantization has nowhere to hide.
The most-used NetLogo colors in the picture right now, by patch count — with the name and number you would actually type in code.
Quantized gives you a number you can reason about. True color gives you a list that looks right. You cannot have both — that is why NetLogo ships both primitives.
After import-pcolors, pcolor is a number, so the whole language still works on it:
ask patches with [pcolor = red] [ ... ], scale-color, pcolor + 2,
diffuse pcolor 0.5 — all fine. After import-pcolors-rgb, pcolor is
[r g b]. It looks better and every one of those tricks stops working: pcolor = red
is comparing a list to a number, and it is simply false. So the real question is never "which is prettier."
It is "does my model need to ask the patch what color it is?" If yes, you pay the 1,400-color tax on
purpose.
colormodel.coffee and api/Color.scala — the 14 base RGBs and the shade math are
verbatim theirs. But my nearest-color match is squared distance in RGB, and NetLogo's real matcher works
through HSB. On a normal frame that agrees nearly everywhere and disagrees on a handful of patches,
which land on a neighbouring shade of the right hue. Close enough to teach with. Not close enough to lie about.
The camera needs https (or localhost) and a click — that is the browser's rule, not mine. Nothing is uploaded anywhere: every pixel here is read, quantized and thrown away inside this tab. Leave the tab and the camera stops.