【p5.js】地形ポリゴンをつくったりハートを描いたり

p5.jsが楽しい。

参考にするのは「The Coding Train」というYouTubeチャンネル。Processingやp5.jsの中の人だと思う方が楽しそうにコーディングしてるのね。

現在は130本以上の動画があがっていて、「ふと」目にとまった動画を模写(or 移植)するようにしてる。最初は真似ることが大切だから。

先人の知識や経験に感謝。

今回「ふと」響いた動画は以下の2本。Processing(Java)からの移植だったのでJavaScriptの基礎を学ぶいい機会になりました。

3D Terrain Generation

ソースコード

sketch.js(クリックすると見れます)
const scl = 30;
const w = 1800;
const h = 1500;
let cols, rows;
let terrain = [];
let flying = 0;
let cam;
let delta = 0.01;

function setup() {
  createCanvas(innerWidth, innerHeight, WEBGL);
  cols = w / scl;
  rows = h / scl;

  frameRate(20);

  // 地形データ用配列の初期化
  terrain = new Array(cols);
  for (let i = 0; i < cols; i++) {
    terrain[i] = new Array(rows).fill(0);
  }

  // カメラの設定(傾きあり)
  cam = createCamera();
  cam.tilt(-0.7);
}

function draw() {
  // 地形データ用配列に位置情報をセット
  flying -= 0.5;
  let yoff = flying;
  for (let y = 0; y < rows; y++) {
    let xoff = 0;
    for (let x = 0; x < cols; x++) {
      terrain[x][y] = map(noise(xoff, yoff), 0, 1, -100, 100);
      xoff += 0.2;
    }
    yoff += 0.2;
  }

  // 地形を描画
  background(0);
  stroke(255);
  noFill();

  rotateX(PI/3);
  translate(-w/2, -h/2);
  for (let y = 0; y < rows-1; y++) {
    beginShape(TRIANGLE_STRIP);
    for (let x = 0; x < cols; x++) {
      vertex(x*scl, y*scl, terrain[x][y]);
      vertex(x*scl, (y+1)*scl, terrain[x][y+1]);
    }
    endShape();
  }

  // カメラの傾きを調整
  cam.tilt(delta);
  if (frameCount % 90 === 0) {
    delta *= -1;
  }
}
sketch.html(クリックすると見れます)
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>p5.js demo | Takashi Q. Hanamura Photograpy</title>
    <style>
        body {
            margin: 0;
            height: 0;
            overflow: hidden;
        }

        canvas {
            width: 100vw;
            height: 100vh;
            background: black;
        }
    </style>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/p5.min.js"></script>
    <script src="sketch.js"></script>
</head>

<body>
</body>

</html>

動作画面

別ウィンドウで見る(Safariがおすすめ)

わかったこと

(1)作り方がわかってきた

動作させたいことを最小単位に分割すればわかりやすいし、作りやすいよね。

つまり、複雑な動きをさせるときも、一つ一つ分解して単純化すればわかりやすい。単純化したものを組み上げていくことで複雑な動き(描画)にすることができるはず。

作り方(考え方)がわかってきた。

会社員のときにシステム開発をしていたことと同じだね。おかげで基本的なことを思い出せた。昔のカンも戻ってきてると思う。

(2)ブラウザによる動作速度の違い

動作確認はSafari / Chrome / Firefoxでやりましたが、Safariが一番低負荷で高速に描画されるのが面白かった。

Chrome / FirefoxではMBPのファンが唸ってしまいます。

Heart Curve

ソースコード

sketch.js(クリックすると見れます)
let heartVector = [];
let angle = 0;

function setup() {
  createCanvas(innerWidth, innerHeight);
}

function draw() {
  background(0);
  translate(width/2, height/2);

  let r = 10;
  let x = r * 16 * pow(sin(angle), 3);
  let y = -r * (13 * cos(angle) - 5 * cos(2*angle) - 2 * cos(3*angle) - cos(4*angle));
  heartVector.push(createVector(x, y));
  angle += 0.05;

  noFill();
  stroke(255);
  strokeWeight(4);
  fill(150, 0, 100);
  beginShape();
  for (i of heartVector) {
    vertex(i.x, i.y);
  }
  endShape();

  if (angle >= TWO_PI) {
    noLoop();
    console.log("Finish");
  }
}

※sketch.htmlは3D Terrain Generationと同様

動作画面

ハートが描かれます。見れない場合はリロードしてくださいね。

別ウィンドウで見る(Safariがおすすめ)

わかったこと

(1)JSの基礎不足

3D Terrain Generationでも感じたけど、僕はJSの配列やデータ型について理解が不足しているね。

ループ処理もなんか複雑。

JavaScriptは年々進化していると聞きます。ループ処理も昔からの「for」のほか「[…Array]」 という書き方もあって、使い分けがわかりにくい。

そんなこんなで以下の記事を参考にしながら、Heart Curveでは「for 〜 of 〜」を使うことで想定した動作をさせることができた。

思わず「よっしゃ!」って叫んじゃったよ(笑)

今のところ、JSの基礎を知るには公式(?)の情報から入っていったほうがいいのかも、と理解しました。

(2)数学を思い出せてきてる

三角関数やベクトルの概念を少しずつ思い出せてきてる!

深まるのが楽しい

できないことができるようになる。
わからなかったことがわかる。

僕はここに楽しさを感じてしまうんだよね。

いずれ素敵な作品を魅せるためにコツコツと筋トレしているよ。

【出張撮影のご依頼、承ってます】

あなたの行きたい場所に出張してポートレイトやプロフィール写真を撮影します。出張エリアは関西エリア(神戸・大阪・京都など)、関東エリア(神奈川、東京など)です。

★詳細:ポートレイト/プロフィール撮影(Photo Session)
★詳細:Photo Shooting

撮影予約可能日

【関西エリア】
・3月1日(金)〜21日(木)
・4月21日(日)〜

【関東エリア】
・3月23日(土)〜4月16日(火)

申し込みフォーム

★ポートレイト/プロフィール撮影を依頼する
★Photo Shootingを依頼する

ピンときた方、まずはお問い合わせください。お待ちしています!
  • コピー

この記事を書いた人

花村貴史|Takashi Q. Hanamura

人物や風景、街並み、小物を好んで撮っている空気感フォトグラファー。本職であるPhotographerのかたわら、Engineer、Creatorとしても活動中。
その人・その場の「空気感をそっとすくい撮る」写真が好評。「自分の素敵に気づける写真」を撮る。数年間の心のお稽古によるカウンセラーマインドによって、撮影は「心のセッション」になることも。
オシゴトについては「メニュー/料金/予約」からどうぞ。

この記事が気に入ったら
いいね!しよう

最新の情報をお届けします

撮影|Photo Session

お話しながらのポートレイト撮影です。「今」そして「これから」のあなたにフォーカスして撮影します。SNSやサイト用のプロフィール写真に。

撮影|Photo Shooting

「友達と楽しんでいる」「セミナーで講演している」「パーティーを主催している」など、皆さんが大切な時間を過ごしている瞬間をスナップします。

写真術|Photo Lecture

カメラの使い方、撮影術、Lightroomの使い方などの「マンツーマンレクチャ」や「少人数制のワークショップ」について。写真に関する疑問の解決に。

販売:Photo Sales

A3ノビ〜A4程度のサイズの額装販売および、壁紙などの写真データの販売。ご自宅やコミニュティスペースに飾り、癒しになれば嬉しい。