如何逆向工程一个webkit的矩阵3D变换

6

我有一个在三维空间中旋转和平移的立方体元素。

我想要找到在给定时间内仅仅是rotateY部分的变换。这可能吗?

我有:

var cube = document.getElementById("cube");
var transform = getComputedStyle(cube).webkitTransform;

//the value of transform is:
// matrix3d(-1, 0, 0.00000000000000012246467991473532, 0, 
//           0, 1, 0, 0, 
//          -0.00000000000000012246467991473532, 0, -1, 0, 
//           0, 0, 0, 1)

需要帮忙吗?:-)


获取变换的y值?您可能需要查看translate()。它将矩阵形式转换为值。更多信息请参见此处的translate transformation - Ikmal Ezzani
也许我没有理解清楚,但是我被这个matrix3d卡住了,变换是由别人的代码为我应用的。我只是想看看能否找回旋转Y。 - Matt H.
我误解了,以为你想使用transform的值来做一些事情。请忽略评论。我在这个链接上找到了一个函数Read getRotationDegrees。并且在上面的链接中读取哪个值属于Y,并使用他们使用该函数的方法来获取Y度数。如果您还没有得到答案,我今晚稍后会继续阅读。很抱歉我帮不上太多忙。我在去上班的路上 :) - Ikmal Ezzani
3个回答

4
如果您的对象只是绕Y轴旋转,那么是的,旋转是简单计算的 - 它是矩阵元素1,1或3,3的反余弦或-(元素3,1)的反正弦或元素1,3的反正弦。在您的特定示例中,它大约是180度。如果旋转不仅仅是关于y轴的,则必须开始跟踪先前的旋转,并且可能会变得更加混乱。
在本例中,您的翻译只是输出矩阵的底行,即0,0,0。
请查看以下示例:http://www.inversereality.org/tutorials/graphics%20programming/3dwmatrices.html

嗯,这是一个七年前的帖子。您可以在archive.org上使用wayback机器来查看其缓存版本。这是来自wayback机器的2011年版本:https://web.archive.org/web/20110127040842/http://www.inversereality.org/tutorials/graphics%20programming/3dwmatrices.html - Ruan Caiman

4
您可以使用“new WebKitCSSMatrix”函数检索变换信息。例如:
var matrix = new WebKitCSSMatrix($('#element').css('-webkit-transform'));
var translateZ = matrix.m43;

每个矩阵的部分在这里都有解释:http://9elements.com/html5demos/matrix3d/。您可以获取更复杂的属性,例如rotationX,在使用数学乱搞的3D矩阵中:
var rotationX = Math.acos(matrix.a) * (180/Math.PI);
var rotationY = Math.asin(matrix.b) * (180/Math.PI);

3
给定的函数确定了给定DOM元素的旋转,变换和缩放,跨浏览器。
如果您想要更多内容或发现数学错误,请在math.stackexchange.com上讨论。
http://caniuse.com/transforms3d中列出的浏览器上进行了测试。
var reverseEngineerTransform3d = function (domElement, parameterName) {

        parameterName = parameterName.toLowerCase();

        var computedStyle = window.getComputedStyle(domElement),
            matrixStyle = computedStyle.transform || computedStyle.WebkitTransform || computedStyle.MozTransform || computedStyle.msTransform || computedStyle.OTransform;

        if (matrixStyle) {
            matrixStyle = matrixStyle.trim();
        }

        if (matrixStyle === 'none') {
            if (parameterName.indexOf('rotate') === 0) {
                return '0deg';
            } else if (parameterName.indexOf('translate') === 0) {
                return '0px';
            } else if (parameterName === 'scale') {
                return 1;
            } else {
                throw "Unsupported 3D parameter " + parameterName;
            }
        }

        else if (!matrixStyle || matrixStyle.substr(0, 9) !== 'matrix3d(') {
            //return something or die ?????
            throw "Something is wrong with 3D transform style. Probably no style applied at all OR unknown CSS3 vendor OR unknown/unsupported 3D matrix representation string OR CSS3 3D transform is not fully supported in this browser";
        }

        var matrix = window.WebKitCSSMatrix && (new WebKitCSSMatrix(matrixStyle)) ||
                window.MozCSSMatrix && (new MozCSSMatrix(matrixStyle)) ||
                window.MsCSSMatrix && (new MsCSSMatrix(matrixStyle)) ||
                window.OCSSMatrix && (new OCSSMatrix(matrixStyle)) ||
                window.CSSMatrix && (new CSSMatrix(matrixStyle)); // sorry 4 copy-paste my friends

        if (!matrix || isNaN(matrix.a) || isNaN(matrix.b) || isNaN(matrix.c) || isNaN(matrix.m41) || isNaN(matrix.m42) || isNaN(matrix.m43) || isNaN(matrix.m11)) {
            throw "Could not catch CSSMatrix constructor for current browser, OR the constructor has returned a non-standard matrix object (need .a, .b, .c and mXX numerical properties to work)";
        }


        // todo: giving a parameters array (and returning an array) is a good idea, or we could return everything if no parameters given

        switch (parameterName) {

            case 'rotatey':  // in degrees
                return Math.acos(matrix.m11)*180/Math.PI * (matrix.m13 > 0 ? -1 : 1) + 'deg';

            case 'rotatex':  // in degrees
                return Math.asin(matrix.m22)*180/Math.PI + 'deg';

            case 'rotatez':  // in degrees
                throw "TODO: Sorry, math people. I really need help here! Please implement this case for me. This will help you: http://9elements.com/html5demos/matrix3d/";

            case 'translatex': // in pixels
                return matrix.m41 + 'px';

            case 'translatey': // in pixels
                return matrix.m42 + 'px';

            case 'translatez': // in pixels
                return matrix.m43 + 'px';

            case 'scale': // no units
                if (matrix.m11 === matrix.m22 && matrix.m22 === matrix.m33) {
                    return matrix.m11;
                } else {
                    throw "I'm not so smart to calculate scale from this matrix";
                }

           // todo: anything else? skew ????

            default:
                throw "This function accepts 3d-parameter name (case-insensitive string) as the second argument. Currently supported: 'rotate[xyz]', 'translate[xyz]', 'scale'. This parameter is unsupported: " + parameterName;
        }
    };

1
一个数学能力更强的人可以扩展功能的可能性。一旦我们有了矩阵,就可以反向工程很多东西。 - Dan
// 待办事项:我将很快处理的好文章:http://css-tricks.com/get-value-of-css-rotation-through-javascript/ - Dan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接