LoginSignup
2
3

More than 1 year has passed since last update.

2次元図形の回転~JavaScript~

Posted at

図形の回転に必要な知識

オブジェクトを回転させるには回転行列という線形代数の知識が必要です。線形代数を習っていな人でも分かりやすく説明するので、是非読んでください。
回転行列は以下の式で表せます。

R(θ)=
\begin{pmatrix}
\cosθ & -\sinθ \\
\sinθ & \cosθ
\end{pmatrix}

原点中心のθ回転 反時計回りを正とする

大学1年生だった当時、回転行列を初めてみたとき何がどうやらと分かりませんでした。線形空間を講義で習っており、「線形従属・線形独立何それ美味しいの?🤤」っていう状態でしたけど今はちゃんと理解してるので今苦しんでいる人もなんとかなります!
ヨビノリの動画やマセマの線形代数の参考書読めばある程度わかります!
線形代数.jpg

線形空間のテスト1年目はF評価でしたけど,2年目はA評価取りました✨

私が一番分かりやすいと思った証明方法を説明します。高校数学の内容のみで証明します。
座標軸上に描かれた図形を動かすというより座標軸そのものをθ回転させるといった考え方ですね。
大雑把な証明ですが回転行列をど忘れしたとき、すぐ導出できるのでおすすめ
Screen Shot 2023-03-06 at 16.59.38.png

\begin{pmatrix}
1 \\
0
\end{pmatrix}
\rightarrow
\begin{pmatrix}
\cosθ  \\
\sinθ 
\end{pmatrix}
\begin{pmatrix}
0 \\
1
\end{pmatrix}
\rightarrow
\begin{pmatrix}
-\sinθ  \\
\cosθ 
\end{pmatrix}

よって

\begin{pmatrix}
1 & 0 \\
0 & 1
\end{pmatrix}
\rightarrow
\begin{pmatrix}
\cosθ &-\sinθ  \\
\sinθ &\cosθ 
\end{pmatrix}

数学的な用語で説明すると (0,1),(1,0) 基底ベクトルで張られた空間をθ回転させることで (cosθ,sinθ),(-sinθ,cosθ) を基底ベクトルにした空間を張る。

JavaScriptで回転させてみる

実際にJavaScriptで図形を回転させてみよう!

2D回転
const canvas = document.getElementById("target");
const context = canvas.getContext("2d"); //2次元描画
let degree = 0; //変数角度を設定

let array=[
    [120,60],
    [360,120],
    [240,240]
]

function triangle(fig,x1,y1,x2,y2,x3,y3){
    fig.beginPath(); //パスの作成
    fig.moveTo(x1,y1);
    fig.lineTo(x2,y2);
    fig.lineTo(x3,y3);
    fig.closePath();
    fig.fillStyle = "blue";
    fig.fill();
    fig.lineWidth = 3;
    fig.strokeStyle = "black";
    fig.stroke();
}

let center = (A) => [
    (A[0][0] + A[1][0] + A[2][0]) / 3,
    (A[0][1] + A[1][1] + A[2][1]) / 3
];

function rotate(){
    context.clearRect(0,0,canvas.width,canvas.height);
    degree+=1
    r=(degree*Math.PI)/180
    let S = array;
    let vx = new Array(3);
    let vy = new Array(3);
    let x = new Array(3);
    let y = new Array(3);
    // 三角形の重心を求める
    let c = center(S);
    for(let i=0; i<3; i++){
        // 回転中心座標から回転する座標へのベクトルを求める
        vx[i] = S[i][0] - c[0];
        vy[i] = S[i][1] - c[1];
        // ベクトルを回転
        x[i] = vx[i]*Math.cos(r) - vy[i]*Math.sin(r);
        y[i] = vx[i]*Math.sin(r) + vy[i]*Math.cos(r);
        x[i]+=c[0];
        y[i]+=c[1];
    }

    triangle(context,x[0],y[0],x[1],y[1],x[2],y[2])
}

setInterval("rotate()",20);

原点中心で回転させるのでなく、三角形の中心(重心)で回転させたいので回転行列を適用する前に 重心の座標分 平行移動させています。またrotate関数をsetIntervalで20msごとに呼び出しています。

ここら辺の処理も慣れないと案外難しいですねー

2
3
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
2
3