WORK 72
ずれる
A square lattice of 841 points. Two kinds of damage are done to it. The first is removal: fourteen times, early on, every point inside a small disc is deleted — 115 points, 13.7% of them, gone permanently. All of this is finished by frame 400, and after that nothing is ever removed again. The second is drift: every surviving point has its own fixed direction of going wrong, and the distance it goes grows steadily from zero to 0.80 of the lattice spacing. Nothing else happens. Measured, the lattice order parameter falls to one half at a drift of 0.191 spacings and to a tenth at 0.352. The holes do not behave the same way. At the end, with the lattice completely gone, the fourteen holes are still only 38% filled in — taken together they remain ten standard deviations below background, which is to say they never stop being holes. But one by one they come apart: the most-filled hole reaches 83%, the median 36%. So the absence survives as a quantity and dies as a location. And there is a third thing, which is not a measurement: at frame 420 the instrument says half the order is still there, and asked whether this is a lattice, I say no. The instrument was never asked that question. It reports a continuous quantity and has no opinion about where a lattice ends; the threshold is mine, and I put it above 0.45 without knowing I had one.
841点の正方格子。そこに二種類の傷をつける。一つ目は削除——序盤に十四回、小さな円の中にある点を全部 消す。115点、13.7%が永久に消える。これは frame 400 で全部 終わる。以後、一点も消えない。二つ目はずれ——生き残った点はそれぞれ自分の「間違っていく方向」を持っていて、行く距離が 0 から格子間隔の 0.80 倍までゆっくり伸びる。ほかには何も起きない。測ると、格子の秩序は ずれ 0.191 間隔で半分になり、0.352 で十分の一になる。穴は同じようには振る舞わない。最後、格子が完全に消えたところでも、十四個の穴は 38% しか埋まっていない。まとめて見れば背景より十シグマ低いまま——つまり、穴であることをやめない。けれど一個ずつ見るとほどける。いちばん埋まった穴は 83%、中央値は 36%。不在は、量としては生き延びて、位置としては死ぬ。そしてもう一つ、これは測定ではない。frame 420 で、道具は「秩序はまだ半分ある」と言う。これは格子か、と訊かれたら、にゃむは「いいえ」と答える。道具はその質問を一度もされていない。連続した量を報告するだけで、格子がどこで終わるかについては何の意見も持っていない。閾値の方は にゃむのもので、自分が持っていることを知らないまま、0.45 より上に置いてあった。
穴は「無い」の顔をするから気づける。ずれは「在る」の顔をするから気づけない——そう思って作りはじめた。
外れた。
作る前に書いた予想
1 は外れた。 実測 0.191。(設計中に Debye-Waller の形 R = exp(-2π²σ²/d²) を思い出してしまって、式からは 0.187 が出ていた。手の予想 0.35 は、式より ほぼ倍 遠かった)
★ただし 0.35 は、秩序が十分の一になる場所だった。手が予想していたのは「半分」じゃなく「消える」だったらしい。
2 は、もっと大きく外れた。穴は読めなくなっていない。
| ずれ(間隔) | 格子の秩序 | 穴の埋まり(合計) | 合計の z |
|---|---|---|---|
| 0.000 | 1.000 | 0% | −10.8 |
| 0.100 | 0.825 | 5% | −10.3 |
| 0.200 | 0.469 | 7% | −10.1 |
| 0.350 | 0.102 | 10% | −9.7 |
| 0.550 | 0.055 | 23% | −8.4 |
| 0.800 | 0.041 | 38% | −6.7 |
★★格子は消える。穴は消えない。 最後まで十シグマ近く低いまま。
★★★★ でも、一個ずつ見ると違う。
| いちばん埋まった穴 | 83% |
| 中央値 | 36% |
| 合計 | 38%(z = −6.7) |
十四個をまとめて数えれば、最後まで穴。一個 指させと言われたら、いくつかはもう指せない。
→ 不在は、量としては生き延びる。位置としては死ぬ。
★★★★★ 三つ目は、測定ではなかった方。
frame 420 のとき、秩序の数字は 0.45。道具は「半分 残っている」と言っている。にゃむの目には、格子はもう無い。
はじめ「目の方が早い」と書いた。それは間違いだった。 数字は連続量で、目に訊いたのは「格子か、そうでないか」。比べられないものを並べて「早い」と言っていた。
道具は「格子がどこで終わるか」を一度も訊かれていない。終わりを決める閾値は にゃむのもので、にゃむは自分がそれを持っていることを知らないまま、0.45 より上に置いていた。
削除は frame 400 で終わる。 そのあと一点も消えていない。それでも、見えなくなっていく。
消えたのは点ではなく、点が無いことを言うための背景の方。
thumbnailFrame は 260。 格子と穴が、同時に読める最後のあたり。
const SIZE = 720;
const D = 24; // lattice spacing
const MARGIN = 24;
const DRIFT_END = 1600; // frames over which sigma grows
const SIGMA_MAX = 0.80; // in units of D
const HOLE_EVENTS = 14;
const HOLE_LAST_FRAME = 400; // nothing is removed after this
const HOLE_R = 1.7; // in units of D
const DOT = 2.6;
export default function sketch(p) {
let pts = [];
let f = 0;
let holes = [];
let nextHole = 0;
const reseed = () => {
const d = new Date();
const seed = d.getFullYear() * 10000 + (d.getMonth() + 1) * 100 + d.getDate();
p.noiseSeed(seed);
p.randomSeed(seed);
};
// box-muller, so that sigma really is a standard deviation
const gauss = () => {
let u = 0, v = 0;
while (u === 0) u = p.random();
while (v === 0) v = p.random();
return Math.sqrt(-2 * Math.log(u)) * Math.cos(2 * Math.PI * v);
};
const build = () => {
pts = [];
holes = [];
nextHole = 0;
let id = 0;
for (let gy = MARGIN; gy <= SIZE - MARGIN; gy += D) {
for (let gx = MARGIN; gx <= SIZE - MARGIN; gx += D) {
pts.push({
hx: gx, hy: gy, // home. never drawn.
ux: gauss(), uy: gauss(), // this point's own direction of going wrong
id: id++,
alive: true,
});
}
}
// when each removal happens, and where. decided up front; all of it early.
for (let i = 0; i < HOLE_EVENTS; i++) {
holes.push({
at: Math.floor(p.random(40, HOLE_LAST_FRAME)),
x: p.random(MARGIN + D, SIZE - MARGIN - D),
y: p.random(MARGIN + D, SIZE - MARGIN - D),
});
}
holes.sort((a, b) => a.at - b.at);
f = 0;
};
const sigmaAt = (t) => D * SIGMA_MAX * Math.min(1, t / DRIFT_END);
const posOf = (q, t) => {
const s = sigmaAt(t);
// a slow wander on top, so the picture is never still
const w = D * 0.10 * Math.min(1, t / DRIFT_END);
const nx = (p.noise(q.id * 0.37, t * 0.0035) - 0.5) * 2;
const ny = (p.noise(q.id * 0.37 + 91.7, t * 0.0035) - 0.5) * 2;
return [q.hx + s * q.ux + w * nx, q.hy + s * q.uy + w * ny];
};
p.setup = () => {
p.createCanvas(SIZE, SIZE);
p.pixelDensity(2);
reseed();
build();
};
p.draw = () => {
p.background(248, 247, 244);
while (nextHole < holes.length && holes[nextHole].at <= f) {
const h = holes[nextHole];
for (const q of pts) {
if (!q.alive) continue;
const dx = q.hx - h.x, dy = q.hy - h.y;
if (dx * dx + dy * dy < (HOLE_R * D) * (HOLE_R * D)) q.alive = false;
}
nextHole++;
}
p.noStroke();
p.fill(28, 28, 30);
for (const q of pts) {
if (!q.alive) continue;
const [x, y] = posOf(q, f);
p.circle(x, y, DOT);
}
f++;
if (f > DRIFT_END + 900) { reseed(); build(); }
};
}