2013-02-22 3 views
4

Поскольку мои знания о матрицах близки к нулю, я искал вспомогательный метод, который мог бы преобразовывать матричный массив в читаемый формат.Преобразование 3D-матрицы в читаемый формат

С читаемом формате, я имею в виду:

{ 
    translate : 
    { 
     x : 0, 
     y : 0, 
     z : 0 
    }, 

    rotation : 
    { 
     x : 0, 
     y : 90, 
     z : 0 
    }, 

    skew : 
    { 
     x : 0, 
     y : 0 
    }, 

    scale : 
    { 
     x : 0, 
     y : 0, 
     z : 0 
    } 
} 

с форматом матрицы Я имею в виду: matrix3d(0.00000000000000006123233995736766, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0.00000000000000006123233995736766, 0, 0, 0, 0, 1).

Я искал Google для такого метода, но не могу найти его.

Есть ли такой метод или как я могу дешифровать/вычислить каждый тип преобразования на каждой доступной оси?

Обновление: Мой друг наткнулся на http://web.iitd.ac.in/~hegde/cad/lecture/L6_3dtrans.pdf, будет изучать это, чтобы попытаться получить хоть что-то.

+0

Эта статья представляет собой довольно полезное объяснение matrix3D https://developer.mozilla.org/en-US/docs/CSS/transform-function, хотя потребовалось бы немало усилий, чтобы использовать эти знания для записи преобразования инструмент. Стоит также отметить, что порядок, в котором выполняются перекосы, поворот и т. Д., Имеет важное значение, т. Е. Вращение, сопровождаемое перекосом, не обязательно такое же, как перекос, за которым следует поворот, поэтому любая читаемая версия матрицы woull должна сделать некоторые явные предположения о том, какое преобразование, как ожидается, будет выполнено сначала – wheresrhys

+0

Хмм, но это относится к перекосу и вращению, не так ли? Если это так, метод может быть сконструирован таким образом, чтобы он принимал параметры для выбора порядка перекоса и вращения. – jolt

+0

yep это могло бы, просто что-то рассмотреть – wheresrhys

ответ

1

Непросто разложить матрицу обратно на исходные преобразования. Мне удалось разложить матрицу scale*rotate*translate.

function extract(m) { // supports only scale*rotate*translate matrix 
    var radians = Math.PI/180 

    var sX = Math.sqrt(m[0]*m[0] + m[1]*m[1] + m[2]*m[2]), 
     sY = Math.sqrt(m[4]*m[4] + m[5]*m[5] + m[6]*m[6]), 
     sZ = Math.sqrt(m[8]*m[8] + m[9]*m[9] + m[10]*m[10]) 

    var rX = Math.atan2(-m[9]/sZ, m[10]/sZ)/radians, 
     rY = Math.asin(m[8]/sZ)/radians, 
     rZ = Math.atan2(-m[4]/sY, m[0]/sX)/radians 

    if (m[4] === 1 || m[4] === -1) { 
     rX = 0 
     rY = m[4] * -Math.PI/2 
     rZ = m[4] * Math.atan2(m[6]/sY, m[5]/sY)/radians 
    } 

    var tX = m[12]/sX, 
     tY = m[13]/sX, 
     tZ = m[14]/sX 

    return { 
     translate: [tX, tY, tZ], 
     rotate: [rX, rY, rZ], 
     scale: [sX, sY, sZ] 
    } 
} 

Но она не будет выполнена в любом другом порядке преобразований.

+0

Любая идея, как вернуть косы тоже? – thednp

+0

Эй, этот код имеет «радианы» как неопределенную переменную, какова будет формула? – thednp

+0

Добавлена ​​переменная «радианы». Вы также можете посмотреть https://github.com/michaelvillar/dynamics.js/blob/master/src/dynamics.coffee#L766-L920. У этого есть более продвинутый метод разложения – 2015-06-24 18:00:04

Смежные вопросы