ゲーム開発
Unity
UnrealEngine
C++
Blender
Houdini
ゲーム数学
ゲームAI
グラフィックス
サウンド
アニメーション
GBDK
制作日記
IT関連
ツール開発
フロントエンド関連
サーバサイド関連
WordPress関連
ソフトウェア設計
おすすめ技術書
音楽
DTM
楽器・機材
ピアノ
ラーメン日記
四コマ漫画
その他
おすすめアイテム
おもしろコラム
  • ゲーム開発
    • Unity
    • UnrealEngine
    • C++
    • Blender
    • Houdini
    • ゲーム数学
    • ゲームAI
    • グラフィックス
    • サウンド
    • アニメーション
    • GBDK
    • 制作日記
  • IT関連
    • ツール開発
    • フロントエンド関連
    • サーバサイド関連
    • WordPress関連
    • ソフトウェア設計
    • おすすめ技術書
  • 音楽
    • DTM
    • 楽器・機材
    • ピアノ
  • ラーメン日記
    • 四コマ漫画
      • その他
        • おすすめアイテム
        • おもしろコラム
      1. ホーム
      2. 20221222_01

      【ゲーム数学】第七回 p5.jsで学ぶゲーム数学「積分の実装とクロソイド曲線」

      ゲーム数学JavaScriptp5.js
      2022-12-23

      マイケル
      マイケル
      みなさんこんにちは!
      マイケルです!
      エレキベア
      エレキベア
      こんにちクマ〜〜〜
      マイケル
      マイケル
      今回は引き続きゲーム数学シリーズ!
      前回は微分を使ってみたので、今回は積分を使っていきます!
      エレキベア
      エレキベア
      そうくると思ったクマ〜〜〜
      マイケル
      マイケル
      積分も実装してみると案外簡単だし理解が深まると思います!
      早速やっていこう!!

      積分とは

      マイケル
      マイケル
      積分とはある関数を導関数とする元の関数を求めることです。
      簡単にいうと微分の逆です!
      マイケル
      マイケル
      積分はインテグラル(∮)を用いて記述され、簡単な例を挙げると下記のようになります。

      $$ \int2xdx = x^2 + C $$

      エレキベア
      エレキベア
      微分と逆の計算をすればいいクマね
      でもこのCは何クマ??
      マイケル
      マイケル
      Cは積分定数と言われていて、任意の値になるんだ。
      例えば下記のように微分をした場合には2は消えてしまいます。
      このように導関数からは復元できない値が出てくるわけですね

      $$ f(x)=x^2+2 $$

      $$ f'(x)=2x $$

      エレキベア
      エレキベア
      なるほどクマ
      微分すると消えてしまう値を表しているクマね
      マイケル
      マイケル
      このように範囲を決めずに積分定数を用いて表す積分を不定積分と言います。
      逆に、下記のように求める範囲を決めて積分することを定積分と言います。

      $$ \int_{1}^{3}2xdx = 3^2 – 1^2 = 8 $$

      マイケル
      マイケル
      これは結果として関数の指定範囲の面積となります。
      下記のようなイメージですね
      エレキベア
      エレキベア
      微分は傾きを求めるものだったクマが、
      積分は面積を求めるものになるクマね

      積分の実装

      マイケル
      マイケル
      それでは早速積分を実装してみます。
      下記は積分定数は無視して関数を微分した結果を描画するサンプルです。
      (青:元の関数 ピンク:積分した関数)

      See the Pen
      20221220_integral
      by masarito617 (@masarito617)
      on CodePen.

      ↑2xの積分(x^2)
      (1/3)x^2の積分(x^3)
      エレキベア
      エレキベア
      ちゃんと元の形を求められていそうクマね
      マイケル
      マイケル
      積分の実装箇所は下記のようになっていて、定めた間隔分、値を求めて加算しています。
      先ほどの面積を求めるイメージですね。
      // 関数
      function func(x) {
        return 2*x; // => x**2
      }
      
      // 積分
      function integral(start, end) {
        let r = 0.0;
        let dx = 0.01; // 間隔を小さくすると精度が向上する
        if (start > end) {
          [start, end] = [end, start];
        }
        for (var x = start; x < end; x += dx) {
          r += func(x) * dx;
        }
        return r;
      }
      エレキベア
      エレキベア
      実装はかなりシンプルなのクマね
      マイケル
      マイケル
      func関数の中身を変更することで任意の関数の積分結果を表示することができるので、いろいろ変えて遊んでみてください!

      応用:面積を求める

      マイケル
      マイケル
      次は面積を求めているイメージが分かりやすいよう、0と指定のX値の定積分の結果面積を可視化するサンプルを作って見ました。

      See the Pen
      20221220_integral_area
      by masarito617 (@masarito617)
      on CodePen.

      ↑2xの積分
      ↑cos(x)の積分
      エレキベア
      エレキベア
      なんだか見ていて面白いクマね
      マイケル
      マイケル
      右上に動きを停止するボタンも用意しているので、止めてみると問題なく面積を求められていることが確認できます。
      ↑止めてみると面積分の数値になっている
      エレキベア
      エレキベア
      実際に図で見てみると分かりやすいクマね

      応用:クロソイド曲線を描画する

      マイケル
      マイケル
      最後に応用として、積分を利用してクロソイド曲線というものを描画してみます。
      クロソイド曲線は何かいい感じの螺旋を描く曲線で、下記の積分値で求めることができます。

      $$ x(l)=\int_{0}^{l}cos(\frac{\theta^2}{2}d\theta) $$

      $$ y(l)=\int_{0}^{l}sin(\frac{\theta^2}{2}d\theta) $$

      エレキベア
      エレキベア
      xとyのどちらも積分することで求めるクマね
      マイケル
      マイケル
      実際に描画するサンプルは下記になります!

      See the Pen
      20221222_integral_clothoid
      by masarito617 (@masarito617)
      on CodePen.

      ↑美しいクロソイド曲線
      マイケル
      マイケル
      問題なく表示することができました!
      エレキベア
      エレキベア
      美しいクマ・・・
      マイケル
      マイケル
      描画部分のコードは下記になります。
      コードで見てもかなりシンプルですね!
      // クロソイド曲線の描画
      function drawClothoidIntegral() {
        strokeWeight(1.5);
        stroke(0, 0, 255);
        let dt = 0.01;
        let l = 10;
        for (let t = -l; t < l; t+=dt) {
          let vec = 0 < t ? 1 : -1; // 0からの方向になるので負の場合は反転させる
          drawLineCanvas(
            vec * integral(0, t, clothoidFuncX),
            vec * integral(0, t, clothoidFuncY),
            vec * integral(0, t+dt, clothoidFuncX),
            vec * integral(0, t+dt, clothoidFuncY));
        }
      }
      
      // クロソイド曲線の関数
      function clothoidFuncX(x) {
        return cos(x**2/2);
      }
      function clothoidFuncY(y) {
        return sin(y**2/2);
      }
      エレキベア
      エレキベア
      積分、恐るるに足らずクマ〜〜〜!!

      おわりに

      マイケル
      マイケル
      というわけで今回は積分について触れてみました!
      どうだったかな??
      エレキベア
      エレキベア
      実装するとやっぱり分かりやすいクマね〜〜
      マイケル
      マイケル
      コードを書いてみるとすごくシンプルな計算をしていることが分かるね!
      積分を使えると様々な式の導出も出来るようになるから、積極的に使っていこう!
      マイケル
      マイケル
      それでは今日はこの辺で!
      アデューー!!
      エレキベア
      エレキベア
      クマ〜〜〜〜

      【ゲーム数学】第七回 p5.jsで学ぶゲーム数学「積分の実装とクロソイド曲線」〜完〜


      ゲーム数学JavaScriptp5.js
      2022-12-23

      関連記事
      【ゲーム数学】第九回 p5.jsで学ぶゲーム数学「フーリエ解析」
      2024-05-12
      【Node.js】廃止されたAmazonアソシエイト画像リンクをAmazon Product Advertising API経由で復活させる
      2024-01-08
      【都会のエレキベア】ブログを大幅リニューアル!WordPressからNext.jsに移行するまでの流れをまとめる
      2024-01-01
      【Next.js】第四回 WordPressブログをNext.jsに移行する 〜サーバ移行・SEO・広告設定編〜
      2023-12-31
      【Next.js】第三回 WordPressブログをNext.jsに移行する 〜Markdown執筆環境構築編〜
      2023-12-31
      【Next.js】第二回 WordPressブログをNext.jsに移行する 〜WordPressデータの移行・表示編〜
      2023-12-31
      【Next.js】第一回 WordPressブログをNext.jsに移行する 〜全体設計、環境構築編〜
      2023-12-31
      【Electron × Vue3】カテゴリ情報のCSVデータを操作するツールを作る
      2023-12-31