【p5.js】三角形の「張力とベクトル」を光で描く!コード実装を徹底解説【WSN : L-019】

p5.jsで描画した三角形のジェネレーティブアート。暗いグリッド背景の中央に、黄色の光の層が重なる鋭角の三角形と、重心から上部の頂点へ向かって伸びる赤いベクトル線が描かれている。
  • URLをコピーしました!
今回の記事の目的
  • 三角形が持つ「3つの頂点の張力」「鋭い方向性(ベクトル)」「光のプリズム・閃光(イッテン的色彩論の黄色)」を、p5.jsのプログラムとして画面上に可視化する。
  • 極座標(cos / sin)とベクトル演算を使って、静止画ではなく「呼吸するように微動しながら方向性を生み出すダイナミズム」を実装する。
  • 手描き作図のためのコードの対応関係を理解し、あらゆるプログラミング言語に応用できる純粋な幾何学アルゴリズムを身につける。
ワタタク

どうもクリエイティブコーダーのワタタクです。

『【三角形ってなに?】ピラミッドからスマホの再生ボタンまで!世界に「動き」と「力」を生むいちばん強い形』で、詳しく書いたのですが、私たちが普段目にする三角形には、建築を支える「圧倒的な構造の強さ」と、再生ボタン(▶)や道路標識のように人の視線を特定の方向へ突き動かす「鋭い矢印(ベクトル)」という2つの顔があります。また、バウハウスのヨハネス・イッテンは、この三角形に最も明るく鋭利な原色である「黄色(閃光・ひらめき)」を割り当てました。

今回は、この「三角形の張力と光のエネルギー」を、p5.jsのクリエイティブコーディングによって画面上で表現していきます。単に三角形を1つ描くだけでなく、空間を切り裂く無限の補助線や、重心から突き抜ける推進力ベクトル、さらには紙とペンで行うアナログ作図とのつながりまで、実践コード付きでじっくり解説します。

この記事を書いた人

クリエイティブコーダー Watataku のプロフィール写真
ワタタク(Watataku)

クリエイティブコーダー

「才能」ではなく「発見」で描く。文系・36歳からの上達ログ。

  • ゼロから独学でクリエイティブコーディングに挑戦し、以下の実績を達成
    • 開始1年8ヶ月目までに公募6つに挑戦し、3つ入選(勝率50%)
      • KITTE大阪の18メートルあるAxCROSS大型スクリーン
      • 虎ノ門ヒルズステーションタワーB2F TOKYO NODE エントランスサイネージで展示
      • UN:O(東京大手町)にある会員限定のサテライトオフィスにて2作品選出・常設展示
  • 開始1年9ヶ月目に、虎ノ門ヒルズ49階、地上250mのインフィニティプールへ作品提供・展示
目次

今回のコードの目的と表現の設計

今回作成するスケッチでは、以下の4つの要素をレイヤー(層)として重ね合わせることで、三角形の本質を表現します。

  1. 静謐なグリッド背景(正方形の秩序): 水平と垂直のラインを薄く敷き、三角形の「斜めのダイナミズム」を際立たせます。
  2. 光のプリズム(残像レイヤー): イッテンが三角形に割り当てた「黄色」を使い、輪郭が波紋のように広がる閃光を描きます。
  3. 空間を切り裂く無限の補助線: 三角形の3辺を画面の端まで延長し、3つの頂点が張り詰めた弦のように空間を緊張させる様子を可視化します。
  4. 推進力ベクトル(赤い矢印): 3つの頂点のうち1つだけを遠くへ突き出させ、重心からその頂点へ向かう「矢印(方向性)」を強調します。

さらに、p5.js web editorで表示された画面をクリックしてキーボードの s キー を押した瞬間に、1600×900ピクセルの高解像度PNG画像としてそのまま保存できる機能も組み込んでいます。

p5.js コード(1600×900・sキー保存対応)

p5.jsで描画した三角形のジェネレーティブアート。暗いグリッド背景の中央に、黄色の光の層が重なる鋭角の三角形と、重心から上部の頂点へ向かって伸びる赤いベクトル線が描かれている。
/**
 * 【三角形ってなに?】世界に「動き」と「力」を生むいちばん強い形
 * - 3つの頂点が張り詰めた張力で結ばれ、鋭いベクトル(方向性)と閃光を生む表現
 * - キーボードの 's' を押すと 1600x900 のPNG画像として保存されます
 */

let vertices = [];
let baseAngles = [];
let t = 0;

