【发布时间】: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