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?

2Dの線形変換をjavascriptのcanvasで学ぶ

Posted at

はじめに

 canvas2Dの線形変換には、平行移動、回転、拡縮があります。それが何をしているのかをざっくりと理解します。

座標系:基底と原点

sample0.png

まずデフォルトでは原点は(0,0)の位置にあります。基底のベクトルを$u,v$とします。$u$は(1,0)で、$v$は(0,1)がデフォルトです。このとき点(2,4)はどこでしょうか。

答えは(2,4)です。

なぜかというと図にある計算の通りです。これを線形結合と言います。成分ごとに係数を掛けて足し算をします。

一般の場合

 原点と基底ベクトルが一般の場合は次のように計算します。

sample1.png

これが座標系に対する点の位置の計算方法です、行列で表すこともできます。
座標変換の関数であるtranslate,rotate,scaleというのは、この座標系を操作するための関数です。

今からその概要を説明します。

rww2qfq.png

うるさい。

translate

sample2.png

translate(平行移動)は座標軸である基底を不変にし、原点のみ指定した値だけ動かすんですが、その動かし方は基底に依存します。すなわち(c,d)とある場合、単純にc,dを足すのではなく、$u$の$c$倍と$v$の$d$倍を順に(まあ順はどうでもいいんですが)足します。基底に依存するところがポイントですね。

rotate

sample3.png

次にrotateは、原点を不変にし、基底のみ変更します。どう変更するかというと、回転させます。回転方向は今$y$軸が下向き(一般的なcanvas2Dの座標系)なので時計回りです。ざっくりいうとこんな感じの計算結果になります。ちなみに筆者はこんなのまじめに覚えていません。なんとなくコサインとサインの足し算掛け算の結果だな~って思いながら符号だけ帳尻合わせてます。要はサインシータの±についてどっちがどっちって話なんですが、まあPI/2の挙動からなんとなくわかるので、それでいいですね。これを理屈で理解するのは大変ですし、理解してもあんま面白くないので。

scale

sample4.png

最後にscaleは、原点を不変にし、基底のみ変更します。$(s_x,s_y)$だとして、$u$を$s_x$倍し、$v$を$s_y$倍します。基底のそれぞれに倍数を掛けるだけ。単純ですね。

練習

これらを踏まえたうえで、練習をします。

sample5.png

この順でtranslate,rotate,scale,translateを実行した場合、座標系はどうなるのか?そしてその結果、点(8,15)はどこになるのか?

答えは原点が(160,250)で、$u$は(0,2)で、$v$は(-3,0)で、位置は(115,266)です。実際...

  const ctx = cvs.getContext("2d");

  ctx.fillStyle = "black";
  ctx.fillRect(0,0,400,400);
  ctx.fillStyle = "white";

  ctx.translate(100,250);
  ctx.rotate(Math.PI/2);
  ctx.scale(2,3);
  ctx.translate(0, -20);
  ctx.beginPath();
  ctx.ellipse(8,15,8,8,0,0,Math.PI*2);
  ctx.fill();

  // transform解除
  ctx.setTransform(1,0,0,1,0,0);
  ctx.fillStyle = "blue";
  ctx.beginPath();
  ctx.ellipse(115, 266, 8,8,0,0,Math.PI*2);
  ctx.fill();

この通り:

erefwrwrwr.png

2つの円が重なりました。なお楕円の描画はスケール変換の影響を受けるので、原点の位置は同じなんですが大きさが変わっています。今は位置を確かめたいだけなので、これでいいですね。

おわりに

 ちなみにp5ではpixelDensityを考慮して、devicePixelRatioが大きい場合にはデフォルトでscaleを実行しています。通常より大きいキャンバス上で描画しても違和感が無いように工夫しているわけです。レファレンスのどこにも書いてませんが、裏で色々やってるんですね。

 ここまでお読みいただいてありがとうございました。

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?