作品はあなた自身を映す鏡。「NATURE OF CODE」に隠された本当の意味について考える

中央の輝くコアから、無数のカラフルな粒子が放射状に広がる様子。クリエイターの「内なる自然(本質)」が、作品として生み出される創造性を象徴したアート。
No.140 Inner Nature - Eyecatch
  • URLをコピーしました!
上記画像のコードを見る(1/3)
(ここをクリックすると以下が開く)

このコードをp5.js Web Editorで試す

/**
 * @title   Inner Nature - Eyecatch(内なる自然 - アイキャッチ)
 * @author  Takuya Watari (watataku) & Gemini
 * @date    2025-08-12
 *
 * @desc
 * 記事「作品はあなた自身を映す鏡」のアイキャッチ画像。
 * 作者の内なる自然(本質)が、創造のコアから無数の粒子となり、
 * 作品として外の世界へ広がっていく様子を一枚のアートとして表現。
 *
 * @license
 * This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
 * http://creativecommons.org/licenses/by-nc-sa/4.0/
 *
 * Takuya Watari
 * Website: https://watataku-artist-katsuyaku.com/
 * X: https://x.com/Watataku_Art
 */

// --- 設定 ---
const particles = [];
const PARTICLE_COUNT = 500; // 静止画なので粒子を少し多めに
let core; // 中心のコア

// --- p5.jsのセットアップ関数 ---
function setup() {
  createCanvas(1600, 900); // アイキャッチ用にサイズを固定
  colorMode(HSB, 360, 100, 100, 100);
  noStroke();

  // 中心のコアを生成
  core = new Core(width / 2, height / 2);

  // 粒子を生成
  for (let i = 0; i < PARTICLE_COUNT; i++) {
    particles.push(new Particle(width / 2, height / 2));
  }
  
  // 静止画として美しい構図にするため、描画前にシミュレーションを少し進める
  for (let i = 0; i < 150; i++) {
    for (let p of particles) {
      p.update();
    }
  }
  
  noLoop(); // アニメーションを停止し、静止画にする
}

// --- p5.jsの描画関数 (noLoop()により一度だけ実行される) ---
function draw() {
  background(240, 50, 10); // 暗めの青紫

  // 中心のコアを描画
  core.display();

  // 全ての粒子を描画
  for (let p of particles) {
    p.display();
  }
  
  // TIPS: この行のコメントを外すと、画像が自動的に保存されます
  // saveCanvas('inner-nature-eyecatch.png');
}

// --- 中心のコアクラス ---
class Core {
  constructor(x, y) {
    this.pos = createVector(x, y);
    this.size = 80; // 静止画なのでサイズは固定
  }

  display() {
    // 複数の円を重ねて、柔らかな光を表現
    for (let i = 10; i > 0; i--) {
      let size = this.size * i * 0.3;
      let alpha = map(i, 10, 0, 0, 8);
      fill(0, 0, 100, alpha);
      ellipse(this.pos.x, this.pos.y, size, size);
    }
    fill(0, 0, 100, 80);
    ellipse(this.pos.x, this.pos.y, this.size, this.size);
  }
}

// --- 粒子のクラス ---
class Particle {
  constructor(x, y) {
    this.pos = createVector(x, y);
    this.vel = p5.Vector.random2D().mult(random(0.5, 3));
    this.lifespan = random(100, 255);
    this.size = random(2, 8);
    this.hue = random(360);
  }

  update() {
    this.pos.add(this.vel);
    this.lifespan -= 1.0; // 静止画なので減りを少し早く
  }

  display() {
    if (this.lifespan > 0) {
      fill(this.hue, 80, 100, this.lifespan / 3);
      ellipse(this.pos.x, this.pos.y, this.size, this.size);
    }
  }  
}
ワタタク

どうもワタタクです、

前回の記事では、クリエイティブコーディングで動きに「生命感」を吹き込むための、自然現象を模倣する技術について探求しました。ボールに重力を与え、粒子を風に揺らがせる。それだけで、無機質なコードがまるで生きているかのように見え始めます。

しかし、一歩立ち止まって考えてみてください。なぜ私たちは、ただの技術解説書ではなく、「The Nature of Code」という本に惹かれるのでしょうか?

そのタイトルに冠された“Nature”という言葉。多くの人はこれを「自然」や「自然現象」と訳すと思います。しかし、この言葉には、あなたの創作活動の根幹を揺るがす、もう一つの、そしてもっと深い意味が隠されていると思いました。

この記事では、”Nature”の本当の意味を解き明かし、あなたのコードが、あなた自身を映し出す「鏡」となるための考え方を探っていきます。

