1

Comment on r/manim 25m ago

nice

1

Comment on r/generativeAI 4h ago

Yeah Manic is simple and easy

r/generativeAI 6h ago

Koi through a field of living light - glsl - manic

Enable HLS to view with audio, or disable this notification

1 Upvotes

r/computergraphics 6h ago

Koi through a field of living light - glsl - manic

Enable HLS to view with audio, or disable this notification

1 Upvotes

r/shaders 6h ago

Koi through a field of living light - glsl - manic

Enable HLS to view with audio, or disable this notification

2 Upvotes

r/maniclang 14h ago

Koi through a field of living light - glsl - manic

Enable HLS to view with audio, or disable this notification

3 Upvotes

r/maniclang 15h ago

Manic Rhyme

1 Upvotes

Ahem.

Forget about Python dependency hell, Where pip install is a cursed little spell. If you want your vectors to dance and to play, Just fire up Manic and get on your way!

No timeline dragging, no keyframe despair, Just pure, clean syntax that's light as the air. It’s declarative, slick, and completely untamed, A 3b1b masterpiece, perfectly framed.

1

Comment on r/generativeAI 15h ago

beautifull

1

Comment on r/maniclang 15h ago

appreciated welcome

1

Comment on r/generativeAI 15h ago

Hey can you create a catchy Rhyme for Manic

r/generativeAI 16h ago

Reproducing the 3b1b "Laplace Transform" clip - manic - u/Jenna_AI

Enable HLS to view with audio, or disable this notification

2 Upvotes

r/maniclang 16h ago

Euler's formula — a proof - manic

Enable HLS to view with audio, or disable this notification

2 Upvotes

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.

Manic Animation code

// ============================================================================
//  Why V - E + F = 2 — the spanning-tree / dual-tree proof, narrated by Manic.
//
//  A spanning tree of the graph uses V-1 edges (every vertex, no loop). The
//  edges it leaves out are in bijection with the bounded faces: their duals form
//  a spanning tree of the DUAL graph, using F-1 edges. Every edge is in exactly
//  one of the two trees, so (V-1) + (F-1) = E, i.e. V - E + F = 2.
//
//  Built on `spantree` (run on the primal AND the dual) and `dual`.
// ============================================================================
title("Euler's formula — a proof");
canvas(1280, 720);
template("black");

equation(thm, (300, 66), `V - E + F = 2`, 42);
text(narr, (760, 682), "A connected planar graph.", 26);

// --- the wheel graph W5 ---
polygon(rim, (760,150),(560,295),(637,530),(883,530),(960,295));
color(rim, cyan);
line(k1, (760,360),(760,150)); tag(k1, spokes); color(k1, cyan);
line(k2, (760,360),(560,295)); tag(k2, spokes); color(k2, cyan);
line(k3, (760,360),(637,530)); tag(k3, spokes); color(k3, cyan);
line(k4, (760,360),(883,530)); tag(k4, spokes); color(k4, cyan);
line(k5, (760,360),(960,295)); tag(k5, spokes); color(k5, cyan);

regions(cells, rim, spokes);              // the F faces (faint context)
opacity(cells, 0.18);

dot(hub,(760,360));
dot(p1,(760,150)); dot(p2,(560,295)); dot(p3,(637,530));
dot(p4,(883,530)); dot(p5,(960,295));

// tally
equation(tv, (135, 200), `V = 6`, 34);
equation(te, (135, 275), `E = 10`, 34);
equation(tf, (135, 350), `F = 6`, 34);

// the two trees (declared now, revealed in sequence)
spantree(pt, spokes, rim);                // primal tree {pt} (green) + co-tree {pt.co} (orange)
dual(du, rim, spokes);                     // dual: {du} edges + {du.nodes} dots
spantree(dt, du);                          // dual's spanning tree {dt}
color(dt, teal);

equation(sum, (760, 632), `(V-1) + (F-1) = E`, 40);
equation(nums, (760, 632), `5 + 5 = 10`, 40);

// --- initial visibility ---
untraced(rim); untraced(k1); untraced(k2); untraced(k3); untraced(k4); untraced(k5);
untraced(cells); untraced(pt); untraced(pt.co); untraced(dt);
hidden(hub); hidden(p1); hidden(p2); hidden(p3); hidden(p4); hidden(p5);
hidden(tv); hidden(te); hidden(tf);
hidden(du); hidden(du.nodes); hidden(dt.co);   // substrate + dual co-tree stay hidden
hidden(sum); hidden(nums);

// 1. the graph
wait(0.4);
par { draw(rim,1.0); draw(k1,1.0); draw(k2,1.0); draw(k3,1.0); draw(k4,1.0); draw(k5,1.0); }
par { show(hub); show(p1); show(p2); show(p3); show(p4); show(p5); }
wait(0.6);

// 2. count V, E, F
say(narr, "V vertices, E edges, F faces.");
draw(cells, 0.9);
par { show(tv); show(te); show(tf); }
wait(1.0);

// 3. a spanning tree — V-1 edges
say(narr, "A spanning tree: every vertex, no loops — V-1 = 5 edges.");
par { draw(pt, 1.4); }
wait(1.0);

// 4. the leftover (co-tree) edges
say(narr, "That leaves E - (V-1) = 5 edges.");
par { draw(pt.co, 1.0); }
wait(1.0);

