Матричный перевод

Я пытаюсь использовать функцию 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 ответ

Вы находитесь на правильном пути с кодом в вашем редактировании, но, как я сказал в комментариях, матрица, которую вы умножаете на вектор, уже содержит информацию о преобразовании. Вам не только не нужно генерировать его снова, но это изменит данные преобразования до такой степени, что вы получите неправильный вывод.

Ресурс, предоставленный qxz:

правильный способ умножить матрицу на вектор столбца. Чтобы реализовать это в коде, вы делаете следующее:

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()
    );
}
Другие вопросы по тегам