アクセス可能な言語でのキャンバス変換

こんにちは、habravchane! この記事では、javascripteでの変換と回転について詳しく説明します。 変換マトリックスは、一見すると理解不能であり、多くの人々は、インターネットからの既成の値を使用して、実際に何をしているのかさえ理解せずにそれを使用します。 MDCでは、これは控えめに説明されており、英語版ウィキペディアの情報は一般に公開するの困難です。 これを一緒に理解しようとします。





翻訳する



翻訳は最も簡単な変換方法です。 アドレス指定されたすべてのピクセルを、指定された値ctx.translate(x,y)



だけシフトします。 彼と一緒に仕事をすることの微妙な違いを以下で詳しく検討します。

翻訳を試す





スケール



scaleは、translateと同様に、xとyを引数として取ります-対応する軸に乗算する値。 たとえば、ctx.scale(2,3)を使用すると、すべてが幅の2倍、高さの3倍で描画されます。 X = -1を指定することにより、画像を左にミラーリングし、y = -1を指定することにより、画像をミラーリングします。

スケールの実験





回転



Rotateは、translateメソッドで指定されたピボットポイントを中心にイメージを回転させるラジアン単位の角度を引数として取ります(デフォルトは0:0)。 LibCanvasのNumber.degreeメソッドの基礎となる単純な式を使用して、度をラジアンに変換できます。

 Number.prototype.degree = function () { return this * Math.PI / 180; }; (60).degree() // 60   
      
      





回転の実験



絵などのオブジェクトを回転させたい場合は、rotateメソッドとtranslateメソッドを正しく操作する必要があります。そうしないと、適切な場所に画像が表示されません。 回転軸で画像の中心を選択し、座標(-width / 2、-height / 2)で描画する最も簡単な方法。 たとえば、100:100座標にある50x50のイメージを展開します。 平行移動125:125をポイントし、座標-25:-25で絵を描きます。 別の方法として、LibCanvasとrotateImageメソッド(または近い将来drawImage)を使用し、負担をかけるのではありません。

画像を回転させる





setTransform



 ctx.setTransform(m11, m12, m21, m22, dx, dy);
      
      





各引数が何に責任があるのか​​を順に考えてみましょう。

dx, dy



翻訳方法を繰り返し、適切な値だけ画像をシフトします。

m11, m22



スケール方法を繰り返し、描画されるピクセルのサイズを変更します。

m12, m21



より興味深い。 各ピクセル(x、y)はy * m21ピクセル右にシフトし、x * m12ピクセル下にシフトします。つまり、m21 = 1の場合、次の各行は前の行に対して1ピクセル右にシフトします。

setTransformの実験



変換メソッドはまったく同じように機能しますが、setTransformとは異なり、毎回前の変換を無効にするのではなく、オーバーレイします。 これから何を得ることができますか?



等尺性マップ



単純な変換を使用して、平面図のタイル2Dマップから等尺性を作成してみましょう。 最も単純な等角投影図は、水平方向の対角線が垂直方向の2倍の大きさの菱形です(幅が2倍高い)。 これは3つのステップで実行できます。



m21 = 1で右にシフトし、m12 = -0.5で持ち上げ、m22 = 0.5で押します( サンドボックスで段階的に繰り返すことができます)。

ただし、水平に対して26.565°の角度の等角図になります。 30°の角度で実際の等角投影が必要な場合は、X軸に沿ってセル幅を変更して幅をわずかに平坦化する必要がありますが、これは次の方法を使用して簡単に計算できます:



セルは、点Oに中心を持つABCD菱形であることがわかります。角度BAOは、26.6から作成する必要がある角度です。AO= BD​​、つまり、二等辺三角形BADの高さは、その底に等しくなります。 この三角形を正三角形にする(つまり、BAD角度が60度になる)必要があります。つまり、何らかの要因で高さを減らします。 AO = BD = 1オウムと仮定します。 次に、AOはオウムのsqrt(AB 2 -BO 2 )= sqrt(1-0.25)= 0.866に等しくなければなりません。 これは、マトリックスで使用する係数です。

 ctx.setTransform(0.866, -0.5, 0.866, 0.5, 0, 0)
      
      





マップの取得方法を確認します





すべてが明確に説明されていることを望みます。 質問をし、提案し、一緒にトピックを補充します。



All Articles