2017-03-07 8 views
1

私は3Dジオメトリを使ってPHPで作業しています。 私は、x、y、zの値を持つKコプレーナ3Dポイントを持っています。一緒にポリゴンを形成します。このポリゴンを三角形分割する必要があります。 2Dポリゴンのために働く、すでに働いているdelaunay traingulation関数を持っています。 私は与えられた点を回転させて、x、y平面に平行な平面に置くようにします。その後、x、yの値を使って三角形分割できます。次の擬似コードは、私がこの目標に到達する方法を説明します。K面の点をx、y面に平行な面に回転させます

私はこれを参照して以下のコードを作成します(私はOPから受理した答えを使用しています):https://math.stackexchange.com/questions/180418/calculate-rotation-matrix-to-align-vector-a-to-vector-b-in-3d、しかし期待通りに動作しません。それが成功したかどうかを知るために、すべてのマッピングされたポイントは、同じ 'z'値を持ちます。 ここに質問がありますが、正しい回転行列を取得するにはどうすればよいですか?それとも、私は概念的な間違いをしましたか?

function matrixRotationMapping(Point $p, Point $q, Point $r) 
     { 
      $normalPolygon =calculatePlaneNormal($p, $q, $r); 
      $v = crossProduct($normalPolygon, new Point(0, 0, 1)); 
      $c = dotProduct($normalPolygon, new Point(0, 0, 1)); 
      $matrix = buildRotationMatrix($v, $c);  
      return $matrix; 
     }  

function buildRotationMatrix($v, $c) 
     { 
      $R2 = new Matrix(array(array(1, -$v->z, $v->y), array($v->z, 1, -$v->x), array(-$v->y, $v->x, 1))); 
      $costant = 1/(1+$c); 
      $R3 = multiplyMatrices($R2, $R2); 
      $R3 = multiplyMatricesWithFactor($R3, $costant); 
      $finalMatrix = sumMatrices($R2, $R3); 
      return $finalMatrix; 
     } 

function calc2DMapping($points) 
     { 
      $rotationMatrix = matrixRotationMapping($points[0], $points[1], $points[2]); 
      foreach($points as $point) 
       { 
        $mappedPoint = $rotationMatrix->multiplyWithPoint($point);    
        $mappedPoints[] = new MappedPoint($mappedPoint); 
       }  
     } 

私はこの問題の別の有用な記述を見つけましたが、私はそれを実装することができませんでした:あなたの注意を事前にMapping coordinates from plane given by normal vector to XY plane

感謝を。

答えて

0

まず、基本ベクトルX,Y,Zが必要です。だから中点Aとそれに2つの遠方の点を最初のデータセットからB,C(1行ではない)とする。 X,Yは、平面内に存在すべきであるとZはそれに垂直でなければなりません:

X = B-A  // any non zero vector inside plane 
X = X/|X| // unit in size 

Y = C-A  // any non zero vector inside plane 
(X.Y) != 0 // but not parallel to X !!! 
Y = Y/|Y| // unit in size 

あなたのポイントをY軸に、正しい嘘面の法線を計算。

Z = X x Y // cross product gives you perpendicular vector 
Y = Z x X // now all vectors are perpendicular and unit 

だからあなたtransform matrixの回転部分にこれらの3つのベクトルを供給し、Aに起源を設定します。しかし、あなたが飛行機に設定してデータから行く必要があるとして、ローカル座標あなたが逆行列を必要とする(または転置に基づく擬似逆を使用)

とにかく今基底ベクトルであなたはパラメトリックにこのようなあなたの飛行機をマッピングすることができます

P(u,v) = A + u*X + v*Y 

ここで、u,v = <-inf,+inf>は、X,Yの方向にAの面間隔です。時には便利なことがあります。また、代わりに行列を使用するのでは2Dに変換するために使用することができます

u = ((P-A).X) = dot(P-A,X) 
v = ((P-A).Y) = dot(P-A,Y) 
...

+0

こんにちは、私は申し訳ありませんが、私はドン」:あなたはPからu,vを計算する必要がある場合は、ドット積を利用します完全にあなたのソリューションを得る。私はすでにすべての点が同じ平面上にあることを知っています。平面の法線と方程式を簡単に見つけることができます。私がしたいことは、すべての点を標準X、Y平面に平行な平面に、また(0,0,1)ベクトルで定義された平面に回転/マップすることです。 – Swisx

+0

@Swisx最後の方程式はあなたに 'u、v'を与えます。回転した点の' x、y'座標として使うことができます 'P' ...' z = 0'何が不明ですか? (あなたはベクトル数学を理解していないのですか?具体的には何ですか?) – Spektre

+0

2番目の説明のためのタク、最後の部分では、私はあなたが何を意味したのか分かりませんでした。しかし、私はそれを得て、私はそれを実装することができます知っている。それは、ポイントがx、y平面に直交する平面上にある場合、エッジケースでも機能しているようです。どうもありがとうございました。 – Swisx

関連する問題