DEFINITION
T(x) = Σ wⁿ s(2ⁿ x) s(x) = distance from x to the nearest integer w = ½ is the blancmange
NOTES
Takagi’s simpler route to Weierstrass’s scandal, published as "a simple example of the continuous function without derivative": stack tent maps, each twice the frequency and a fraction of the height of the last. At w = ½ the sum is the blancmange curve, named for the pudding; the weight slides the family from nearly-smooth toward a jagged ridge, and the plate builds it a term at a time because the construction is the exhibit.
PROVENANCE
- Origin
- T. Takagi, "A simple example of the continuous function without derivative", Tokyo Sugaku-Butsurigakkwai Hokoku (Proc. Phys.-Math. Soc. Japan) 1, F176–F177 — the volume is dated 1901 and the paper is just as often cited as 1903; the w ≠ ½ family is Takagi–Landsberg, after G. Landsberg, Jahresber. Deutsch. Math.-Verein. 17 (1908), 46–51
- Standing
- Public domain — early 20th-century analysis
- Constants
- Term count is resolution-bound, as on PL. 69: each term doubles in frequency, and past the pixel grid there is nothing left to draw
HOUDINI · VEX
The same published mathematics as a Detail Wrangle body. Paste it into a Wrangle with Run Over set to Detail; every constant is the published value plus a tweak channel, so Create Spare Parameters gives a slider that starts where the paper does.
// FORMA — PL. 70 · TAKAGI CURVE — Teiji Takagi, 1901
// T(x) = Σ wⁿ s(2ⁿ x)
// s(x) = distance from x to the nearest integer
// w = ½ is the blancmange
// Paste into a Detail Wrangle (Run Over: Detail), no inputs needed.
// Written from the published mathematics, not adapted from any code.
// Constants arrive at their published values. Press the node's Create
// Spare Parameters button and every tweak becomes a slider — starting
// at 0, the published figure, and moving in the constant's own units.
// https://forma-gen.com/#plate=takagi
float p_w = 0.5 + chf('w_tweak'); // w — term weight · live 0.4 .. 0.8
// The plate's own colour: FORMA's CURVES accent as a cosine ramp,
// brightest near t = 0 and t = 1, near-black around t = 0.5.
vector forma_ramp(float t){
return set(
0.11 + 0.1196 * cos(6.28318530718 * (t + 0)),
0.46 + 0.5 * cos(6.28318530718 * (t + 0.05)),
0.2453 + 0.2667 * cos(6.28318530718 * (t + 0.1)));
}
// The blancmange at full depth: ten tent-map terms, which is the sample
// floor — 2¹⁰ oscillations across 1400 samples is where the top term stops
// rendering as shape. The plate reveals the terms one by one; the geometry
// is the finished pathology.
int forma_n = 1400;
int forma_top = 10;
// peak of Σ wⁿ·s(2ⁿx) is bounded by Σ wⁿ/2; normalising keeps every weight
// on the same baseline
float norm = (1.0 - pow(p_w, forma_top)) / (1.0 - p_w) * 0.5;
int prim = addprim(0, "polyline");
for (int i = 0; i <= forma_n; i++){
float x = float(i) / float(forma_n);
float y = 0.0;
for (int k = 0; k < forma_top; k++){
float sx = x * pow(2.0, k); // VEX has no shift operator
y += pow(p_w, k) * abs(sx - rint(sx));
}
// the graph is drawn y-up already; no flip needed
int pt = addpoint(0, set(x, y / norm, 0.0));
// colour sweeps the bright lobe of the ramp along the graph
float u = float(i) / float(forma_n);
setpointattrib(0, "Cd", pt, forma_ramp(0.8 + 0.3 * u));
addvertex(0, prim, pt);
}
AFTER EFFECTS · EXPRESSION
The same published mathematics as a Shape Layer path expression. Paste it onto a Path property; every constant is the published value plus a Slider Control named
// FORMA — PL. 70 · TAKAGI CURVE — Teiji Takagi, 1901
// T(x) = Σ wⁿ s(2ⁿ x)
// s(x) = distance from x to the nearest integer
// w = ½ is the blancmange
// After Effects port — paste onto a Shape Layer's Path property
// (Contents › Shape › Path). Written from the published mathematics, not
// adapted from any code. Constants arrive at their published values; add a
// Slider Control (Effect › Expression Controls) named <k>_tweak and that
// constant moves in its own units, starting at 0 — the published figure.
// The plate's comet and its reveal are Trim Paths; the stroke colour is
// FORMA's CURVES accent, #3DFF88. Animation runs on time.
// https://forma-gen.com/#plate=takagi
// A missing slider reads 0, so a bare paste already draws the figure.
function forma_tweak(n){ try { return effect(n)("Slider"); } catch (e){ return 0; } }
var p_w = 0.5 + forma_tweak("w_tweak"); // w — term weight · live 0.4 .. 0.8
// The frame: the plate's W × H canvas is this comp, with the origin at the
// layer's anchor; canvas y already runs down, as After Effects' does.
var forma_W = thisComp.width, forma_H = thisComp.height, forma_t = time;
var forma_phase = 0.5039210487157106; // this plate's own fixed phase, as the page has it
function forma_pt(x, y){ return [x - forma_W / 2, y - forma_H / 2]; }
// The Takagi (blancmange) curve: Σ wᵏ·tent(2ᵏx) with tent(x) the distance to
// the nearest integer, ten terms — the sample floor for 1,400 points — and
// normalised so the graph fills 0.68 of the height. The page adds the terms
// one at a time over 12 s; this is the finished curve.
var N = 1400, TOP = 10;
function forma_tent(x){ return Math.abs(x - Math.round(x)); }
var norm = (1 - Math.pow(p_w, TOP)) / (1 - p_w) * 0.5;
var pts = [];
for (var i = 0; i <= N; i++){
var x = i / N, y = 0;
for (var k = 0; k < TOP; k++) y += Math.pow(p_w, k) * forma_tent(x * (1 << k));
pts.push(forma_pt(forma_W * (0.05 + 0.9 * x), forma_H * 0.86 - (y / norm) * forma_H * 0.68));
}
createPath(pts, [], [], false);