矩阵翻译

时间:2016-12-10 20:18:48

标签: javascript linear-algebra vector-multiplication

我正在尝试使用createTranslation函数来转换向量。这必须通过茉莉花测试。

我的矩阵对象:

/*global it, describe, expect, Vector, Matrix*/
/// <reference path="../js/vector.js"/>
/// <reference path="../js/matrix.js"/>
/// <reference path="../Scripts/jasmine.js"/>

var Matrix = (function () {
function Matrix(pX0, pX1, pX2, pY0, pY1, pY2, pZ0, pZ1, pZ2) {

    this.matrix = [
        [pX0, pX1, pX2],
        [pY0, pY1, pY2],
        [pZ0, pZ1, pZ2]
    ];
}
Matrix.prototype.getX0 = function () {
    return this.mX0;
};
Matrix.prototype.setX0 = function (pX0) {
    this.mX0 = pX0;
};
Matrix.prototype.getX1 = function () {
    return this.mX1;
};
Matrix.prototype.setX1 = function (pX1) {
    this.mX1 = pX1;
};
Matrix.prototype.getX2 = function () {
    return this.mX2;
};
Matrix.prototype.setX2 = function (pX2) {
    this.mX2 = pX2;
};


Matrix.prototype.getY0 = function () {
    return this.mY0;
};
Matrix.prototype.setY0 = function (pY0) {
    this.mY0 = pY0;
};
Matrix.prototype.getY1 = function () {
    return this.mY1;
};
Matrix.prototype.setY1 = function (pY1) {
    this.mY1 = pY1;
};
Matrix.prototype.getY2 = function () {
    return this.mY2;
};
Matrix.prototype.setY2 = function (pY2) {
    this.mY2 = pY2;
};


Matrix.prototype.getZ0 = function () {
    return this.mZ0;
};
Matrix.prototype.setZ0 = function (pZ0) {
    this.mZ0 = pZ0;
};
Matrix.prototype.getZ1 = function () {
    return this.mZ0;
};
Matrix.prototype.setZ1 = function (pZ1) {
    this.mZ1 = pZ1;
};
Matrix.prototype.getZ2 = function () {
    return this.mZ2;
};
Matrix.prototype.setZ2 = function (pZ2) {
    this.mZ2 = pZ2;
};
Matrix.prototype.getElement = function (pRow, pColumn) {
    return this.matrix[pRow][pColumn];
};

Matrix.createIdentity = function () {
    return new Matrix(1, 0, 0, 0, 1, 0, 0, 0, 1);
};
Matrix.createTranslation = function (translationVector) {

    return new Matrix(1, 0, translationVector.getX(),
        0, 1, translationVector.getY(), 0, 0, 1);
};
Matrix.createScale = function (scaleVector) {

    return new Matrix(scaleVector.getX(), 0, 0,
        0, scaleVector.getY(), 0, 0, 0, 1);
};
Matrix.createRotation = function (rotation) {

    return new Matrix(Math.cos(rotation), -Math.sin(rotation), 0,
        Math.sin(rotation), Math.cos(rotation), 0, 0, 0, 1);
};

Matrix.prototype.multiplyVector = function (vector) {
    vector = new Vector();
    return new Vector(this.getX0() * vector.getX(),
        this.getX1() * vector.getY(), this.getX2() * vector.getZ(),
        this.getY0() * vector.getX(),
        this.getY1() * vector.getY(), this.getY2() * vector.getZ(),
        this.getZ0() * vector.getX(),
        this.getZ1() * vector.getY(), this.getZ2() * vector.getZ());
};

Matrix.prototype.multiply = function (secMatrix) {
    secMatrix =  this.matrix();
    return new Matrix(this.getX0 * secMatrix.getX0,
        this.getX1 * secMatrix.getY0,
        this.getX2 * secMatrix.getZ0,
        this.getY0 * secMatrix.getX1,
        this.getY1 * secMatrix.getY1,
        this.getY2 * secMatrix.getZ1,
        this.getZ0 * secMatrix.getX2,
        this.getZ1 * secMatrix.getY2,
        this.getZ2 * secMatrix.getZ2);

};
//Matrix.prototype.multiplyVector = function (translationVector,
//secondVector, vector) {

//    return new Vector(this.getX0 * Matrix.createTranslation(translationVector),
//        this.getX1 * Matrix.createTranslation(translationVector),
//        this.getX2 * Matrix.createTranslation(translationVector),
//        this.getY0 * Matrix.createTranslation(translationVector),
//        this.getY1 * Matrix.createTranslation(translationVector),
//        this.getY2 * Matrix.createTranslation(translationVector),
//        this.getZ0 * Matrix.createTranslation(translationVector),
//        this.getZ1 * Matrix.createTranslation(translationVector),
//        this.getZ2 * Matrix.createTranslation(translationVector));
//};
Matrix.prototype.multiplyVectors = function (translationVector,
    vector, secondVector) {

    return new Vector(vector.getX() * Matrix.createTranslation(translationVector),
        vector.getY() * Matrix.createTranslation(translationVector),
        vector.getZ() * Matrix.createTranslation(translationVector),
        secondVector = this.multiplyVector(vector));
};
//Matrix.prototype.multiply = function () {
//    return new Matrix();
//};

return Matrix;

}());