function setup() {
  // 高解像度(1600x900)のキャンバスを作成
  createCanvas(1600, 900);
  pixelDensity(1); // 保存時に正確な1600x900ピクセルにするための設定

  // 正三角形をベースにした3つの位相
  baseAngles = [-PI / 2, PI / 6, (5 * PI) / 6];

  // 3つの頂点の初期データを作成
  for (let i = 0; i < 3; i++) {
    vertices.push({
      pos: createVector(0, 0),
      radius: 260,
      speed: 0.015 + i * 0.004,
      offset: i * 2.0
    });
  }
}

function draw() {
  // 深い漆黒の背景(静謐な展示空間の秩序)
  background(12, 14, 18);

  // 背景にうっすらと水平・垂直のグリッド(静かな秩序・正方形の対比)を描く
  drawBackgroundGrid();

  // 画面の中心を基準にする
  translate(width / 2, height / 2);

  // 3つの頂点の位置を計算(張り詰めた弦のように微細に揺れ動く)
  for (let i = 0; i < 3; i++) {
    let v = vertices[i];
    // 1つ目の頂点(index 0)だけ少し遠くへ突き出させ、「矢印(方向性)」を強調する
    let stretch = (i === 0) ? 1.35 + sin(t * 1.5) * 0.15 : 1.0 + cos(t + v.offset) * 0.12;
    let angle = baseAngles[i] + sin(t * 0.8 + v.offset) * 0.12;

    v.pos.x = cos(angle) * v.radius * stretch;
    v.pos.y = sin(angle) * v.radius * stretch;
  }

  // 1. 空間を切り裂く「光のプリズム(三角形の残像レイヤー)」を描く
  noFill();
  for (let layer = 12; layer > 0; layer--) {
    let scaleRatio = 1 + layer * 0.045;
    let alpha = map(layer, 1, 12, 140, 5);

    // イッテンの色彩論における三角形の色「鋭利な黄色(閃光)」
    stroke(255, 225, 60, alpha);
    strokeWeight(map(layer, 1, 12, 2.0, 0.5));

    beginShape();
    for (let i = 0; i < 3; i++) {
      vertex(vertices[i].pos.x * scaleRatio, vertices[i].pos.y * scaleRatio);
    }
    endShape(CLOSE);
  }

  // 2. 3つの頂点から伸びる「無限の補助線(空間を切り裂くエッジ)」
  stroke(255, 255, 255, 35);
  strokeWeight(1);
  for (let i = 0; i < 3; i++) {
    let current = vertices[i].pos;
    let next = vertices[(i + 1) % 3].pos;
    // 2点を結ぶベクトルを延長して画面の端まで線を引く
    let dir = p5.Vector.sub(next, current).normalize().mult(2000);
    line(current.x - dir.x, current.y - dir.y, current.x + dir.x, current.y + dir.y);
  }

  // 3. 主役となる「いちばん強い形(コアの三角形)」を描く
  fill(255, 225, 60, 22); // 内側にほのかな光の面
  stroke(255, 240, 120);    // 鋭く光る輪郭線
  strokeWeight(3);
  beginShape();
  for (let i = 0; i < 3; i++) {
    vertex(vertices[i].pos.x, vertices[i].pos.y);
  }
  endShape(CLOSE);

  // 4. 3つの頂点(支点)と、重心からのベクトル(矢印)を描く
  let centroid = createVector(
    (vertices[0].pos.x + vertices[1].pos.x + vertices[2].pos.x) / 3,
    (vertices[0].pos.y + vertices[1].pos.y + vertices[2].pos.y) / 3
  );

  // 重心から最も尖った頂点(vertices[0])へ向かう推進力ベクトル
  stroke(255, 90, 90, 200);
  strokeWeight(2);
  line(centroid.x, centroid.y, vertices[0].pos.x, vertices[0].pos.y);

  // 3つの頂点のノード(支点)
  for (let i = 0; i < 3; i++) {
    fill(i === 0 ? color(255, 90, 90) : color(255, 240, 120));
    noStroke();
    circle(vertices[i].pos.x, vertices[i].pos.y, i === 0 ? 12 : 8);
  }

  t += 0.02;
}

// 背景の静謐なグリッド(水平・垂直の秩序)
function drawBackgroundGrid() {
  stroke(255, 255, 255, 12);
  strokeWeight(1);
  let step = 100;
  for (let x = 0; x <= width; x += step) {
    line(x, 0, x, height);
  }
  for (let y = 0; y <= height; y += step) {
    line(0, y, width, y);
  }
}

// キーボードの 's' または 'S' を押したときに 1600x900 で保存する
function keyPressed() {
  if (key === 's' || key === 'S') {
    saveCanvas('triangle_energy_1600x900', 'png');
  }
}

