light vs inkNetLogo colorswebcam STI hublaser lab
Summer Teacher Institute · color theory

The Colors of Melrose

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.

1 · RGB — light adds

Three spotlights on a dark stage

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.

This is exactly the pixel from the laser lab. A pixel is 3 numbers — R, G, B — each 0 to 255, which is 256 values, because 0 is a value too. 256 × 256 × 256 ≈ 16.7 million colors, and every one of them is somewhere in those three sliders. Go find the dot: the laser lab ▸

2 · CMYK — ink subtracts

Four inks on white paper

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:

what the formula promises
what the paper gives you

3 · The bridge

One color, both systems, live

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.

Be honest with your students here. The conversion I am doing is the naive one: C = 1 − R/255, then pull the common part out into K. It is arithmetic, not color science. Real printing uses ICC color profiles that measure this ink on that paper under that light — and even then, the same file genuinely looks different on a screen than it does off a press. That gap is not a bug in the page. That gap is the lesson.

4 · The Melrose palette

Click a color. Watch what it costs in light, and in ink.

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.

5 · Two Melrose beats

William Hanna was born in Melrose in 1910

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:

Full 16.7 million.

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.

The Melrose Art Center

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.

7 · import-pcolors vs import-pcolors-rgb

Two primitives. One image. Point it at the room.

NetLogo 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:

quantized

import-pcolors
each patch's pcolor becomes the nearest NetLogo color number. The image is squeezed into ~1,400 colors.

true color

import-pcolors-rgb
each patch's pcolor becomes an RGB list [r g b]. Nothing is thrown away.

The camera is off. Nothing is requested until you press the button.

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.

import-pcolors nearest of 1,400 NetLogo colors · pcolor is a number
import-pcolors-rgb 16.7 million colors · pcolor is a list [r g b]
distinct NetLogo colors in this frame
patches in the world
mean RGB shift per patch
frames per second

What the frame collapsed to

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.

Say this part out loud to your class, because I am saying it to you. This is not NetLogo running. It is a faithful JavaScript re-implementation of NetLogo's color model, ported straight from 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.

And one more, because your sharper students will ask why it is fast. The 1,400 colors are packed tighter than people expect — 4.4 RGB units apart on average, and the closest pair is 1 unit apart. So I look each patch up in a table keyed on the pixel rounded to 7 bits per channel. That is measurably good, not perfect: 12 of the 1,400 colors resolve to their own next-door shade, at most 3 RGB units off. You will never see it. You should still know it is there.

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.