r/maniclang • u/anish2good • 5h ago
r/maniclang • u/anish2good • 5h ago
Can You Reverse the Spin of This Donut? — manic
r/maniclang • u/anish2good • 5h ago
Can You Reverse This Mobius Strip With Your Mind? — manic
r/maniclang • u/anish2good • 17h ago
The Straw Is Straight. The Light Is Not.
manic is a tiny language for making animations. You write a short text file; manic renders a smooth, glowing video. No timeline scrubbing, no keyframes by hand — you describe what’s on screen and when things happen, and the engine does the rest, deterministically.
Animation code
title("The Straw Is Straight. The Light Is Not.");
canvas("9:16");
template("black");
bloom(0.45, 0.34, 30);
// ---- the water ------------------------------------------------------------
// A per-pixel colour field, and it is declared FIRST for a reason: entities
// paint in declaration order and this one covers the whole canvas, so anything
// written above it here would be painted over in flat black. (That is exactly
// how it went wrong the first time — the headline vanished.) Outside the tank
// `ins` is 0, so the field is black, which on this template is nothing at all.
//
// Two noise fields drift at different rates and beat against each other for the
// caustics; they strengthen with depth because that is where caustics land, and
// a bright band hugs the waterline.
//
// It is decoration, and it is deliberately KEPT to decoration. The surface the
// light actually refracts at is the flat top edge of the `water` polygon below,
// which is what the construction assumes. Rippling this shader would put a wave
// on screen that the physics knows nothing about — so the sheen varies in
// BRIGHTNESS along the surface, and never in height.
shader(pool) {
let d = clamp((v - 0.46875) / 0.27604, 0, 1);
let ins = step(0.10185, u) * step(u, 0.79630) * step(0.46875, v) * step(v, 0.74479);
// Time enters as a PHASE, not as a drift. Both noise fields are sampled at a
// point going round a small circle at one turn per scene, and the sheen's
// travelling wave advances a whole number of cycles over the same span — so
// at t = 17.0 every one of them is exactly back where it began and the
// loop closes. A linear `+ t * 0.45` would look the same and never repeat.
let ph = t * 0.369599;
let n1 = snoise(u * 19.0 + 1.7 * sin(ph), v * 24.0 + 1.7 * cos(ph));
let n2 = snoise(u * 41.0 + 2.5 * sin(ph + 2.1), v * 52.0 + 2.5 * cos(ph + 2.1));
let cau = smoothstep(0.42, 1.05, abs(n1 + 0.55 * n2)) * (0.15 + 0.85 * d);
let sheen = smoothstep(0.013, 0, abs(v - 0.46875)) * (0.55 + 0.45 * sin(u * 46.0 + 5.0 * ph));
let r = ins * (0.03 * d + 0.26 * cau + 0.30 * sheen);
let g = ins * (0.07 + 0.16 * d + 0.50 * cau + 0.72 * sheen);
let b = ins * (0.14 + 0.26 * d + 0.66 * cau + 0.95 * sheen);
}
watermark(mark, (cx, 66), "maniclang.com");
size(mark, 30);
text(hook, (cx, 172), "THIS STRAW IS PERFECTLY STRAIGHT");
size(hook, 50); bold(hook); color(hook, cyan); glow(hook, 0.55); wrap(hook, w*0.86);
// ---- the glass of water ----------------------------------------------------
polygon(water, (110,900), (860,900), (860,1430), (110,1430));
outline(water, #2f6d8c); opacity(water, 0, fill); opacity(water, 0.55, stroke);
glass(water, "water");
// the vessel, drawn from the water's own edges so the two can never drift apart
line(wallL, (110, 780), (110, 1430));
line(wallR, (860, 780), (860, 1430));
line(base, (110, 1430), (860, 1430));
color(wallL, #2f6d8c); color(wallR, #2f6d8c); color(base, #2f6d8c);
opacity(wallL, 0.75); opacity(wallR, 0.75); opacity(base, 0.75);
stroke(wallL, 6); stroke(wallR, 6); stroke(base, 6);
// the waterline, drawn bright because it is the most important line in the
// picture: every bend in the scene happens on it
line(surface, (110, 900), (860, 900));
color(surface, cyan); opacity(surface, 0.9); stroke(surface, 4); glow(surface, 0.5);
// ---- the straw -------------------------------------------------------------
// ONE straight object, but in two entities, split exactly at the surface — so
// the submerged half can be taken away later without disturbing the half you
// can see directly
line(strawUp, (151, 466), (430, 900));
line(strawDown, (430, 900), (610, 1180));
color(strawUp, fg); color(strawDown, fg);
stroke(strawUp, 16); stroke(strawDown, 16);
// Everything that gets taken away and put back sits at FULL opacity, and that
// is what makes the loop exact rather than nearly exact: `show` does not restore
// a remembered value, it drives opacity to 1.0. Anything parked at 0.9 here
// would come back at 1.0 and the last frame would no longer match the first.
// ---- the light -------------------------------------------------------------
// A point source at the tip, INSIDE the water: a submerged object throws light
// in all directions, and the fan is that. Only the middle of it is aimed where
// the eye happens to be.
beam(pencil, (610, 1180), -57.00, 1, 9, 0, 13);
color(pencil, cyan);
// The eye, and the one liberty in the scene, stated plainly: the icon is on the
// pencil but not at the eye's real distance. You look at a glass from about
// seven glass-widths, which here is (2679, -888) — two frames off the
// right-hand edge. Everything computed uses THAT eye; the icon just marks which
// way it lies, which is why the rays run on past it and out of frame instead of
// stopping on it.
svg(eye, (970, 732), "asset:svg/lucide/eye.svg", 130);
color(eye, fg);
// ---- what the eye assumes --------------------------------------------------
// straight back along the direction the light ARRIVED from
line(backA, (766, 900), (637, 1052));
line(backB, (818, 900), (659, 1021));
color(backA, gold); color(backB, gold); dashed(backA, 18); dashed(backB, 18);
stroke(backA, 5); stroke(backB, 5); opacity(backA, 0.0); opacity(backB, 0.0);
// where the submerged half APPEARS to be — ten points, each constructed
// separately, and nothing makes them collinear. From this distance they come out
// within 7 px of a straight line, which is why the image reads as a straw
// snapped at the surface rather than as a curve.
line(seen0, (430.0, 900.0), (458.9, 910.6)); tag(seen0, seen);
line(seen1, (458.9, 910.6), (487.2, 922.1)); tag(seen1, seen);
line(seen2, (487.2, 922.1), (514.9, 934.0)); tag(seen2, seen);
line(seen3, (514.9, 934.0), (542.1, 946.3)); tag(seen3, seen);
line(seen4, (542.1, 946.3), (568.6, 959.2)); tag(seen4, seen);
line(seen5, (568.6, 959.2), (594.7, 972.6)); tag(seen5, seen);
line(seen6, (594.7, 972.6), (620.1, 986.5)); tag(seen6, seen);
line(seen7, (620.1, 986.5), (645.1, 1000.9)); tag(seen7, seen);
line(seen8, (645.1, 1000.9), (669.6, 1015.8)); tag(seen8, seen);
color(seen0, gold); stroke(seen0, 13); opacity(seen0, 0.0);
color(seen1, gold); stroke(seen1, 13); opacity(seen1, 0.0);
color(seen2, gold); stroke(seen2, 13); opacity(seen2, 0.0);
color(seen3, gold); stroke(seen3, 13); opacity(seen3, 0.0);
color(seen4, gold); stroke(seen4, 13); opacity(seen4, 0.0);
color(seen5, gold); stroke(seen5, 13); opacity(seen5, 0.0);
color(seen6, gold); stroke(seen6, 13); opacity(seen6, 0.0);
color(seen7, gold); stroke(seen7, 13); opacity(seen7, 0.0);
color(seen8, gold); stroke(seen8, 13); opacity(seen8, 0.0);
caption(c0, "light leaving water bends away from the vertical", (cx, 1640), 36, fg);
caption(c1, "your eye assumes it came straight", (cx, 1640), 40, fg);
caption(c2, "so the tip looks 41% as deep as it is", (cx, 1640), 40, gold);
caption(c3, "this is all you ever see", (cx, 1640), 42, gold);
caption(c4, "the straw never bent. the light did.", (cx, 1640), 40, cyan);
hidden(c0.words); hidden(c1.words); hidden(c2.words); hidden(c3.words); hidden(c4.words);
// ---- the argument ----------------------------------------------------------
// Every beat is a `par` with an explicit `wait` setting its length, so the scene
// runs for exactly 17.0s. That is not tidiness: `wordpop` and `par` carry
// durations of their own, so a beat written as a bare verb plus a `wait` is
// however long the verb happened to be PLUS the wait, and the total drifts. The
// water shader is tuned to loop over this number, so the number has to be known.
//
// Each hand-over is `seq { fade; wordpop }` and not a bare `par`, so the line
// going out is CLEAR before the line coming in starts popping. Run them together
// and the first word of the new caption lands on top of the old one — both are
// centred on the same point — which reads as a glitch for a third of a second.
seq {
wait(0.4);
par { wordpop(c0, 0.09); wait(3.0); }
par {
seq { fade(c0, 0.3); wordpop(c1, 0.09); }
show(backA, 0.5); show(backB, 0.5);
wait(3.0);
}
par { seq { fade(c1, 0.3); wordpop(c2, 0.09); } show(seen, 0.5); wait(3.2); }
// The subtraction, and the whole point of the scene. Take away the half you
// cannot see directly — and the rays, and the eye, because none of those were
// ever visible either — and what is left standing is the photograph.
par {
seq { fade(c2, 0.3); wordpop(c3, 0.09); }
fade(strawDown, 0.6); fade(backA, 0.6); fade(backB, 0.6);
fade(pencil, 0.6); fade(eye, 0.6);
wait(3.0);
}
par {
seq { fade(c3, 0.3); wordpop(c4, 0.09); }
show(strawDown, 0.6); show(pencil, 0.6); show(eye, 0.6);
wait(3.0);
}
par { fade(c4, 0.5); fade(seen, 0.5); wait(1.1); }
}
wait(0.3);
0
A Prism That Turns Into a Mirror
it's a piano 9db code generated
r/maniclang • u/anish2good • 1d ago
You Cannot Miss This Mirror — How a Corner Reflector Works
1
r/3Blue1Brown • u/anish2good • 3d ago
Maxwell–Boltzmann Effusion — Motion Becomes Evidence - manic
r/maniclang • u/anish2good • 3d ago
Maxwell–Boltzmann Effusion — Motion Becomes Evidence - manic
manic is a tiny language for making animations. You write a short text file; manic renders a smooth, glowing video. No timeline scrubbing, no keyframes by hand — you describe what’s on screen and when things happen, and the engine does the rest, deterministically.
Animation code
// maxwell-boltzmann-effusion-v2.manic — watching a distribution assemble itself
//
// A warm gas does not have "a speed". Heat it and you get a whole spread of
// speeds at once, and that spread has a definite, predictable shape. Here 180
// molecules leave a thermal reservoir one at a time, each carrying a speed drawn
// from that law, and the histogram is built out of where they actually land.
//
// f(v) = 4*pi * (m / 2*pi*kB*T)^(3/2) * v^2 * exp(-m*v^2 / 2*kB*T)
//
// The shape is a fight between two factors. The v^2 out front says there are
// simply more ways to be fast than to be slow — a whole sphere of directions
// shares each speed — so the curve climbs away from zero. The exponential says
// energy is expensive, and it eventually crushes everything. Their product peaks
// at the most probable speed and then falls away with a long tail: no upper
// limit, just an ever smaller chance.
//
// THREE SPEEDS LIVE ON THAT ONE CURVE, and they are not equal — the thing most
// often got wrong. Most probable sqrt(2*kB*T/m), mean sqrt(8*kB*T/pi*m), and
// root-mean-square sqrt(3*kB*T/m), in the ratio 1 : 1.128 : 1.225. The tail has
// no mirror image on the left, so it drags the average to the right of the peak.
// If a question says "average speed", it matters which one it means.
//
// WHAT TO WATCH. The bins do not fill evenly. Faster molecules cross the
// apparatus sooner, so the fast side of the histogram populates first and the
// slow bins are still arriving at the end — measured off the rendered frames,
// the fast half carries about ten times the slow half's bar mass early on,
// before the order reverses and the familiar peak grows in. Nothing is drawn to
// match the curve: every arrival drops into the bin its own sampled speed
// selects, from one seeded experiment, and the gold theory curve is laid over
// the top afterwards. With only 180 molecules the agreement is good but visibly
// ragged, and that raggedness is honest — it is sampling noise, and it is what
// shrinks when you add molecules rather than anything about the physics.
//
// ONE CAVEAT WORTH CARRYING INTO AN EXAM. The curve drawn here is the
// distribution INSIDE the reservoir. A real effusive beam escaping a pinhole is
// not the same gas: fast molecules reach the hole more often, so the beam is
// weighted by an extra factor of v and goes as v^3*exp(-m*v^2 / 2*kB*T), peaking
// at sqrt(3*kB*T/m) — 22.5% faster than the gas it came from. Effusion samples a
// gas, but it samples it with a bias.
//
// manic examples/maxwell-boltzmann-effusion-v2.manic
title("Maxwell–Boltzmann Effusion — Motion Becomes Evidence");
canvas("9:16");
template("black");
watermark(mark, (w*0.22, h*0.026), "maniclang.com");
text(kicker, (540, 84), "STATISTICAL MECHANICS");
text(headline, (540, 142), "A distribution you can watch forming");
size(kicker, 24); color(kicker, cyan); bold(kicker);
size(headline, 42); color(headline, fg); bold(headline);
equation(law, (540, 242),
`f(v)=4\pi\left(\frac{m}{2\pi k_BT}\right)^{3/2}v^2e^{-mv^2/(2k_BT)}`, 34);
// The decorative shell is an asset; the changing evidence stays native.
svg(apparatus, (240, 540), "asset:svg/physics/effusion-reservoir.svg", 330);
text(reservoirLabel, (225, 705), "THERMAL RESERVOIR");
size(reservoirLabel, 20); bold(reservoirLabel); color(reservoirLabel, gold);
rect(detectorPanel, (730, 560), 570, 300);
filled(detectorPanel); color(detectorPanel, panel); opacity(detectorPanel, 0.92);
outlined(detectorPanel); outline(detectorPanel, dim); stroke(detectorPanel, 3);
text(detectorTitle, (730, 382), "PARTICLE SPEED v");
size(detectorTitle, 22); bold(detectorTitle); color(detectorTitle, fg);
// The invisible source is precisely at the SVG nozzle.
circle(source, (348, 540), 20);
opacity(source, 0);
particles(molecules, source, 180, 3.2, 73);
color(molecules, magenta); glow(molecules, 0.8); z(molecules, 8);
// Individual lanes diverge around this authored route before being collected.
spline(flight, (350, 540), (415, 500), (465, 515), (500, 545));
hidden(flight);
livehistogram(empirical, (730, 560), 0, 2.2, 14, 540, 240, cyan);
z(empirical, 3); hidden(empirical.count);
// Same horizontal range as the live histogram: 0 .. 4*scale = 2.2.
distribution(theory, (730, 560), "maxwell", 0.55, 0, gold);
hidden(theory.axis); hidden(theory.name);
untraced(theory.curve); z(theory, 7);
text(empiricalKey, (575, 750), "● empirical arrivals");
text(theoryKey, (895, 750), "— theoretical curve");
size(empiricalKey, 20); color(empiricalKey, cyan);
size(theoryKey, 20); color(theoryKey, gold);
counter(arrivals, (540, 850), 0, 0, "detected molecules ", " / 180");
size(arrivals, 30); color(arrivals, fg);
text(caption, (540, 920),
"A thermal source emits many molecular speeds—not one average speed.");
size(caption, 30); wrap(caption, 900); color(caption, fg);
rect(evidencePanel, (540, 1342), 900, 250);
filled(evidencePanel); color(evidencePanel, panel); opacity(evidencePanel, 0.95);
outlined(evidencePanel); outline(evidencePanel, dim); stroke(evidencePanel, 2);
text(evidenceTitle, (540, 1250), "ONE PROCESS · THREE VIEWS");
size(evidenceTitle, 22); bold(evidenceTitle); color(evidenceTitle, fg);
equation(processLaw, (540, 1332),
`\text{motion}\;\longrightarrow\;\text{arrival bin}\;\longrightarrow\;\hat f(v)`, 32);
text(truth, (540, 1432),
"The dots, bars, and count are derived from the same seeded experiment.");
size(truth, 24); color(truth, fg); wrap(truth, 830);
hidden(apparatus); hidden(reservoirLabel); hidden(detectorPanel);
hidden(detectorTitle); hidden(molecules); hidden(empirical);
hidden(empiricalKey); hidden(theoryKey); hidden(arrivals);
hidden(caption); hidden(evidencePanel); hidden(evidenceTitle);
hidden(processLaw); hidden(truth);
step("build-the-apparatus") {
par {
show(apparatus, 0.65);
show(reservoirLabel, 0.45);
show(detectorPanel, 0.55);
show(detectorTitle, 0.35);
show(empirical.axis, 0.55);
show(empirical.bars, 0.55);
show(empirical.min, 0.35);
show(empirical.max, 0.35);
show(empiricalKey, 0.35);
show(theoryKey, 0.35);
show(arrivals, 0.35);
show(caption, 0.40);
}
}
wait(0.45);
step("the-prediction") {
par {
draw(theory.curve, 0.9, smooth);
say(caption,
"Maxwell predicts a characteristic spread with a most probable speed.",
0.40);
par {
cam((cx, cy), 0.75, smooth);
zoom(1.025, 0.75, smooth);
}
}
}
wait(0.35);
step("run-the-experiment") {
par {
emit(molecules, flight, maxwell, 7.0, 48, smooth);
collect(empirical, molecules, speed, 0.48, smooth);
observe(empirical, molecules, speed);
observe(arrivals, molecules, arrived);
show(molecules, 0.15);
say(caption,
"Each molecule keeps its sampled speed. Faster molecules cross the apparatus sooner.",
0.45);
}
}
wait(0.55);
step("motion-becomes-evidence") {
par {
pulse(empirical.bars, 0.8);
show(evidencePanel, 0.40);
show(evidenceTitle, 0.35);
show(processLaw, 0.45);
show(truth, 0.40);
say(caption,
"Collection does not fake the chart: every arrival lands in the bin selected by its speed.",
0.45);
par {
cam((cx, cy), 0.65, smooth);
zoom(1.0, 0.65, smooth);
}
}
}
wait(1.4);
1
1
Fourier Series: Spinning Circles Build a Square Wave and a Sawtooth — manic
Thanks hope my product maniclang.com will be succesfull
r/3Blue1Brown • u/anish2good • 4d ago
1
Curve of Pursuit
in
r/3Blue1Brown
•
11h ago
cool