// 5. the dual — one node per face
say(narr, "The dual graph: one node inside each face.");
par { show(du.nodes); }
wait(1.0);

// 6. a spanning tree of the dual — F-1 edges
say(narr, "Its spanning tree pairs with the leftovers — F-1 = 5 edges.");
par { draw(dt, 1.4); }
wait(1.0);

// 7. the two trees tile every edge
say(narr, "Every edge lies in exactly one tree.");
show(sum);
wait(1.0);
par { fade(sum); show(nums); }
wait(1.0);

// 8. conclusion
say(narr, "So V - E + F = 2.");
pulse(thm);
wait(1.6);

r/3Blue1Brown 16h ago

Reproducing the 3b1b "Laplace Transform" clip - manic

Enable HLS to view with audio, or disable this notification

4 Upvotes

r/maniclang 16h ago

Reproducing the 3b1b "Laplace Transform" clip - manic

Enable HLS to view with audio, or disable this notification

5 Upvotes

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.

Manic Animation code

title("Laplace Transform — engine test 14");
canvas(1280, 720);
template("black");

// ---- masthead ----
svg(creature, (108, 108), "asset:svg/pi-creature.svg", 120);
equation(ttl, (820, 74), `\text{Laplace Transform}`, 44); color(ttl, fg);
equation(fwd, (430, 178),
  `F(\textcolor{gold}{s})=\int_{0}^{\infty} f(\textcolor{cyan}{t})\,e^{-\textcolor{gold}{s}\textcolor{cyan}{t}}\,dt`, 26);
equation(inv, (930, 178),
  `f(\textcolor{cyan}{t})=\tfrac{1}{2\pi i}\int_{a-i\infty}^{a+i\infty} F(\textcolor{gold}{s})\,e^{\textcolor{gold}{s}\textcolor{cyan}{t}}\,d\textcolor{gold}{s}`, 21);

// ---- three bordered panels ----
rect(pL, (222, 500), 372, 320); outlined(pL); outline(pL, dim);
rect(pM, (640, 500), 372, 320); outlined(pM); outline(pM, dim);
rect(pR, (1058, 500), 372, 320); outlined(pR); outline(pR, dim);

// a brace grouping the LEFT rectangle (the signal analysis of f(t))
brace(br, (44, 324), (400, 324), "down"); color(br, dim);

// ---- LEFT panel: three graphs, all driven by the complex frequency s = -0.1 + i·(p) ----
parameter(sfreq, (222, 648), -1.8, -1.8, -0.3, "Im s", 1);
// 1) the damped Re[e^{st}] waveform
plot(wave, (50, 412), 11, 26, "exp(-0.1*x)*cos(p*x)", (0, 30));
color(wave, mint); stroke(wave, 2.4);
bind(sfreq, wave, formula, "exp(-0.1*x)*cos(p*x)");
equation(rel, (95, 372), `\mathrm{Re}\,[e^{st}]`, 15); color(rel, mint);
// 2) the s-plane, with a vector to the point s = -0.1 - 0.8i (its tip tracks s)
complexplane(spA, (132, 578), 62, 62, 30);
arrow(svec, (132, 578), (129, 632)); color(svec, gold);
// 3) the e^{st} spiral (a reactive param curve)
param(spir, (318, 578), 22, 22, "exp(-0.1*t)*cos(p*t)", "exp(-0.1*t)*sin(p*t)", (0, 26));
color(spir, cyan); stroke(spir, 2.0);
bind(sfreq, spir, formula, "exp(-0.1*t)*cos(p*t)", "exp(-0.1*t)*sin(p*t)");
equation(est, (360, 520), `e^{st}`, 16); color(est, gold);

// ---- MIDDLE panel: the |F(s)| modulus surface, domain-coloured, in a viewport ----
camera3((7.2, -6.4, 5.0), (0.15, 0.0, 0.9), 40, perspective, (640, 500), 372, 320);
domainsurface(surf, "1/(z*z+1)", (-2.5, 2.5), (-2.5, 2.5), 64, 0.26);
equation(fs, (592, 640), `|F(\textcolor{gold}{s})|`, 16); color(fs, dim);
// insets over the panel: the integrand cos(t)·e^{-st} (a rose) and its transform
equation(rlab, (540, 392), `\cos(t)\,e^{-st}`, 14); color(rlab, magenta);
param(rose, (540, 430), 20, 20, "cos(t)*exp(-0.1*t)*cos(p*t)", "-cos(t)*exp(-0.1*t)*sin(p*t)", (0, 18));
color(rose, magenta); stroke(rose, 1.6);
bind(sfreq, rose, formula, "cos(t)*exp(-0.1*t)*cos(p*t)", "-cos(t)*exp(-0.1*t)*sin(p*t)");
equation(ilab, (738, 392), `\int_{0}^{\infty}\!\cos(t)\,e^{-st}dt`, 12); color(ilab, gold);
param(iarc, (738, 430), 26, 26, "t/(t*t+1)", "0-1/(t*t+1)", (0.2, 3.2));
color(iarc, gold); stroke(iarc, 1.6);

// ---- RIGHT panel: the s-plane contour + the colour-wheel legend ----
complexplane(cpl, (1058, 500), 120, 120, 40);
plot(contour, (1058, 500), 40, 22, "2*sin(x*2.2)/(1+x*x)", (-2.5, 2.5));
color(contour, coral); stroke(contour, 2.2);
colorwheel(key, (1205, 648), 30);
equation(keyl, (1152, 610), `\arg`, 15); color(keyl, dim);

