2017-06-05 176 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来构建表示从向量和角度的纯旋转的单位四元数,并且如预期它将工作。