2017-06-26 9 views
1

私は、変換ポイントを2Dポイントに手動で適用するという奇妙な問題に遭遇しました。変換マトリックスに変換またはスケーリングを適用すると、2Dポイントの結果の位置は、それが予想される場所になります。一方、回転は、奇妙で予期しない方法で形状を歪ませて回転させるようです。なぜ翻訳とスケーリングは期待どおりに動作しますが、ローテーションは純粋なトランスフォームの実装ではありませんか?

私は、この問題が数日間起こっている理由を理解しようとしていましたが、役に立たなかった。私は数学をチェックしましたが、問題の原因ではないようです(コンポジット変換はSVGの変換属性を使って適用したときに期待どおり動作しますが、手動で各ピクセルに適用したときは期待通りに動作します)変換マトリックスが実際に2Dポイントにどのように適用されるかについての私の理解の欠陥であると信じてください。私は2D点に変換行列を単純に乗算して新しい点を得る。

回転が期待通りに動作しないのはなぜですか?

この問題を示す例は、jsfiddleにあります。正確に方向付けられた回転行列が使用されていても、問題が明らかになるので、逆Y軸を無視します。あなたがxyを宣言した

function paint_point(x, y) { 
    var x = ctm[0]*x + ctm[2]*y + ctm[4]; 
    var y = ctm[1]*x + ctm[3]*y + ctm[5]; 
    ctx.fillRect(x, y, 1, 1); 
    } 

あなたの変換関数に

window.onload = function(e) { 
    var canvas = document.getElementsByTagName('canvas')[0]; 

    if (canvas.getContext) { 
     var ctx = canvas.getContext('2d'); 
     var ctm = [1.0, 0.0, 0.0, 1.0, 0.0, 0.0]; 
     ctx.lineWidth = 0.0; 

     function matrix_mul(a, b) { 
      return [ 
       a[1]*b[2] + a[0]*b[0], 
       a[1]*b[3] + a[0]*b[1], 
       a[3]*b[2] + a[2]*b[0], 
       a[3]*b[3] + a[2]*b[1], 
       b[4] + a[5]*b[2] + a[4]*b[0], 
       b[5] + a[5]*b[3] + a[4]*b[1] 
      ]; 
     } 
     function rotate(ang) { 
      ctm = matrix_mul(ctm, [Math.cos(ang), Math.sin(ang), -Math.sin(ang), Math.cos(ang), 0.0, 0.0]); 
     } 
     function paint_point(x, y) { 
      var x = ctm[0]*x + ctm[2]*y + ctm[4]; 
      var y = ctm[1]*x + ctm[3]*y + ctm[5]; 
      ctx.fillRect(x, y, 1, 1); 
     } 
     function square() { 
      for (i = 0; i <= 100; ++i) { paint_point(150+i, 150); } 
      for (j = 0; j <= 100; ++j) { paint_point(150, 150+j); 
             paint_point(250, 150+j); } 
      for (i = 0; i <= 100; ++i) { paint_point(150+i, 250); } 
     } 


     square(); 
     for (d=0; d<3; ++d) { 
      rotate(Math.PI/14); 
      ctx.fillStyle = 'rgb(0, ' + d+30*40 + ', 0)'; 
      square(); 
     } 

     ctm = [1.0, 0.0, 0.0, 1.0, 0.0, 0.0]; 
     ctx.fillStyle = 'rgb(0, 0, 255)'; 
     rotate(Math.PI/14 * 3); 
     square(); 

    } else { 
     alert("Something bad happend"); 
    } 
}; 

答えて

1

単純なタイプミスが、彼らはすでに引数として定義されています。ここでは主要部分です。したがって、xは、最初の行で修正され、2行目は、xの間違った値を使用します。

修正が簡単です。

function paint_point(x, y) { 
    var x1 = ctm[0]*x + ctm[2]*y + ctm[4]; 
    var y1 = ctm[1]*x + ctm[3]*y + ctm[5]; 
    ctx.fillRect(x1, y1, 1, 1); 
    } 

またはそれ以上

function paint_point(x, y) { 
    ctx.fillRect(
     ctm[0]*x + ctm[2]*y + ctm[4], 
     ctm[1]*x + ctm[3]*y + ctm[5], 
     1, 1 
    ); 
    } 
+0

私は複数の言語で、この小さなプログラムを再実装し、同じ問題が一つ一つの時間をトリミングして、複数のシステムを使用して、それをレンダリングする数日を費やしてきました。私はこの問題がこれと同じ単純なバグだとは思っていませんでした。後見では明らかだったはずです。これを指摘するのに十分なことはありません。私は明日のあなたの答えを受け入れるでしょう! – Doe

+0

あなたが答えに満足しているなら、[accepting](http://stackoverflow.com/help/accepted-answer)it ..を考えてみてください! – TaW

関連する問題