2017-06-05 107 views
1

我正在嘗試使用haskell將矩陣分解爲3x3旋轉矩陣,縮放矢量和平移矢量。我正在使用linear軟件包中的矩陣。不幸的是,該軟件包只導出了用於根據比例,旋轉和平移製作矩陣的函數,而不是從矩陣中提取矩陣。因此,我決定寫一個函數來自己做。將矩陣分解爲與haskell的縮放,旋轉和平移

但是,即使我在使用矩陣而不縮放它們,我的函數也會返回除V3 1.0 1.0 1.0以外的比例向量。

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中運行該功能:

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

這是我所得到的結果(格式化的,所以你可以閱讀更容易):

(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不構建純循環。它構建了旋轉和縮放的組合。嘗試的例子:

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

其使用LA.axisAngle來構建表示從向量和角度的純旋轉的單位四元數,並且如預期它將工作。

相關問題