オブジェクトが常にキャンバスの中心を向く仕組み
をp5.jsで実装しようとして沼った話です。クリエイティブコーダーの皆さんや数字に強い方には当たり前のことだとは思いますが、半ば備忘録的に記しておきます。
'translate()'関数や'heading()'関数で頑張った
回転の話なので、まずは'translate()'関数と'rotate()'関数で実装する方法を考えました。任意の座標に図形(ここでは三角形)を描画し、その中心を原点に移動させて回転。そのあとに元の位置へ戻す。考え方はシンプルですが、どうにも意図した挙動にならず、結局自分がどういう計算をさせていたのかいまだにわかっていません。また、p5.Vectorに含まれる'heading()'メソッドでも試してみましたが、こちらも似たような挙動を再現するのみで、キャンバスの中心を向いてくれませんでした。
正解は逆正接関数、つまりatan2だった
失敗した方法を何度も堂々巡りをしていたので「そろそろシフマン先生の動画でも漁るかなぁ」と思い始めたが、とりあえずChatGPTに三角形の描画からステップを踏んで描画をしてもらうことにしました。数回のやり取りであっさり解決。
描画の条件と生成されたコードは以下の通り。
任意の半径rの円周上に始点が90°(12時)の位置にくるように三角形を描画する*
三角形の中心はマウスの座標で指定する
三角形の中心が常にキャンバスの中心を向く
*この描画方法自体はこちらからコードの例を示した(追記参照)
function setup() {
createCanvas(600, 600);
}
function draw() {
background(220);
let centerX = mouseX;
let centerY = mouseY;
let r = 100;
// 中心からの角度を計算
let angle = atan2(centerY - height / 2, centerX - width / 2);
// 三角形の描画
push();
translate(centerX, centerY);
rotate(angle);
beginShape();
for (let a = -PI / 2; a < TAU - PI / 2; a += TAU / 3) {
let x = r * cos(a);
let y = r * sin(a);
vertex(x, y);
}
endShape(CLOSE);
pop();
}
ほう、'atan2()'関数ですか…
リファレンスで見たことあるけど放置してたわ。なんですかそれは。
生成AIによる解説を真に受けるべきかどうかという問題はありますが、ざっくりググってみた内容とも大きな差異はなさそうでした。とにかく任意の座標と原点との角度を計算するみたいですね。
なんか作ってみた
簡単なアレンジを試みました。
おわりに
今回も生成AIに解決してもらいました。だんだんと逆引き辞書のように思えてきました。
先述の通り、どうやら逆正接関数を使用した回転の制御は半ば常識のようなものらしいです。この記事が同じような沼に向かっている方への道標(墓石?)になれば幸いです。そんな方は少数かもしれませんが…。
追記:コードに誤りがあったので修正しました。(2024年5月2日)
この記事が気に入ったらサポートをしてみませんか?