【问题标题】:Matrix Translation矩阵翻译
【发布时间】:2016-12-10 20:18:47
【问题描述】:

我正在尝试使用 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());

};

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

【问题讨论】:

  • multiplyVector 函数的唯一目的是将矩阵乘以向量,不是吗?您是否应该在其中嵌入所有这些隐藏的功能?这里的实际问题是什么?
  • 我也这么认为,但就像所有给定的测试一样,它们包括函数的名称,例如 multiplyVector,而不是 multiplyVectorTranslate。我想知道是否需要为每个 Translate、rotate 和 scale 设置一个新函数,或者是否可以将向量相乘并在单个 MultiplyVector 函数中包含 translate、rotate 和 scale 操作。
  • 调用multiplyVector 的矩阵中已经包含平移/旋转/缩放数据。将向量乘以变换矩阵就是将变换应用于向量的方式。如果你在函数内部重新生成转换,你会得到不正确的结果。
  • Matrix.prototype.multiplyVector = function (translationVector) { return new Vector(Matrix.createTranslation().getX0 * translationVector.getX() + Matrix.createTranslation().getX1 * translationVector.getY() + Matrix.createTranslation().getX2 * translationVector.getZ()); }; 类似这样,但对于 getY 和 getZ 继续?

标签: javascript linear-algebra vector-multiplication


【解决方案1】:

您在编辑中的代码处于正确的轨道上,但就像我在 cmets 中所说的那样,您与向量相乘的矩阵中已经包含转换信息。您不仅不需要再次生成它,而且这样做会将转换数据更改为您将得到错误输出的程度。

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()
    );
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-14
    • 2011-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-24
    相关资源
    最近更新 更多