评论部分是我尝试不同的方法来实现这一点。

此对象必须通过以下测试。

describe("Multiply vector", function () {
    describe("Translation", function () {
        var vector, translationVector, matrix, secondVector;
        vector = new Vector(30, 40, 1);
        translationVector = new Vector(10, 20, 1);
        matrix = Matrix.createTranslation(translationVector);
        secondVector = matrix.multiplyVector(vector);
        it("X Set", function () {
            expect(secondVector.getX()).toEqual(40);
        });

        it("Y Set", function () {
            expect(secondVector.getY()).toEqual(60);
        });

        it("Z Set", function () {
            expect(secondVector.getZ()).toEqual(1);
        });
    });
    describe("Rotation", function () {
        var vector, rotation, matrix, secondVector;
        vector = new Vector(30, 40, 1);
        rotation = Math.PI / 2;
        matrix = Matrix.createRotation(rotation);
        secondVector = matrix.multiplyVector(vector);
        it("X Set", function () {
            expect(secondVector.getX()).toBeCloseTo(-40, 1);
        });

        it("Y Set", function () {
            expect(secondVector.getY()).toBeCloseTo(30, 1);
        });

        it("Z Set", function () {
            expect(secondVector.getZ()).toBeCloseTo(1, 1);
        });
    });
    describe("Scale", function () {
        var vector, scaleVector, matrix, secondVector;
        vector = new Vector(30, 40, 1);
        scaleVector = new Vector(2, 2, 1);
        matrix = Matrix.createScale(scaleVector);
        secondVector = matrix.multiplyVector(vector);
        it("X Set", function () {
            expect(secondVector.getX()).toEqual(60);
        });

        it("Y Set", function () {
            expect(secondVector.getY()).toEqual(80);
        });

        it("Z Set", function () {
            expect(secondVector.getZ()).toEqual(1);
        });
    });
});

还有其他旋转测试,但是一旦我弄明白这一点,其余的将会跟随。

我有点坚持这个,因为我不确定我需要做什么,我是否为每个翻译,旋转,缩放创建了更多的功能,还是可以在multiplyVector函数中完成所有功能?

编辑:

Matrix.prototype.multiplyVector = function (translationVector) {

    return new Vector(Matrix.createTranslation().getX0 *        translationVector.getX() +
           Matrix.createTranslation().getX1 * translationVector.getY() +
           Matrix.createTranslation().getX2 * translationVector.getZ(),
           Matrix.createTranslation().getY0 * translationVector.getX() +
           Matrix.createTranslation().getY1 * translationVector.getY() +
           Matrix.createTranslation().getY2 * translationVector.getZ(),
           Matrix.createTranslation().getZ0 * translationVector.getX() +
           Matrix.createTranslation().getZ1 * translationVector.getY() +
           Matrix.createTranslation().getZ2 * translationVector.getZ());

};

我试过这样做,但仍然无法正常工作。

1 个答案:

答案 0 :(得分:2)

你在编辑中的代码是正确的,但就像我在评论中所说的那样,你与矢量相乘的矩阵已经包含了转换信息。您不仅不需要再次生成它,而且这样做会将转换数据更改为您将得到错误输出的位置。

qxz提供的资源:

enter image description here

是将矩阵乘以列向量的正确方法。要在代码中实现它,请执行以下操作:

Matrix.prototype.multiplyVector = function(vector) {
    return new Vector(
        this.getX0() * vector.getX() + this.getX1() * vector.getY() + this.getX2() * vector.getZ(),
        this.getY0() * vector.getX() + this.getY1() * vector.getY() + this.getY2() * vector.getZ(),
        this.getZ0() * vector.getX() + this.getZ1() * vector.getY() + this.getZ2() * vector.getZ()
    );
}