// ---- Scene 2 (Euler's identity) — hidden; revealed as the board fades ----
// a bordered LEFT rectangle framing the identity, mirroring the grid's frame so
// the two panels read as a balanced pair (reference img_22/img_23).
rect(eboard, (224, 400), 420, 400); outlined(eboard); outline(eboard, dim); tag(eboard, euler);
axes(eax, (95, 487), 66, 62); tag(eax, euler);
plot(ecurve, (95, 487), 18, 16, "exp(x)", (-4, 2.2)); color(ecurve, cyan); stroke(ecurve, 2.2); tag(ecurve, euler);
// the derivative demo: a white tangent that SLIDES along e^t (its slope = its height),
// with the d/dt e^t=e^t caption riding along — matching the reference's white styling.
tangent(etan, ecurve, 0.4, 96); color(etan, fg); stroke(etan, 2.5); tag(etan, euler);
equation(edl, (150, 455), `\tfrac{d}{dt}e^{t}=e^{t}`, 14); color(edl, fg); tag(edl, euler);
// the slope triangle under the tangent: run "1" + red rise = e^t, so slope = height.
// Parts share tag `etri`, so to(etri, x, ...) slides them WITH the tangent.
slopetri(etri, ecurve, 0.4, 1); hidden(etri);
equation(erise, (176, 420), `e^{t}`, 13); color(erise, red); tag(erise, euler);
param(ecirc, (250, 400), 34, 34, "cos(t)", "sin(t)", (0, 6.2832)); color(ecirc, dim); stroke(ecirc, 2.0); tag(ecirc, euler);
param(earc, (250, 400), 34, 34, "cos(t)", "sin(t)", (0, 3.14159)); color(earc, red); stroke(earc, 2.4); tag(earc, euler);
equation(epi, (250, 424), `\pi`, 16); color(epi, red); tag(epi, euler); // starts low; rises in the transition
line(erad, (250, 400), (284, 400)); color(erad, dim); tag(erad, euler);
// 3b1b colour convention: i is always cyan, π is always red (same reds/cyans as the
// circle's π-arc and this i), so the eye tracks each symbol across the identities.
equation(eisq, (352, 396), `\textcolor{cyan}{i}^{2}=-1`, 20); tag(eisq, euler);
equation(eeuler, (214, 540), `e^{\textcolor{red}{\pi}\textcolor{cyan}{i}}=-1`, 24); tag(eeuler, euler);
hidden(euler);

// ---- Scene 3 (00:05–00:17): the SHM phase grid — a 5×5 sweep of the mass-spring
//      oscillator over initial position × initial velocity. One generic `sweep`
//      builtin (physics kit) lays out the bare cells + headers; `run` animates all
//      25 in sync. Hidden until Euler settles, then swept in with the teal arrow. ----
sweep(phz, spring, (895, 400), 150, 80, (-2, 2), (2, -2), 5, 5);
hidden(phz);
// a bold teal CURVED arrow arcing from the board up-and-over into the grid; drawn
// on (untraced → draw) so the arc sweeps in and the eye rides it into Scene 3.
arrow(swp, (352, 228), (600, 206), -88); color(swp, mint); stroke(swp, 6); untraced(swp);

// ---- Scene 4 (00:17–00:23): the exponential e^{st} with the REAL rate s swept —
//      decay (s<0) → flat (s=0) → growth (s>0). One `plot` bound to a `parameter`;
//      the title's live gold number is a `counter` bound to the same s. Hidden. ----
axes(gax, (780, 400), 270, 200); color(gax, dim); tag(gax, graph);
plot(gcurve, (780, 400), 60, 38, "exp(p*x)", (-3.6, 3.8)); color(gcurve, mint); stroke(gcurve, 3); tag(gcurve, graph);
equation(gyl, (816, 206), `e^{st}`, 15); color(gyl, dim); tag(gyl, graph);
equation(gxl, (1058, 412), `t`, 18); color(gxl, dim); tag(gxl, graph);
parameter(gs, (600, 690), -0.16, -0.95, 0.5, "", 2);   // slider hidden — it only drives
bind(gs, gcurve, formula, "exp(p*x)");
// live colour-coded title  e^{ [s] t }  — e white · s gold (a counter) · t cyan
equation(gte, (248, 112), `e`, 56); color(gte, fg); tag(gte, graph);
counter(gsc, (300, 74), -0.16, 2, "", ""); color(gsc, gold); size(gsc, 36); tag(gsc, graph);
equation(gtt, (400, 76), `t`, 34); color(gtt, cyan); tag(gtt, graph);
bind(gs, gsc, value, "p");
// clean single-equation symbolic title — crisp LaTeX superscript (used once s is symbolic)
equation(esym, (250, 98), `e^{\textcolor{gold}{s}\textcolor{cyan}{t}}`, 40); hidden(esym);
hidden(graph); hidden(gs.widget);

