デジタル・デザイン・ラボラトリーな日々

アラフィフプログラマーが数学と物理を基礎からやり直す。https://qiita.com/yaju

座標の回転式における私の勘違い

座標を回転した位置を求める関数として以下を使用していた。

function rotate2d(x, y, rad) {
    var p = new Point;
    p.x =  Math.cos(rad) * x - Math.sin(rad) * y;
    p.y =  Math.sin(rad) * x + Math.cos(rad) * y;

    return p;
}

ある座標位置を30度回転した座標を求めるんだけど、どうも思っていた座標と違うのが戻ってくる。
計算式は、本やサイトを参考にして作成しているので間違っているとは思えない。

そこで座標(322,127)の角度0で幅100の位置を求めたところ、座標(422,227)が返ってきたわけです。

var p = new Point(100, 100);
var pt = rotate2d(p.x, p.y, rad);

自分が意図していた座標は角度0なので幅100の座標(422,0)なんですけどね。
ということは引数yに値を渡していることに問題がありそうです。

そこで過去のプログラムを見直してみると、幅100で指定の角度を求めていた場合、

var p = new Point(100, 0);
var pt = rotate2d(p.x, p.y, rad);

としていました。引数yは0を指定しいます、0でいいなら引数yの計算が無意味です。
幅100で指定の角度を求めるだけであれば、下記の計算式で十分です。

function rotate2d(w, rad) {
    var p = new Point;
    p.x =  Math.cos(rad) * w;
    p.y =  Math.sin(rad) * w;

    return p;
}

では、引数yは何のために必要だったのかと調べていくと、例えば下図の長方形を回転させようとした場合、点A(x,0)とは平行に点P(x,y)があります。その場合に引数yが必要となります。

var A = new Point(100, 0);
var ptA = rotate2d(A.x, A.y, rad);
var P = new Point(100, -50);
var ptP = rotate2d(P.x, P.y, rad);

f:id:Yaju3D:20120702020536p:plain

回転式の意味をしっかり理解していなかった為に、平行移動としての引数yと意識せずに指定して、想定していた座標とは違う座標が返ってきてしまい、嵌る原因となっていたわけです。