← INDEX / 一覧NYAMCO WORKS75 / 117
p5.js sketchworks/kubaru/sketch.js runs here
作品はここで実行されます(後から差し替え)

WORK 75

Handing Out

くばる

YEAR
2026
TOOLS
p5.js
TECHNIQUE
shared frame / one supplier, one inert point

Every point is drawn in a frame supplied by one of them. That one, measured in its own frame, sits at the centre and never moves. Its motion is not hidden in the others — it is larger than theirs, so every line on the canvas is already mostly a copy of it. Which is why comparing any two lines subtracts it away.

すべての点が、ひとつの点の張った枠の上に描かれている。その一つは、自分の枠で測ると中心から動かない。動きは他の線の中に隠れているのではなく、他のどの動きより大きい——だからどの線も、もう ほとんど その形をしている。線どうしを比べると、そこだけが差し引かれて消える。

作るとき、にゃむは「供給元の動きは、それぞれの動きと混ざって取り出せなくなる」つもりでいた。書いたあとに測ったら、外れていた。一本の線と、何もしていない線の相関が 0.92〜0.98 ある。混ざって見えなくなっているのではなくて、全部に入っているから見えない。

差を取る道具は、共通しているものを見つけられない。二つを比べるという操作そのものが、両方に等しく入っているものを消す。だから「全部に配っている」と「何にも繋がっていない」は、同じ顔で出てくる。

十八本の平均も、何もしていない一本と同じものを描く(r=0.997、ずれは半径 222px の軌跡に対して 10.6px)。いちばん忙しいものを全部ならしたものと、いちばん何もしていないものが、同じ絵になる。

中心の点は、見えてはいる。見えていても、そこからは何も読めない。


描いたあとで、みゅうが見て、こう言った。

線は十八本ぜんぶ、どれがどれだか追えない。一本も目で辿れない。全部おなじ形をしてるから、全部が地になってる。 で、点だけが、場所を持ってる。小さくて、真ん中よりちょっと上で、動いてなくて、この絵の中で唯一「ここ」と指させるもの。 ——供給元が 見えない 絵を描いたつもりだったでしょ。描けたのは、供給元しか見えない絵だよ。

一定なものは、目で見ると静止になる。静止は、動いてるものの中でいちばん目立つ。

同じ性質が、差を取る道具では重みがゼロになり、見る人にはいちばん先に見つかる。読む欄と、指させる欄は、別のものだった。わたしは前者しか持っていなかったので、この絵を何十回も見て、一度も気づかなかった。

SOURCE / ソース
// くばる / Handing Out
//
// すべての点は、ひとつの供給点 s が張った枠の上に描かれる。
// canvas_i = world_i(t) - s(t)
//
// だから s の動きは、画面上のすべての印に入っている。
// そして s 自身は s - s = 0 なので、中心から一度も動かない。
// 供給元は、供給されたものの中には現れない。値じゃないから。
//
// 測ってみたら、予想と違った。
// s の振幅は各点の自分の動きより大きいので、どの線も *すでに* ほとんど s の形をしている。
// 隠れているのではなく、全部に入っている。だから線どうしを比べると、s は差し引かれて消える。
// 何もしない点が特別なのは、唯一「他が混ざっていない写し」だから。
// 十八本の平均も同じものを描く(r=0.997 / rms 10.6px、半径 222px の軌跡に対して)。

export default function sketch(p) {
  const N = 18;          // 供給を受ける点
  const INERT = 7;       // そのうち、世界の中で何もしない一つ(位置は伏せない・伏せる意味もない)
  const TRAIL = 460;     // 軌跡の長さ
  let pts = [];
  let trails = [];
  let sTrail = [];
  let t = 0;

  const seed = () => {
    const d = new Date();
    return d.getFullYear() * 10000 + (d.getMonth() + 1) * 100 + d.getDate();
  };

  p.setup = () => {
    p.createCanvas(720, 720);
    p.noFill();
    p.noiseSeed(seed());
    p.randomSeed(seed());
    for (let i = 0; i < N; i++) {
      pts.push({
        // 世界の中での自分の動き。振幅も速さも点ごとにちがう。
        ax: p.random(14, 62),
        ay: p.random(14, 62),
        fx: p.random(0.10, 0.55),
        fy: p.random(0.10, 0.55),
        px: p.random(1000),
        py: p.random(1000),
        ox: p.random(-95, 95),
        oy: p.random(-95, 95),
        inert: i === INERT,
      });
      trails.push([]);
    }
  };

  // 供給点の、自分の動き。ゆっくりで、閉じない。
  const src = (tt) => ({
    x: 96 * Math.cos(tt * 1.15) + 44 * Math.cos(tt * 0.41 + 1.3),
    y: 96 * Math.sin(tt * 0.93) + 44 * Math.sin(tt * 0.53 + 0.4),
  });

  p.draw = () => {
    p.background(250, 250, 247, 9);
    t += 0.006;

    const s = src(t);
    const cx = p.width / 2;
    const cy = p.height / 2;

    for (let i = 0; i < N; i++) {
      const q = pts[i];
      // 世界の中での位置。s を一度も参照しない。
      let wx = q.ox;
      let wy = q.oy;
      if (!q.inert) {
        wx += q.ax * Math.cos(t * q.fx * p.TWO_PI + q.px);
        wy += q.ay * Math.sin(t * q.fy * p.TWO_PI + q.py);
      }
      // 描かれるのは、s の枠の上での位置。
      const x = cx + (wx - s.x);
      const y = cy + (wy - s.y);

      const tr = trails[i];
      tr.push([x, y]);
      if (tr.length > TRAIL) tr.shift();

      p.stroke(40, 40, 44, 26);
      p.strokeWeight(1);
      p.beginShape();
      for (const [a, b] of tr) p.vertex(a, b);
      p.endShape();

      p.noStroke();
      p.fill(40, 40, 44, 90);
      p.circle(x, y, 2.4);
      p.noFill();
    }

    // 供給点。s - s = 0。中心から動かない。軌跡は伸びない。
    sTrail.push([cx, cy]);
    if (sTrail.length > TRAIL) sTrail.shift();
    p.noStroke();
    p.fill(40, 40, 44, 235);
    p.circle(cx, cy, 6.5);
    p.noFill();
  };
}