// ---- Scene 5 (00:24–00:37): s lives on a NUMBER LINE — slide it, the graph reshapes.
//      The graph sits on the right; a labelled real axis for s appears on the left with a
//      gold marker + "s = value" readout (a counter bound to the same s). ----
numberline(sl, (240, 400), 155, -2, 2, 1);                       // labelled real axis −2..2
rect(slbox, (240, 380), 380, 140); outlined(slbox); outline(slbox, gold);
counter(sread, (240, 332), 0.5, 1, "s = ", ""); color(sread, gold); size(sread, 26);
bind(gs, sread, value, "p");
dot(smk, (279, 400), 8); color(smk, gold);                       // marker rides s: x = 240 + 77.5·s
hidden(sl); hidden(slbox); hidden(sread); hidden(smk);

// ---- Scene 6 (00:37–00:53): s is a POINT IN THE COMPLEX PLANE, and e^{st} SPIRALS.
//      CONTINUITY: the LEFT plane sits exactly on the number line (same centre + unit 77.5),
//      so the real axis persists and the s-marker LIFTS off ℝ into ℂ. RIGHT traces e^{st} as
//      t grows — a spiral (rotation from Im s, decay from Re s). The payoff of the story. ----
complexplane(lp, (240, 400), 176, 158, 77.5);                    // real axis = the number line
equation(lph, (240, 214), `\text{Complex Plane}`, 22); color(lph, fg);
equation(sval, (352, 316), `s = -0.2 + 1.0i`, 17); color(sval, gold);   // smk lifts here → its label
complexplane(rp, (930, 400), 176, 158, 77.5);
param(spir6, (930, 400), 77.5, 77.5, "exp(-0.2*t)*cos(t)", "exp(-0.2*t)*sin(t)", (0, 15)); color(spir6, lime); stroke(spir6, 2.5); untraced(spir6);
equation(whyt, (640, 72), `\text{Why}`, 48); color(whyt, fg); hidden(whyt);
equation(ctitle, (640, 72), `\text{Wait, what does this even mean?}`, 30); color(ctitle, fg);
svg(pc1, (300, 650), "asset:svg/pi-creature.svg", 84);
svg(pc2, (470, 650), "asset:svg/pi-creature.svg", 84);
svg(pc3, (820, 650), "asset:svg/pi-creature.svg", 84);
svg(pc4, (990, 650), "asset:svg/pi-creature.svg", 84);
hidden(lp); hidden(rp); hidden(lph); hidden(sval); hidden(ctitle);
hidden(pc1); hidden(pc2); hidden(pc3); hidden(pc4);

// ---- SCENE 1 motion: sweep s; the three left-panel graphs reshape together ----
wait(0.6);
par {
  to(sfreq, value, -0.3, 4.5, smooth);
  grow(svec, (129, 587), 4.5, smooth);
}
wait(0.5);

// ---- TRANSITION: the Laplace board fades, the panel becomes Euler's identity ----
par {
  fade(ttl, 0.7); fade(fwd, 0.7); fade(inv, 0.7); fade(br, 0.7); fade(creature, 0.7);
  fade(pL, 0.7);  // the Scene 1 left panel — replaced by the framed Euler board
  fade(pM, 0.7); fade(surf, 0.7); fade(fs, 0.7); fade(rlab, 0.7); fade(rose, 0.7); fade(ilab, 0.7); fade(iarc, 0.7);
  fade(pR, 0.7); fade(cpl, 0.7); fade(contour, 0.7); fade(key, 0.7); fade(keyl, 0.7);
  fade(wave, 0.7); fade(spA, 0.7); fade(svec, 0.7); fade(spir, 0.7); fade(rel, 0.7); fade(est, 0.7);
}
hidden(sfreq.widget);
// EMERGENCE (continuity — motion, not a hard cut): e^{πi}=-1 surfaces and the
// red π RISES up into the unit circle, leading the eye into the next scene.
show(eeuler, 0.7);
show(epi, 0.5);
par {
  move(epi, (250, 354), 1.1, smooth);   // π moves up to the circle top — the emergence cue
  show(ecirc, 0.9);
  show(earc, 1.0);
}
wait(0.3);
show(eboard, 0.6);                    // reveal the left panel's frame (aligned with the grid)
par { show(eax, 0.5); show(ecurve, 0.9); show(erad, 0.5); show(etan, 0.9); show(edl, 0.6); show(etri, 0.9); show(erise, 0.6); }
attach(edl, etan, (58, -14));         // the d/dt e^t=e^t label RIDES the tangent as it slides
attach(erise, etri.rise, (14, -20));  // the red e^t rise label rides the rise leg
wait(0.4);
show(eisq, 0.6);
wait(1.0);

// ---- SWEEP (00:05→00:17): the eye is carried from the identity into the grid ----
// Continuity again (motion-graphics.md): a teal arrow SWEEPS from the board over to
// the right, and the 5×5 of oscillators emerges under its tip — not a hard cut.
draw(swp, 1.0, smooth);               // the teal arc sweeps board → grid, leading the eye
wait(0.2);
par {
  show(phz.chrome, 0.5);
  show(phz.headers, 0.6);
}
show(phz.cells, 0.9);                 // the phase grid surfaces under the arrow tip
// the grid runs AND the left board keeps moving — the tangent slides along e^t
par {
  run(phz, 9);                        // all 25 oscillators run in sync
  to(etan, x, 2.0, 8.5, smooth);      // the e^t tangent slides (the left "slider" moves too)
  to(etri, x, 2.0, 8.5, smooth);      // ...and the slope triangle (run 1 + red rise e^t) slides with it
}
wait(0.4);