この記事を書いた人
ワタタク
  • クリエイティブコーディングで制作した作品と、上達のためにやったこと・学習過程を発信
  • コンセプトは「クリエイティブコーディング1万時間の歩き方」
  • 2024年にProcessingの構文のアウトプットを終え、2025年から作品制作開始(クリエイティブコーディングで作成した作品集

目次

“NATURE”の二つの顔:模倣すべき「自然」と、表現すべき「本質」

画面の左半分に描かれた森の風景と、右半分に描かれた人のシルエットの中の宇宙。「外的自然」と「内的自然」という、Natureという言葉が持つ二つの意味を対比したイラスト。
No.141 Two Natures(二つの自然)
上記画像のコードを見る(2/3)
(ここをクリックすると以下が開く)

このコードをp5.js Web Editorで試す

/**
 * @title   Two Natures(二つの自然)
 * @author  Takuya Watari (Watataku) & Gemini
 * @date    2025-08-12
 *
 * @desc
 * 記事「作品はあなた自身を映す鏡」の挿絵。
 * 左半分に「外的自然」の象徴として森を、右半分に「内的自然」の
 * 象徴として人の内なる宇宙を描き、"Nature"の二面性を表現する。
 *
 * @license
 * This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
 * http://creativecommons.org/licenses/by-nc-sa/4.0/
 */

function setup() {
  createCanvas(1600, 900);
  colorMode(HSB, 360, 100, 100, 100);
  noStroke();
  noLoop(); // 静止画なのでアニメーションは停止
}

function draw() {
  // --- 左半分:外的自然(森) ---
  drawForest();

  // --- 右半分:内的自然(内なる宇宙) ---
  drawInnerCosmos();

  // 中央に分割線
  stroke(0, 0, 80, 50);
  strokeWeight(2);
  line(width / 2, 0, width / 2, height);
}

// --- 森を描画する関数 ---
function drawForest() {
  // 空のグラデーション
  for (let y = 0; y < height; y++) {
    let inter = map(y, 0, height, 0, 1);
    let c = lerpColor(color(190, 40, 90), color(210, 30, 100), inter);
    stroke(c);
    line(0, y, width / 2, y);
  }
  noStroke();

  // パーリンノイズで木々を生成
  for (let i = 0; i < 200; i++) {
    let x = random(-50, width / 2 - 50);
    let y = height - random(height * 0.3);
    let treeHeight = random(50, 200);
    let treeWidth = random(20, 40);
    let hue = random(90, 140);

    // 幹
    fill(30, 60, 40);
    rect(x, y, treeWidth, height - y);

    // 葉
    for (let j = 0; j < 50; j++) {
      let px = x + treeWidth / 2 + random(-treeWidth * 2, treeWidth * 2);
      let py = y - random(treeHeight);
      fill(hue, random(50, 80), random(60, 90), 80);
      ellipse(px, py, random(10, 30));
    }
  }
}


// --- 内なる宇宙を描画する関数 ---
function drawInnerCosmos() {
  // 背景
  fill(240, 70, 15);
  rect(width / 2, 0, width / 2, height);

  // 星
  for (let i = 0; i < 500; i++) {
    let x = random(width / 2, width);
    let y = random(height);
    let size = random(0.5, 2.5);
    fill(0, 0, 100, random(50, 100));
    ellipse(x, y, size, size);
  }

  // 人のシルエット
  // noStroke()とfill()で図形を描画することでシルエットを作成
  noStroke();
  fill(0, 0, 0, 80); // 半透明の黒
  
  // beginShape()とendShape()で複雑な形を描く
  beginShape();
  // 横顔の輪郭を頂点(vertex)で指定していく
  vertex(width, 0); // 右上から開始
  vertex(width, height); // 右下へ
  vertex(width * 0.75, height); // 左下へ
  // 以下、横顔のシルエットを形成する座標
  curveVertex(1150, 800);
  curveVertex(1100, 700);
  curveVertex(1120, 600); // あご
  curveVertex(1100, 500); // 口
  curveVertex(1200, 450); // 鼻
  curveVertex(1150, 350); // 眉
  curveVertex(1250, 250); // 額
  curveVertex(1350, 100);
  curveVertex(width, 0); // 右上に戻る
  endShape(CLOSE);
}

英語の”Nature”という単語は、大きく分けて二つの意味を持っています。

  1. 外的自然 (External Nature): 私たちが普段目にする、物理的な自然界、自然現象のこと。前回の記事で書いた「重力」や「風」はこちらに含まれます。
  2. 内的自然 (Internal Nature): その人や物が元々持っている、本質、天性、性質のこと。日本語で言う「人間性」や「個性」に近い概念です。

クリエイティブコーディングの名著が”Nature”という言葉を選んだのは、偶然ではあないと思うんです。このタイトルは私たちに、「①自然界の法則(External Nature)を学び、模倣しなさい。しかし、最終的にあなたが表現すべきは、あなた自身の内なる自然(Internal Nature)なのですよ」という、深遠なメッセージを伝えているのではないでしょうか?

つまり、p5.jsのnoise()関数を使って木々の揺らめきを再現するのは、あくまでスタート地点。その揺らめきを通して、あなたが表現したい「穏やかな感情」や「心のざわめき」こそが、作品の本当の核となるべきなのです。

作品は人なり:コードという鏡に映る、あなたの「本質」

人のシルエットが円形の鏡を覗き込むと、自身の顔ではなく、流れるような美しいジェネラティブアートが映っている。作品が作者の内面を映し出す「創造の鏡」を象徴したイラスト。
No.142 The Mirror of Creation – Animated(創造の鏡 – アニメーション)
上記画像のコードを見る(3/3)
(ここをクリックすると以下が開く)

このコードをp5.js Web Editorで試す

/**
 * @title   The Mirror of Creation - Animated(創造の鏡 - アニメーション)
 * @author  Takuya Watari (Watataku) & Gemini
 * @date    2025-08-12
 *
 * @desc
 * 人が鏡を覗き込むと、そこに映るのは自らの顔ではなく、
 * 内面から溢れ出す創造性そのものである、という比喩を表現した。
 *
 * @license
 * This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
 * http://creativecommons.org/licenses/by-nc-sa/4.0/
 */

// --- 設定 ---
const particles = [];
const PARTICLE_COUNT = 2000; // アニメーションなので少し減らす
let flowfield;
const GRID_SCALE = 20;

// --- p5.jsのセットアップ関数 ---
function setup() {
  createCanvas(windowWidth, windowHeight); // ウィンドウサイズに合わせる
  colorMode(HSB, 360, 100, 100, 100);

  flowfield = new Array(floor(width / GRID_SCALE) * floor(height / GRID_SCALE));
  calculateFlowField();

  for (let i = 0; i < PARTICLE_COUNT; i++) {
    particles[i] = new Particle();
  }
}

// --- p5.jsの描画関数 ---
function draw() {
  background(240, 30, 10); // 背景色

  // 最初に「鏡に映る模様」となる粒子を更新し、描画する
  for (let p of particles) {
    p.follow(flowfield);
    p.update();
    p.show();
    p.edges();
  }

  // 次に、上から「シルエットの枠」をかぶせる
  drawFrameAndSilhouette();
}

// --- シルエットとくり抜かれた鏡の枠を描画する関数 ---
function drawFrameAndSilhouette() {
  fill(0, 0, 10); // シルエットの色(ほぼ黒)
  noStroke();

  // beginShape()で複雑な図形を描き始める
  beginShape();

  // 外側の四角形(画面全体)の頂点を指定
  vertex(0, 0);
  vertex(width, 0);
  vertex(width, height);
  vertex(0, height);

  // beginContour()で、図形の内側に「穴」を開け始める
  // これがp5.jsで図形をくり抜くための正式な方法です
  beginContour();
  // 鏡の円形の穴を、外側とは逆の順序(反時計回り)で指定
  let mirrorX = width * 0.65;
  let mirrorY = height / 2;
  let mirrorDiameter = height * 0.7;
  for (let i = 360; i > 0; i--) {
    let angle = radians(i);
    let x = mirrorX + cos(angle) * (mirrorDiameter / 2);
    let y = mirrorY + sin(angle) * (mirrorDiameter / 2);
    vertex(x, y);
  }
  endContour(); // 穴あけ終了

  endShape(CLOSE); // 図形描画終了

  // 人のシルエット部分を上から描画して、枠と一体化させる
  beginShape();
  vertex(0, 0);
  vertex(width * 0.5, 0);
  curveVertex(550, 200);
  curveVertex(480, 350); // 頭
  curveVertex(500, 500); // 肩
  curveVertex(450, 700);
  vertex(width * 0.4, height);
  vertex(0, height);
  endShape(CLOSE);
}


// --- 流れの地図(Flow Field)を計算する関数 ---
function calculateFlowField() {
  let yoff = 100;
  for (let y = 0; y < height; y += GRID_SCALE) {
    let xoff = 0;
    for (let x = 0; x < width; x += GRID_SCALE) {
      let angle = noise(xoff, yoff, frameCount * 0.0005) * TWO_PI * 4;
      let v = p5.Vector.fromAngle(angle);
      v.setMag(1);
      let index = floor(x / GRID_SCALE) + floor(y / GRID_SCALE) * floor(width / GRID_SCALE);
      flowfield[index] = v;
      xoff += 0.05;
    }
    yoff += 0.05;
  }
}

// --- 粒子クラス ---
class Particle {
  constructor() {
    this.pos = createVector(random(width), random(height));
    this.vel = createVector();
    this.acc = createVector();
    this.maxSpeed = 2;
    this.hue = random(180, 300);
    this.prevPos = this.pos.copy();
  }

  update() {
    this.vel.add(this.acc);
    this.vel.limit(this.maxSpeed);
    this.pos.add(this.vel);
    this.acc.mult(0);
  }

  show() {
    stroke(this.hue, 80, 100, 50);
    strokeWeight(1.5);
    line(this.pos.x, this.pos.y, this.prevPos.x, this.prevPos.y);
    this.updatePrev();
  }
  
  updatePrev() {
    this.prevPos.x = this.pos.x;
    this.prevPos.y = this.pos.y;
  }

  edges() {
    if (this.pos.x > width) {
      this.pos.x = 0;
      this.updatePrev();
    }
    if (this.pos.x < 0) {
      this.pos.x = width;
      this.updatePrev();
    }
    if (this.pos.y > height) {
      this.pos.y = 0;
      this.updatePrev();
    }
    if (this.pos.y < 0) {
      this.pos.y = height;
      this.updatePrev();
    }
  }

  follow(vectors) {
    let x = floor(this.pos.x / GRID_SCALE);
    let y = floor(this.pos.y / GRID_SCALE);
    let index = x + y * floor(width / GRID_SCALE);
    let force = vectors[index];
    if (force) this.applyForce(force);
  }

  applyForce(force) {
    this.acc.add(force);
  }
}

// --- ウィンドウサイズが変わった時の処理 ---
function windowResized() {
    resizeCanvas(windowWidth, windowHeight);
}

「作品はその人自身で、作品にはその人の本質が出る。」これは、僕が思っている創作における考え方です。人の振る舞いや雰囲気を嫌いな人は作品も嫌いになりやすいと思っています。

例えば、どれだけ素晴らしい作品だとしても、その人がわざと人に嫌がらせをたくさんしている人だった場合、僕はその人の作品を好きにはなれない。

僕達が書くコードの一つ一つは、単なる命令の羅列ではありません。

  • どんな色を選ぶか?
  • どんな動きを心地よいと感じるか?
  • どんなテーマに心惹かれるか?

そこに、あなたの美的感覚、価値観、そしてこれまでの人生で培われた「あなたらしさ」が色濃く反映される。

僕が音楽で人に感動してもらおうとしたとき、音程を意識した演奏よりも、僕自身の感情の「ゆらぎ」が人の心を動かしたように、あなたのコードもまた、あなた自身の「内なる自然」を奏でる楽器だと思う。

考えてみてください。同じ「雨」というお題でも、穏やかな性格の人が作れば優しい春の雨になり、情熱的な人が作れば激しい夏のスコールになるかもしれません。コードは、作者の意図を超えて、その人となりを映し出す正直な鏡なのです。

あなたの創作スタイルは?「職人」か、それとも「表現者」か

あなたの「本質」は、最終的なアウトプットだけでなく、創作のプロセス、つまり創作スタイルにも現れます。

  • AIを使わず、一つ一つネットで調べてコードを書くスタイル: これは、「職人」タイプと言えるかもしれません。プロセスの一つ一つを自分の手で確認し、試行錯誤を繰り返す。その手間や時間そのものに価値を見出し、コードの隅々にまで自分のこだわりを宿らせたいという「誠実さ」や「探究心」という本質が表れています。
  • AIを共創パートナーとして、積極的に活用するスタイル: こちらは、「表現者」あるいは「起業家」タイプに近いかと。アイデアを形にすることを最優先し、最新のツールを合理的に使いこなす。自分の創造性を最大化するためには、何が最も効率的かを考える「柔軟性」や「目的志向」という本質が反映されています。

どちらが優れているという話ではないんです。大切なのは、自分がどちらのスタイルに心地よさを感じるかを知り、そのスタイルを通して自分の”Nature”を表現することです。

ワタタク

僕はAIを共創のパートナーとして、創作のサポートをしてもらえる存在としてめっちゃ使っています。

あなただけの”Nature”を見つける旅へ

「The Nature of Code」が教えてくれる本当の教え。それは、自然現象という外なる法則を学ぶだけでなく、それを触媒として、あなた自身の内なる声に耳を傾け、自分だけの「本質」を探求しなさい、ということを記事にしてみました。

あなたが書いたコードを見て、誰かが「これは、あなたの作品だね」と一目で分かるようになった時。その時、あなたのコードは単なるプログラムではなく、あなた自身の分身として、本当の生命を宿すことになるでしょう。

さあ、あなたの鏡には、今どんな「あなた」が映っていますか?

ワタタク

それでは今日もレッツワクワクコーディング。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次