こんにちは。エンジニアの辻です。
前回、前々回は反時計回りの線形変換を扱ってきました。
実は線形変換には回転以外にもいくつか種類があります。
今回は canvas でよく使いそうな計算式を紹介していきます。
ソースコードについて
今回紹介する線形変換の関数は、以下の main.js で確認できます。
ソースコードの構造は前回、前々回と同様です。
様々な線形変換
x 軸に対して反転する
まずはじめに紹介するのは x 軸に対して反転させる計算式です。
JavaScript で表すと以下のような関数になります。
引数の target には{x: x 軸の位置, y: y 軸の位置}のオブジェクトが入ってきます。
target の x、y に対して変換を行い、その結果を返しています。
1 2 3 4 5 6 7 |
// x軸に対して反転する処理 const inversionXTransformation = function (target) { return { x: target.x * 1 + target.y * 0, y: target.x * 0 + target.y * -1 } } |
実際に canvas 上に描画してみると以下のようになります。
初期配置のボックスが赤です。
赤ボックスを x 軸に対して反転し、その位置に青ボックスを描画しています。
y 軸に対して反転する
x 軸と来たら、次は y 軸で反転ですね。計算式は上記の通りです。
JavaScript で表すと以下になります。
1 2 3 4 5 6 7 |
// y軸に対して反転する処理 const inversionYTransformation = function (target) { return { x: target.x * -1 + target.y * 0, y: target.x * 0 + target.y * 1 } } |
canvas 上に描画してみると以下のようになります。
こちらも赤ボックスが初期配置のボックスです。
赤ボックスを y 軸に対して反転して描画したのが、緑ボックスです。
長さ(位置)を n 倍する
次は長さ(位置)を n 倍する計算式です。
x は nx で乗算され、y は ny で乗算されます。
結果として、x を nx 倍した x’ と、y を ny 倍した y’ のベクトルが得られます。
例えば nx = 1、ny = 2 とした場合、x は 1 倍。y は 2 倍となるため、横幅は変わらず。高さだけが 2 倍となります。
JavaScript で表すと、以下の通りです。
1 2 3 4 5 6 7 |
// targetのx,yをnx, ny倍する処理 const multipeTransformation = function (target, nx = 1, ny = 1) { return { x: target.x * nx + target.y * 0, y: target.x * 0 + target.y * ny } } |
canvas 上に描画してみると以下のようになります。
multipeTransformation の nx と ny に 2 を入れて実行した結果を描画しています。
初期配置の赤ボックスから、x・y ともに 2 倍した位置に黄色ボックスが配置されます。
x 軸から θ° でせん断(斜めにひしゃげる)
せん断の計算式です。斜めにひしゃげる変形ですね。
上記は x 軸から θ° でせん断させる計算式です。
JavaScript で表すと、以下の通りです。
1 2 3 4 5 6 7 8 9 |
// x軸からθ°でせん断する処理 const shearXTransformation = function (target, degree = 0) { // 度からラジアンを取得 const radian = convertToRadian(degree) return { x: target.x * 1 + target.y * 0, y: target.x * Math.tan(radian) + target.y * 1 } } |
せん断を canvas 上に描画してみると以下のようになります。
せん断前のオブジェクトは、縦 20x 横 20 の正方形で、左下の点が原点と重なる位置にいました。
そのオブジェクトを x 軸に対して 60° でせん断しています。
結果的に、平行四辺形を描く事ができました。
y 軸から θ° でせん断
最後は y 軸から θ° でせん断させる計算式です。
JavaScript で表すと、以下の通りです。
1 2 3 4 5 6 7 8 9 |
// y軸からθ°でせん断する処理 const shearYTransformation = function (target, degree = 0) { // 度からラジアンを取得 const radian = convertToRadian(degree) return { x: target.x * 1 + target.y * Math.tan(radian), y: target.x * 0 + target.y * 1 } } |
canvas 上に描画してみると以下のようになります。
y 軸に対して 60° でせん断しています。
まとめ
さて、今回は様々な線形変換を見てきました。
他にも様々なタイプがあるので、気になる方はぜひ調べてみてください!
線形変換 wikipedia
次回の記事: JS奮闘記【JavaScriptとcanvasと線形変換 その4 ~線形変換のポイントと行列積の特徴編~】