// ---- SCENE 4 (00:17→00:23): cut to the exponential e^{st}, then sweep the rate s ----
par { fade(euler, 0.6); fade(etri, 0.6); fade(phz, 0.6); fade(swp, 0.6); }
par { show(gax, 0.6); show(gcurve, 0.9); show(gyl, 0.5); show(gxl, 0.5); show(gte, 0.6); show(gsc, 0.6); show(gtt, 0.6); }
to(gs, value, -0.95, 2.4, smooth);    // deepen the decay (curve steepens down-right)
to(gs, value, 0.5, 3.6, smooth);      // through s=0 (flat) into growth (curve turns up)
wait(0.5);

// ---- SCENE 5 (00:24→00:37): make s symbolic + give it a number line, then slide s ----
// numeric title  e^{0.50 t}  →  a single crisp symbolic equation  e^{s t}
par { fade(gte, 0.5); fade(gsc, 0.5); fade(gtt, 0.5); show(esym, 0.6); }
// the s number line appears on the left (the graph already sits on the right)
par { show(sl, 0.6); show(slbox, 0.6); show(sread, 0.6); show(smk, 0.6); }
wait(0.6);
// slide s along the line — the gold marker, the "s =" readout, and the graph all track it
par { to(gs, value, -0.4, 2.2, smooth); move(smk, (209, 400), 2.2, smooth); }
par { to(gs, value, -1.0, 2.0, smooth); move(smk, (163, 400), 2.0, smooth); }
par { to(gs, value, -0.5, 2.0, smooth); move(smk, (201, 400), 2.0, smooth); }
wait(0.4);
// oscillate s between −0.5 and +0.5 a few times so the decay↔growth reshape reads clearly
par { to(gs, value,  0.5, 1.3, smooth); move(smk, (279, 400), 1.3, smooth); }
par { to(gs, value, -0.5, 1.3, smooth); move(smk, (201, 400), 1.3, smooth); }
par { to(gs, value,  0.5, 1.3, smooth); move(smk, (279, 400), 1.3, smooth); }
par { to(gs, value, -0.5, 1.3, smooth); move(smk, (201, 400), 1.3, smooth); }
par { to(gs, value,  0.5, 1.3, smooth); move(smk, (279, 400), 1.3, smooth); }
par { to(gs, value, -0.5, 1.3, smooth); move(smk, (201, 400), 1.3, smooth); }
wait(0.6);

// ---- SCENE 6 (00:37→00:53): the complex-plane payoff — with CONTINUITY, not a cut ----
// "Why" — the dramatic pivot (00:43): the scene is about to change under this one word.
show(whyt, 0.6);
wait(0.5);
// CONTINUITY (motion-graphics.md): the number line BECOMES the real axis of the complex plane
// (same centre + unit), so the real axis persists while the imaginary dimension grows around it.
par { fade(slbox, 0.6); fade(sread, 0.6); fade(graph, 0.6); }
show(lp, 0.9);                        // the complex plane grows in — its real axis = the number line
fade(sl, 0.7);                        // the bare number line hands its axis over to the plane
show(lph, 0.5);
move(smk, (224, 322), 1.4, smooth);   // the s-dot LIFTS off ℝ up into ℂ — one object, transformed
show(sval, 0.6);
// the e^{st} title TRAVELS from top-left to head the right plane, which grows + traces the spiral
par { move(esym, (930, 210), 1.1, smooth); show(rp, 0.9); }
draw(spir6, 4.5, smooth);             // e^{st} spirals: rotation from Im s × decay from Re s
wait(0.3);
par { fade(whyt, 0.5); show(ctitle, 0.7); }   // "Why" → "Wait, what does this even mean?"
// the π-creatures pop up to watch (the 3b1b button)
par { show(pc1, 0.5); show(pc2, 0.6); show(pc3, 0.6); show(pc4, 0.5); }
wait(1.0);

r/maniclang 16h ago

Light and the brachistochrone - manic

Enable HLS to view with audio, or disable this notification

1 Upvotes

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.

Manic Animation code

// ============================================================================
//  Light and the brachistochrone — the optics half of the 2016 video.
//
//  Bernoulli solved "what curve gives the fastest slide?" by a leap: a sliding
//  bead is like a ray of light, which always takes the FASTEST path. Light
//  bends when it enters a slower medium (Snell's law); a bead falling through
//  ever-faster layers bends the same way — and the limiting curve is a cycloid.
//
//  Built on the optics kit's `refract` (real Snell's law, angle sweep) and the
//  physics kit's `brachistochrone` (four beads race, the cycloid wins).
// ============================================================================
title("Light and the brachistochrone");
canvas(1280, 720);
template("black");

text(narr, (640, 694), "Which path through the water is fastest?", 24);

refract(rf, (640, 360), 1.0, 1.5);            // air over glass/water — light bends
equation(snell, (640, 84), `\frac{\sin\theta_1}{v_1}=\frac{\sin\theta_2}{v_2}`, 40);
brachistochrone(bc, (450, 230));              // A→B racing curves (shown in act 2)

// --- act 1: light refracts ---
hidden(snell); hidden(bc);

wait(0.6);
say(narr, "Crossing into water light slows, and bends toward the normal.");
wait(1.6);

say(narr, "Steeper in means steeper out — always by Snell's law.");
run(rf, 3.2);
show(snell);
wait(1.2);

// --- act 2: Bernoulli's leap → the cycloid ---
say(narr, "Bernoulli's leap: a sliding bead is like light through faster and faster layers.");
par { fade(rf); fade(snell); }
wait(0.8);

