👻 ✨ Twinkling Stars with Hue:
Three Languages, Three New Ideas
The hue-drift extension of the twinkling stars sketch in JavaScript (p5.js),
Java Processing, and Python Processing. Float accumulator, loop-scope rule,
and class design — Star and Sinusoid classes
in all three languages so the concept is visible side-by-side.
Compare with Twinkling Stars v1 which uses the natural container idioms (dict / object literal / class) — two design styles, one algorithm.
Four Concepts at Work in the Hue-Drift Version
These pages assume you have already read Twinkling Stars v1 and understand named constants, HSB color mode, data structures, mouse input, and sinusoidal twinkling. The four ideas below are the new additions.
The broken first attempt updated hue as 0.01 * frameCount.
Because frameCount grows every frame, the increment grows too —
slow at frame 10, frantic at frame 5000. The fix is a float
accumulator: a variable that gains a fixed amount each frame.
HUE_SPEED = 0.3 means 9°/sec at 30 fps — a full
color wheel cycle every 40 seconds. Change one constant; the speed changes everywhere.
The other bug in the broken version: STAR_HUE was mutated
inside the per-star loop. With 500 stars and an increment per iteration,
every star landed at a different hue in the same frame — a full rainbow.
The fix is simple: advance the accumulator once, before the loop, then read that single value in every iteration:
globalHue = (globalHue + HUE_SPEED) % 360; // once var starHue = floor(globalHue); // snap for (var i ...) { star.h = starHue; ... } // readThis is a general rule: any value that should be the same for all iterations must be computed outside the loop.
This version defines Star and Sinusoid classes in
all three languages, making the OOP pattern directly comparable.
The data model is identical; only the declaration syntax differs:
Sinusoid is the cleaner teaching object for classes: it has
stable data (A, B, C set once in setup())
and reusable behavior (f(x) called every frame —
exactly the pattern a class earns its keep on).
Star teaches containers: seven related fields grouped under one name.
Compare with v1: the original cross-training page used Python dicts, JS object literals, and a Java class — deliberately different to show each language’s natural container idiom. This page shows that all three can use classes; v1 shows what they use by default. Read both for the full picture.
New to sinusoids? Before digging into the class,
visit the
SketchWave Sinusoid Wave Demo ↗
— an interactive control panel where you can slide amplitude,
period, phase shift, and vertical offset and watch the wave respond
in real time. Ten minutes there makes the A, B, C parameters in
Sinusoid immediately recognizable.
Stars with saturation near 0 are almost gray — they cannot show a hue change.
Raising the minimum from 0 to 20 ensures every star
participates in the color drift. A floor of 20 still allows pale stars; it just
rules out colorless ones.
Hue drift and twinkling are independent animations that compose:
hue advances every frame regardless of the toggle;
alpha modulation activates only when twinkling is on.
Each animation has its own variable (globalHue vs.
shouldTwinkle) and its own logic path. They share only the
stroke() call that combines their results.
All Three Sketches, Side by Side
Yellow paper = JavaScript •
Blue paper = Java •
Green paper = Python. Each panel scrolls independently.
All three panels now define Star and Sinusoid classes.
Scroll to the bottom of each panel to see how the class syntax differs.
Spotlight: The Three Differences Across Languages
- JS / Java / Python: twinkling uses
myWave.f(frameCount + star.offset)/my_wave.f(frameCount + star.offset)via theSinusoidclass in all three - JS:
class Star { constructor(...) }| Java:class Star { float x; ... Star(...) {} }| Python:class Star: def __init__(self, ...) - Java only:
settings()lets you usesize(CW, CH)with constants;setup()would require literals - Python:
global global_huerequired indraw()to mutate the accumulator | JS / Java: sketch-level variables are accessible from all functions - JS / Java / Python:
star.h = starHue— all three use dot notation now; v1 Python usedstar['h'] = star_hue(dict)
Read the Chat Log for the full story: the broken Java attempt, the three bugs, and the class design discussion.