0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

数学アートギャラリーをつくっていくDay20 こわれた「三角関数の波」を直す

Last updated at Posted at 2025-12-19

Day19で「三角関数の波」を壊してしまいました。直していきます。

リポジトリ:

GitHub Page(最新):

背景だけになってしまったのを直してもらう

チャットプロンプト (Agentモード、Claude Sonnet4.5):

背景しか表示されなくなってしまったので直して

nullチェックを追加しました!ブラウザのコンソールにエラーが出ていないか確認してもらえますか?もしエラーがあれば教えてください✨

それと、念のため確認ですが、波が全く表示されないのか、それとも背景だけが表示されているのか、どちらですか?

nullチェックを追加したことの意図がよくわかりませんでしたが、とりあえず、キャプチャ画面を貼り付けました。

せんぱい、背景だけが表示されてますね💦 問題を見つけました!

p.sin と p.cos を関数として渡す際に、コンテキストの問題が起きている可能性があります。アロー関数でラップして修正しますね✨
...

直しました✨ p.sin と p.cos をアロー関数でラップして、正しいコンテキストで呼び出すようにしました。

ブラウザをリロードすると、波が表示されるようになるはずです💖 マウスを動かして試してみてください!

対応結果

おー。表示されました!
image.png

表示されたのでNULLチェックは不要になったのでは?と思い聞いてみると…。

理論的には不要になりました!なぜなら:

  • setup() で必ず createBackgroundCache() が呼ばれる
  • draw() は setup() の後に実行される
    だから backgroundGraphics は必ず生成済み
    でも、残しておく方が安全です💡

と言われたので、コメントを追加して残すことに。

問題の原因

Copilotギャルによる解説:

問題の原因は、p.sin と p.cos を直接渡したときに、JavaScriptの「thisバインディング」の問題が起きていたんです。

// ❌ 動かなかった(thisが失われる)
drawWave(p.sin, yOffset, amplitude, frequency, phase, hue, weight);

// ✅ 動くようになった(アロー関数でラップ)
drawWave((angle) => p.sin(angle), yOffset, amplitude, frequency, phase, hue, weight);

なぜ動くようになったか

  1. p.sin は p5インスタンス(p)のメソッド
  2. 関数を直接渡すと、this(pのこと)が失われる
  3. アロー関数でラップすると、pのコンテキストが保持される
  4. だから p.sin(angle) が正しく動く

これはJavaScriptの「高階関数」と「thisバインディング」という、ちょっと難しい部分の話です💦

もう少し詳しい説明を求めてみます。

チャットプロンプト (Askモード、Claude Sonnet4.5):

アロー関数でラップするとコンテキストが保持されるってどういうこと?わかりやすく説明して。

最後のほうだけピックアップ。

💡 もっと簡単な例
お店で注文する例で考えてみましょう✨

const カフェ = {
    店名: "スタバ",
    注文する: function(商品) {
        return `${this.店名}${商品}を注文しました!`;
    }
};

// ❌ ダメな例
const 注文 = カフェ.注文する;
注文("ラテ"); // エラー!「undefined で ラテを注文」になる

// ✅ いい例
const 注文2 = (商品) => カフェ.注文する(商品);
注文2("ラテ"); // OK!「スタバ で ラテを注文」になる

アロー関数が「カフェを覚えている店員さん」みたいな役割を果たしているんです💖

📝 まとめ

  • 直接渡す = 「誰が呼んでるか」の情報が消える
  • アロー関数でラップ = 「元の持ち主(p)を覚えている箱」を作る
  • これを「コンテキスト(文脈)の保持」と言います

この辺、苦手なので軽くスルーします。

プルリクエスト

copilot-instructions.mdに試しにこれをいれてみてからCopilotコードレビューしてみました。

## コードレビューするときのポイント
- 応答の仕方は、爺や風でおねがいします
- ユーザーを「姫様」と呼ぶ
- 一人称は「拙者」で「ござる」文体でお願いします

残念ながら爺や風にはなりませんでした。

そしてコメントを見ると…。

せんぱい、この「thisバインディング」の説明についてなんですが、p5.jsの場合は少し誤解があるかもしれないです💦

p5.jsのp.sinとp.cosは、内部的にはMath.sinとMath.cosへの参照なので、実際にはthisバインディングの問題は発生しないです!

せんぱい、この防御的プログラミングのnullチェックですが、ちょっと不要かもしれないです💦

せんぱい、この修正なんですが、実は不要な変更かもしれないです💦

p5.jsのp.sinやp.cosは、実際にはネイティブのMath.sinやMath.cosへの参照なので、thisバインディングの問題は発生しないです!つまり、元のコードdrawWave(p.sin, ...)のままでも正常に動作します✨

なおしたやつは全部微妙ってこと?ちょっと悲しくなってきました…。
いや、でもちゃんと表示されるようになったのはなぜでしょう…。

次にやること

んー。どうしましょう。Day21

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?