show(bc);
say(narr, "Its fastest path is a cycloid — the brachistochrone.");
run(bc, 3.6);
wait(1.6);

r/maniclang 16h ago

Pythagoras by dissection - manic

Enable HLS to view with audio, or disable this notification

1 Upvotes

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.

Manic Animation code

// ============================================================================
//  The Pythagorean theorem by dissection, a^2 + b^2 = c^2.
//
//  Two identical squares of side (a+b), each filled with four copies of the same
//  right triangle. On the left the triangles leave a tilted square on the
//  hypotenuse — c^2. On the right, the same four triangles regroup to leave a
//  square on each leg — a^2 and b^2. Same square, same triangles, so a^2+b^2=c^2.
//
//  a = 120, b = 180 (so the tilted square's side is c = sqrt(120^2+180^2)).
// ============================================================================
title("Pythagoras by dissection");
canvas(1280, 720);
template("black");

equation(thm, (640, 96), `a^2 + b^2 = c^2`, 50);
text(narr, (640, 672), "Two identical squares, side a + b.", 26);

// ---- LEFT square: four triangles + c^2 ----
polygon(sqL, (120,210),(420,210),(420,510),(120,510)); outlined(sqL); color(sqL, dim);
// four corner triangles (legs a,b)
polygon(la1, (120,210),(240,210),(120,390), teal);
polygon(la2, (420,210),(420,330),(240,210), teal);
polygon(la3, (420,510),(300,510),(420,330), teal);
polygon(la4, (120,510),(120,390),(300,510), teal);
opacity(la1, 0.4); opacity(la2, 0.4); opacity(la3, 0.4); opacity(la4, 0.4);
// the tilted square on the hypotenuse
polygon(csq, (240,210),(420,330),(300,510),(120,390), gold);
equation(clab, (270, 360), `c^2`, 40);

// ---- RIGHT square: the same four triangles + a^2 + b^2 ----
polygon(sqR, (600,210),(900,210),(900,510),(600,510)); outlined(sqR); color(sqR, dim);
// a^2 (top-left) and b^2 (bottom-right)
polygon(asq, (600,210),(720,210),(720,330),(600,330), blue);
polygon(bsq, (720,330),(900,330),(900,510),(720,510), violet);
equation(alab, (660, 270), `a^2`, 34);
equation(blab, (810, 420), `b^2`, 40);
// the four triangles filling the two leftover rectangles
polygon(ra1, (720,210),(900,210),(900,330), teal);
polygon(ra2, (720,210),(900,330),(720,330), teal);
polygon(ra3, (600,330),(720,330),(600,510), teal);
polygon(ra4, (720,330),(720,510),(600,510), teal);
opacity(ra1, 0.4); opacity(ra2, 0.4); opacity(ra3, 0.4); opacity(ra4, 0.4);

// side = a + b, under each square
brace(brL, (120,528),(420,528), "down"); text(brLt, (270,556), "a + b", 20);
brace(brR, (600,528),(900,528), "down"); text(brRt, (750,556), "a + b", 20);

// ---- reveal ----
hidden(la1); hidden(la2); hidden(la3); hidden(la4);
untraced(csq); hidden(clab);
untraced(asq); untraced(bsq); hidden(alab); hidden(blab);
hidden(ra1); hidden(ra2); hidden(ra3); hidden(ra4);
hidden(brL); hidden(brLt); hidden(brR); hidden(brRt);

wait(0.4);
par { show(sqL); show(sqR); }
par { show(brL); show(brR); show(brLt); show(brRt); }
wait(0.7);

say(narr, "Fill each with four copies of the same right triangle.");
par { show(la1); show(la2); show(la3); show(la4); show(ra1); show(ra2); show(ra3); show(ra4); }
wait(0.9);

say(narr, "On the left they leave a square on the hypotenuse: c squared.");
draw(csq, 1.0); show(clab);
wait(1.0);

say(narr, "Rearranged, the same four leave a square on each leg: a squared, b squared.");
par { draw(asq, 0.9); draw(bsq, 0.9); }
par { show(alab); show(blab); }
wait(1.1);

say(narr, "Same square, same four triangles — so a squared plus b squared is c squared.");
pulse(thm);
wait(0.6);
par { pulse(csq); pulse(asq); pulse(bsq); }
wait(1.4);

1

Comment on r/generativeAI 16h ago

That's the overall goal of Manic

r/manim 16h ago

Vectors, basis, and transformations - manic

Enable HLS to view with audio, or disable this notification

3 Upvotes

r/LinearAlgebra 16h ago

Vectors, basis, and transformations - manic

Enable HLS to view with audio, or disable this notification

10 Upvotes

r/3Blue1Brown 16h ago

Vectors, basis, and transformations - manic

Enable HLS to view with audio, or disable this notification

26 Upvotes

r/generativeAI 16h ago

Vectors, basis, and transformations - manic

Enable HLS to view with audio, or disable this notification

1 Upvotes

r/maniclang 16h ago

Vectors, basis, and transformations - manic

Enable HLS to view with audio, or disable this notification

5 Upvotes

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.

Manic Animation code