3. コードの解説(技術的な仕組み)

  • pixelDensity(1) と createCanvas(1600, 900) MacのRetinaディスプレイなどの高精細モニター環境でも、書き出される画像サイズが2倍(3200×1800)にならず、指定通りの 1600×900ピクセル で正確に保存されるように制御しています。
  • 3つの頂点の極座標計算(cos / sin)とベクトルの強調 正三角形の3つの基準角度(-PI / 2, PI / 6, 5 * PI / 6)をベースにしつつ、1つ目の頂点(i === 0)だけ半径の倍率(stretch)を大きく設定しています。これにより、単なる対称図形ではなく「特定の方向をビシッと指し示す矢印(ベクトル)」としての緊張感を生み出しています。
  • p5.Vector.sub(next, current).normalize().mult(2000) 隣り合う2つの頂点を結ぶ差分ベクトルを取り出し、normalize() で長さを1に正規化したあと、2000倍に引き伸ばしています。これにより、三角形の3辺が画面の端まで突き抜ける「無限の補助線」となり、建築的な構造美と張力が際立ちます。
  • 重心の算出と推進力ベクトル 3つの頂点のX座標・Y座標をそれぞれ足して3で割ることで「重心(centroid)」をリアルタイムに計算し、そこから最も尖った頂点へ向かって赤いラインを引くことで、図形全体のエネルギーの向きを視覚化しています。
  • keyPressed() によるワンキー保存s キーを押した瞬間のフレームを saveCanvas() でPNG画像としてブラウザのデフォルト保存先へ即座に書き出します。

4. コードのかんたんな言葉での解説

このプログラムは、三角形が持つ「3つの性格」を画面の中で動かしています。

  1. 後ろのうっすらしたマス目(静かな部屋) 背景にある四角いマス目は、「正方形(静かで落ち着いた秩序)」を表しています。まっすぐな線の部屋を用意することで、三角形のナナメの線がよりシャープに浮かび上がります。
  2. 真っ暗な空間を切り裂く「黄色の光」 バウハウスのイッテンが三角形に割り当てた「黄色(ひらめき・閃光)」を使って、三角形が波紋のように広がっていく様子を描いています。
  3. 上に向かって伸びる「赤い矢印の線」 3つの角のうち、上の1つだけを少し遠くへ引っ張ることで、三角形全体が「上に向かって今にも飛び出しそうなロケット(矢印)」になるように仕掛けています。

キーボードの s キー をポンッと押すと、動いている好きな瞬間の絵を、そのままきれいな画像(1600×900)としてパソコンに保存できます。

今日の「観察ミッション」:街の中で隠れた三角形を3つ探してみよう

コードを実行して画像を保存したあと、ぜひ今日1日だけ、街の中やスマホの画面の中で「隠れた三角形」を3つ探してみてください。

  • 駅のホームの案内表示やエスカレーターの矢印
  • 橋やビルの天井を支える鉄骨の組み方
  • Webサイトの再生ボタンやロゴマークの余白

私たちが「つい目で追ってしまった場所」や「なぜか安心感を覚える場所」には、必ず誰かが意図して仕掛けた三角形が隠れています。形が持つ「言葉にならないメッセージ」と、その裏側にある数理的なルールに気づけるようになると、いつもの街並みが巨大なデザインの教科書に見えてきますよ。

まとめ・今回の実践を終えて

三角形は、わずか3つの点と3本の線という「これ以上削ぎ落とせない最小のルール」から生まれながら、巨大な建築を支える「揺るぎない構造の強さ」と、人の視線や心を特定の方向へ突き動かす「鋭いベクトル(エネルギー)」という、一見相反する2つの力を同時に宿した特別な図形です。

紙の上でコンパスと定規を使って3つの点を結び、それを今度はコードの中で cos と sin を使って動かしてみる。このアナログとデジタルの往復運動こそが、幾何学表現を自分の血肉にする一番楽しいプロセスです。ぜひパラメータの数値(半径の伸び率やレイヤーの枚数)を自分なりに書き換えて、あなただけの「光の三角形」を生み出してみてください。

Processingのコードで三角形を描きたい場合はこちら。

三角形について詳しくしりたい方はこちら。

ワタタク

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

ワタタク(Watataku)
クリエイティブコーダー
独学1年9ヶ月で虎ノ門ヒルズ49階、地上250mのインフィニティプールへ作品提供・展示

言葉×コード×手書き。三位一体の表現が成長する過程の記録

【発信】クリエイティブコーディング(2024.3~) / 絵(2025.11~) / モレスキン / 思考法 / 生き方

▼運営者について
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次