2017-06-05 12 views
1

行列を3x3回転行列、スケールベクトル、および翻訳ベクトルに分解しようとしています。これは、haskellを使って行います。私はlinearパッケージの行列を使用しています。残念ながら、パッケージは、行列をスケール、回転、および平行移動から作成し、行列からそれらを抽出するのではなく、関数をエクスポートします。したがって、私は自分でそれを行うための関数を書くことにしました。行列を縮尺、回転、および変換で分解する。

しかし、私はそれらをスケーリングせずに行列を使用していますが、私の関数はV3 1.0 1.0 1.0以外のスケールベクトルを返します。

decomposeMatrix $ LA.mkTransformation (LA.Quaternion 1 (LA.V3 1 2 3)) $ LA.V3 1 2 3 

そして、これは私が(あなたが簡単にそれを読むことができるようにフォーマットされた)結果として得るものである:ここで

import qualified Linear.Matrix  as LA 
import qualified Linear.V4   as LA 
import qualified Linear.V3   as LA 
import qualified Linear.Vector  as LA 
import qualified Linear.Quaternion as LA 

import Control.Lens hiding (deep) 

... 

decomposeMatrix :: LA.M44 Double -> (LA.M33 Double, LA.V3 Double, LA.V3 Double) 
decomposeMatrix m = (rot, scale, trans) 
    where trans = (m ^.LA.column LA._w ^. LA._xyz) 
      scale = LA.V3 sx sy sz 
      sx = vecLength (m ^.(LA.column LA._x) ^. LA._xyz) 
      sy = vecLength (m ^.(LA.column LA._y) ^. LA._xyz) 
      sz = vecLength (m ^.(LA.column LA._z) ^. LA._xyz) 
      rot = LA.V3 ((m ^. (LA.column LA._x) ^.LA._xyz) LA.^/ sx) 
         ((m ^. (LA.column LA._y) ^.LA._xyz) LA.^/ sy) 
         ((m ^. (LA.column LA._z) ^.LA._xyz) LA.^/ sz) 

vecLength :: LA.V3 Double -> Double 
vecLength (LA.V3 a b c) = sqrt (a*a + b*b + c*c) 

は、私がGHCiの中でこの機能を実行している方法です

(V3 (V3 (-0.9259259259259259) 0.37037037037037035 7.407407407407407e-2) 
    (V3 (-8.444006618414981e-2) (-0.8021806287494233) 0.5910804632890487) 
    (V3 0.5965499862718936 0.5965499862718936 (-0.5368949876447042)), 
V3 27.0 23.68543856465402 16.76305461424021, 
V3 1.0 2.0 3.0) 

ありがとうございます。

答えて

2

あなたのdecomposeMatrix関数は、(回転行列が必要なものから転置されている以外は)機能しているようです。

大きな問題はテストケースです。使用している四元数(LA.Quarternion 1 (LA.V3 1 2 3)は単位四元数ではないため、LA.mkTransformationは純回転を構築していません。ローテーションとスケーリングの組み合わせを構築しています。ベクトル及び角度からの純粋な回転を表す単位クォータニオンを構築するLA.axisAngleを使用

decomposeMatrix $ LA.mkTransformation (LA.axisAngle (LA.V3 1 2 3) 1) 
       $ LA.V3 1 2 3 

し、そして期待どおりに動作します:例を試みます。

関連する問題