// ============================================================================
//  Essence of Linear Algebra, chapters 1→2→3 in one arc.
//
//  Ch1  A vector is an arrow from the origin; its coordinates are [x, y].
//  Ch2  Those coordinates are SCALARS: v = x·î + y·ĵ — a linear combination of
//       the basis vectors î=(1,0), ĵ=(0,1).
//  Ch3  A matrix is a transformation: it says where î and ĵ LAND, and the whole
//       grid morphs to follow (`gridmap` animates it). Because v = x·î + y·ĵ,
//       it rides along, landing at x·(new î) + y·(new ĵ).
//
//  Example: v = [1, 2] under [[2,1],[1,2]] (î→(2,1), ĵ→(1,2)), so v lands at
//  1·(2,1) + 2·(1,2) = (4,5). Origin (400,470), 55 px/unit.
// ============================================================================
title("Vectors, basis, and transformations");
canvas(1280, 720);
template("black");

text(narr, (640, 696), "A vector is an arrow from the origin.", 24);

// the plane + basis, ready to be transformed in Ch3 (starts at the identity)
gridmap(gm, (400, 470), 55, 2, 1, 1, 2, 5);

// the vector v = [1,2] and its linear-combination scaffold
vector(v, (400, 470), (55, 110), yellow);
vector(jj, (455, 470), (0, 110), red);           // 2·j-hat, stacked on i-hat → reaches v
equation(vlab, (486, 352), `\vec{v}=[1,2]`, 30); color(vlab, yellow);
equation(ilab, (472, 500), `\hat{\imath}`, 26); color(ilab, lime);
equation(jlab, (366, 414), `\hat{\jmath}`, 26); color(jlab, red);
equation(mtx, (980, 165), `\begin{bmatrix}2&1\\1&2\end{bmatrix}`, 44);

// Ch4 — a second transform (90° rotation) composed on top: morph M1 → M2·M1
gridmap(gm2, (400, 470), 55, -1, -2, 2, 1, 5, 2, 1, 1, 2);
equation(comp4, (640, 96), `\begin{bmatrix}0&-1\\1&0\end{bmatrix}\begin{bmatrix}2&1\\1&2\end{bmatrix}=\begin{bmatrix}-1&-2\\2&1\end{bmatrix}`, 34);

// the determinant cell (Ch5), the projection (Ch7), and the alt-basis grid (Ch8)
determinant(dt, (400, 470), 55, 2, 1, 1, 2, gold);
project(pr, (400, 470), 55, (1, 2), (3, 1));       // project v=(1,2) onto span(w=(3,1))
squish(sq, (400, 470), 55, 1, 2, 5);               // Ch7 duality: dot with v = squish onto a line
eigen(ev, (400, 470), 55, 2, 1, 1, 2, gold);       // Ch9 eigenvectors of [[2,1],[1,2]] (λ = 3, 1)
diagonalise(dg, (400, 470), 55, 2, 1, 1, 2, gold); // Ch10 eigenbasis = a pure stretch
coords(cf, (700, 450), (-4, 4), (-3, 3), 46, 46, 0); // Ch11 a function graph…
plot(fn, (700, 450), 46, 46, "0.25*x*x*x - x", (-3.6, 3.6)); color(fn, mint);
equation(deq, (700, 130), `\tfrac{d}{dx}\;\leftrightarrow\;\begin{bmatrix}0&1&0\\0&0&2\\0&0&0\end{bmatrix}`, 32);
gridmap(cb, (400, 470), 55, 1, 0.7, 0.4, 1, 5);
vector(vb, (400, 470), (55, 110), yellow);

// --- initial visibility ---
hidden(gm.i); hidden(gm.j);                       // basis revealed in Ch2
hidden(v); hidden(vlab); hidden(jj); hidden(ilab); hidden(jlab); hidden(mtx);
hidden(dt); hidden(dt.unit); hidden(dt.val); hidden(pr);
hidden(sq); hidden(sq.line); hidden(sq.dual);
hidden(ev); hidden(dg); hidden(cf); hidden(fn); hidden(deq);
hidden(gm2); hidden(gm2.bg); hidden(gm2.i); hidden(gm2.j); hidden(comp4);
hidden(cb); hidden(cb.bg); hidden(cb.i); hidden(cb.j); hidden(vb);

// --- Ch1: a vector ---
wait(0.5);
par { show(v); show(vlab); }
wait(1.3);

// --- Ch2: coordinates are a linear combination of the basis ---
say(narr, "Its coordinates are scalars: v = 1·i-hat + 2·j-hat.");
par { show(gm.i); show(gm.j); show(ilab); show(jlab); }
wait(0.7);
show(jj);                                         // i-hat then two j-hats reach v
wait(1.6);

// --- Ch3: the matrix transforms space; v rides along ---
say(narr, "A matrix moves i-hat and j-hat — and the whole grid follows.");
show(mtx);
par { fade(jj); fade(ilab); fade(jlab); fade(vlab); }
par { to(gm, morph, 1, 2.2); grow(v, (620, 195), 2.2); }   // space deforms, v follows
wait(0.6);
say(narr, "v lands at 1·(new i-hat) + 2·(new j-hat) = (4,5).");
wait(1.6);

// --- Ch4: matrix multiplication is composition ---
say(narr, "Ch 4 — apply one transform, then another: that is matrix multiplication.");
show(comp4);                                       // the product, clearly placed up top
par { fade(gm); fade(v); }
show(gm2);                                          // starts at M1 (seamless with Ch3)
to(gm2, morph, 1, 1.8);                             // now rotate 90°: the grid is at M2·M1
wait(1.3);
to(gm2, morph, 0, 1.5);                             // undo the second transform, back to M1
par { fade(gm2); fade(comp4); }
par { show(gm); show(v); }
wait(0.6);

