Twinkling Stars  •  Hue Drift  •  App Comparison  •  09/30/2026
TNT — Processing Cross Training  •  Henry’s Ghost Saga

👻 ✨ 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.

New Ideas

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 Float Accumulator Pattern

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.

JS/Java: globalHue = (globalHue + HUE_SPEED) % 360 Python: global_hue = (global_hue + HUE_SPEED) % 360

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.

identical pattern in all three
🔁
Compute Once — Before the Loop

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; ... } // read

This is a general rule: any value that should be the same for all iterations must be computed outside the loop.

identical structure in all three
📦
Classes in All Three Languages — Same Concept, Different Syntax

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:

Java: class Star { float x, y, sw, h, s, b; int offset; } JS: class Star { constructor(x, y, sw, h, s, b, offset) {...} } Python: class Star: def __init__(self, x, y, sw, h, s, b, offset): ...

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.

Star + Sinusoid classes in all three
🎨
Saturation Floor & Independent Animations

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.

JS: s: random(20, 100) Java: random(20, 100) // saturation arg Python: 's': random(20, 100)

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.

identical in all three

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.

JavaScript twinklingStarsWithHueSketch.js
    Java TwinkeAndChangeHueJavaSketch.pde
      Python twinklingStarsWithHue.py

        Spotlight: The Three Differences Across Languages

        • JS / Java / Python: twinkling uses myWave.f(frameCount + star.offset) / my_wave.f(frameCount + star.offset) via the Sinusoid class in all three
        • JS: class Star { constructor(...) }  |  Java: class Star { float x; ... Star(...) {} }  |  Python: class Star: def __init__(self, ...)
        • Java only: settings() lets you use size(CW, CH) with constants; setup() would require literals
        • Python: global global_hue required in draw() 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 used star['h'] = star_hue (dict)

        Read the Chat Log for the full story: the broken Java attempt, the three bugs, and the class design discussion.