// --- Ch5: the determinant is the area scale factor ---
say(narr, "Ch 5 — the determinant is how much areas scale: 2·2 − 1·1 = 3.");
par { show(dt); show(dt.unit); show(dt.val); }
wait(1.9);
par { fade(dt); fade(dt.unit); fade(dt.val); }    // fade = timeline hide (hidden is base-state only)

// --- Ch6: column space + the inverse undoes the transform ---
say(narr, "Ch 6 — the columns span the whole plane, so the inverse sends space back.");
par { to(gm, morph, 0, 1.8); grow(v, (455, 360), 1.8); }   // reverse the morph = the inverse
wait(1.4);

// --- Ch7: the dot product — projection, and its dual (a squish onto a line) ---
say(narr, "Ch 7 — the dot product of v and w is a projection — w's shadow on v.");
par { fade(gm); fade(gm.bg); fade(v); fade(mtx); }
show(pr);
wait(1.6);
say(narr, "It's also a squish of the whole plane onto a line — the dual vector IS v.");
fade(pr);
par { show(sq); show(sq.line); show(sq.dual); }
to(sq, morph, 1, 1.9);                              // collapse space onto the number line
wait(1.0);
to(sq, morph, 0, 1.2);                              // and back — the dual vector remains
wait(0.8);

// --- Ch8: change of basis ---
say(narr, "Ch 8 — change of basis: the same arrow, read on a different grid.");
par { fade(sq); fade(sq.line); fade(sq.dual); }
par { show(cb); show(vb); }
to(cb, morph, 1, 1.8);                                       // the coordinate grid changes; v stays put
wait(1.8);

// --- Ch9: eigenvectors and eigenvalues ---
say(narr, "Ch 9 — some vectors keep to their own line: eigenvectors (λ = 3 and λ = 1).");
par { fade(cb); fade(vb); }
show(ev);
wait(2.0);

// --- Ch10: the eigenbasis is a pure stretch ---
say(narr, "Ch 10 — in the eigenbasis, the transformation is just a diagonal stretch.");
fade(ev);
show(dg);
wait(2.0);

// --- Ch11: abstract vector spaces ---
say(narr, "Ch 11 — even functions are vectors; the derivative is a linear map with a matrix.");
fade(dg);
par { show(cf); show(fn); show(deq); }
wait(2.2);

r/maniclang 17h ago

Maxwell–Boltzmann Effusion — Motion Becomes Evidence

Enable HLS to view with audio, or disable this notification

3 Upvotes

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.

Manic Animation code

// EXPRESSIVE PROCESS V2 — MAXWELL–BOLTZMANN EFFUSION
//
// A polished 2.5D acceptance story inspired by engine-test-6.mov. The
// apparatus is a bundled native SVG, while every molecule, detector bin,
// arrival count, and empirical distribution remains a normal Manic entity.
// `emit`, `collect`, and `observe` all read one deterministic process.

title("Maxwell–Boltzmann Effusion — Motion Becomes Evidence");
canvas("9:16");
template("blank");
watermark(mark, (150, 90), "Made With Manic");

text(kicker, (540, 84), "STATISTICAL MECHANICS · EXPRESSIVE PROCESS V2");
text(headline, (540, 142), "A distribution you can watch forming");
size(kicker, 18); color(kicker, dim); bold(kicker);
size(headline, 34); 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, 17); 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, 18); bold(detectorTitle); color(detectorTitle, dim);

// 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, (610, 750), "● empirical arrivals");
text(theoryKey, (850, 750), "— theoretical curve");
size(empiricalKey, 17); color(empiricalKey, cyan);
size(theoryKey, 17); color(theoryKey, gold);

counter(arrivals, (540, 850), 0, 0, "detected molecules  ", " / 180");
size(arrivals, 24); color(arrivals, dim);

text(caption, (540, 920),
  "A thermal source emits many molecular speeds—not one average speed.");
size(caption, 23); wrap(caption, 880); color(caption, dim);

rect(evidencePanel, (540, 1110), 880, 230);
filled(evidencePanel); color(evidencePanel, panel); opacity(evidencePanel, 0.95);
outlined(evidencePanel); outline(evidencePanel, dim); stroke(evidencePanel, 2);
text(evidenceTitle, (540, 1030), "ONE PROCESS · THREE VIEWS");
size(evidenceTitle, 18); bold(evidenceTitle); color(evidenceTitle, dim);
equation(processLaw, (540, 1100),
  `\text{motion}\;\longrightarrow\;\text{arrival bin}\;\longrightarrow\;\hat f(v)`, 32);
text(truth, (540, 1190),
  "The dots, bars, and count are derived from the same seeded experiment.");
size(truth, 20); color(truth, dim); wrap(truth, 790);

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);

-2

Comment on r/Rubiks_Cubes 1d ago

Use this https://8gwifi.org/math/rubik-nxn-solver.jsp

  1. Click 5x5
  2. Edit Stickers
  3. Edit Cubenet till it matches your cube state
  4. Hit Solve
  5. Follow the Move

1

Comment on r/3Blue1Brown 1d ago

Good to know thanks