Единственное, что всегда мешало мне заниматься 3D-программированием, это не понимать, как работает математика. Я могу согласиться с математикой в программировании, используя методы и функции, тогда мне все понятно и логично, но в математической записи я просто не могу сделать из этого ни головы, ни хвоста.
Я читал веб-сайты, смотрел видео институтов, пытающихся объяснить это, но все они используют математические обозначения, и я просто теряюсь в этом, мой разум не переведет это в нечто понятное. У меня может быть дефект там.
Кроме того, использование чужого кода меня не интересует, я хочу понять механику, стоящую за ним, логику. Я был бы рад использовать чужой код, но я действительно хочу понять, как он работает.
Вопрос
Можете ли вы объяснить мне в простых терминах без математической нотации, просто программируя нотацию/функции /psuedocode, как реализовать матричное преобразование по всем 3 осям?
В идеале мне нужен материал/понимание, чтобы написать метод/объект, в котором я могу определить углы 3-х осей, аналогично glRotate, чтобы вращать коллекцию четырехугольников/треугольников, которые у меня есть. (Я пытаюсь запрограммировать трехмерное вращение фигур куба, не имея доступа к функциям OpenGL, чтобы сделать это для меня, потому что это делается одним вызовом отрисовки каждый раз, когда что-то меняется в списке отображения.)
Что я сделал?
Я попытался сделать функцию преобразования 90 градусов, чтобы получить представление о математике, но не смог создать правильную матрицу, что в теории должно было быть самым простым. Вы можете увидеть мою неудачную попытку во всей ее красе на http://jsfiddle.net/bLfg0tj8/5/
Vec3 = function(x,y,z) {
this.x = x;
this.y = y;
this.z = z;
}
Matrix = function Matrix() {
this.matrixPoints = new Array();
this.rotationPoint = new Vec3(0,0,0);
this.rotationAngle = 90;
}
Matrix.prototype.addVector = function(vector) {
this.matrixPoints.push(vector);
}
Matrix.prototype.setRotationPoint = function(vector) {
this.rotationPoint = vector;
}
Matrix.prototype.setRotationAngle = function(angle) {
this.rotationAngle = angle;
}
Matrix.prototype.populate = function() {
translateToOrigin = [[1,0,0-this.rotationPoint.x],
[0,1,0-this.rotationPoint.y],
[0,0,0-this.rotationPoint.z]];
rotationMatrix = [[0,-1,0],
[0,1,0],
[0,0,1]];
translateEnd = [[1,0,this.rotationPoint.x],
[0,1,this.rotationPoint.y],
[0,0,this.rotationPoint.z]];
currentColumn = 0;
currentRow = 0;
this.combomatrix = this.mergeMatrices(this.mergeMatrices(translateEnd,rotationMatrix),
translateToOrigin);
}
Matrix.prototype.transform = function() {
newmatrix = new Array();
for(c = 0;c<this.matrixPoints.length;c++) {
newmatrix.push(this.applyToVertex(this.matrixPoints[c]));
}
return newmatrix;
}
Matrix.prototype.applyToVertex = function(vertex) {
ret = new Vec3(vertex.x,vertex.y,vertex.z);
ret.x = ret.x + this.combomatrix[0][0] * vertex.x +
this.combomatrix[0][1] * vertex.y +
this.combomatrix[0][2] * vertex.z;
ret.y = ret.y + this.combomatrix[1][0] * vertex.x +
this.combomatrix[1][1] * vertex.y +
this.combomatrix[1][2] * vertex.z;
ret.z = ret.z + this.combomatrix[2][0] * vertex.x +
this.combomatrix[2][1] * vertex.y +
this.combomatrix[2][2] * vertex.z;
return ret;
}
Matrix.prototype.mergeMatrices = function(lastStep, oneInFront) {
step1 = [[0,0,0],[0,0,0],[0,0,0]];
step1[0][0] = lastStep[0][0] * oneInFront[0][0] +
lastStep[0][1] * oneInFront[1][0] +
lastStep[0][2] * oneInFront[2][0];
step1[0][1] = lastStep[0][0] * oneInFront[0][1] +
lastStep[0][1] * oneInFront[1][1] +
lastStep[0][2] * oneInFront[2][1];
step1[0][2] = lastStep[0][0] * oneInFront[0][2] +
lastStep[0][1] * oneInFront[1][2] +
lastStep[0][2] * oneInFront[2][2];
//============================================================
step1[1][0] = lastStep[1][0] * oneInFront[0][0] +
lastStep[1][1] * oneInFront[1][0] +
lastStep[1][2] * oneInFront[2][0];
step1[1][1] = lastStep[1][0] * oneInFront[0][1] +
lastStep[1][1] * oneInFront[1][1] +
lastStep[1][2] * oneInFront[2][1];
step1[1][2] = lastStep[1][0] * oneInFront[0][2] +
lastStep[1][1] * oneInFront[1][2] +
lastStep[1][2] * oneInFront[2][2];
//============================================================
step1[2][0] = lastStep[2][0] * oneInFront[0][0] +
lastStep[2][1] * oneInFront[1][0] +
lastStep[2][2] * oneInFront[2][0];
step1[2][1] = lastStep[2][0] * oneInFront[0][1] +
lastStep[2][1] * oneInFront[1][1] +
lastStep[2][2] * oneInFront[2][1];
step1[2][2] = lastStep[2][0] * oneInFront[0][2] +
lastStep[2][1] * oneInFront[1][2] +
lastStep[2][2] * oneInFront[2][2];
return step1;
}
Matrix.prototype.getCurrentMatrix = function() {
return this.matrixPoints;
}
myvectors = [new Vec3(50,50,0), new Vec3(20,80,0), new Vec3(80, 80, 0)];
function drawVectors(vectors,color) {
for(c=0;c<vectors.length;c++) {
document.getElementById("whoa").innerHTML += '<div style="color:'+color+';position:absolute;left:'+vectors[c].x+'px; top:'+vectors[c].y+'px;z-index:'+vectors[c].z+';">('+c+').</div>';
}
}
matrix = new Matrix();
for(c=0;c<myvectors.length;c++) {
matrix.addVector(myvectors[c]);
}
matrix.setRotationPoint(new Vec3(50,70,0));
matrix.populate();
somematrix = matrix.transform();
drawVectors(matrix.getCurrentMatrix(),"lime"); // draw current matrix that was hand coded
drawVectors([matrix.rotationPoint],'white'); // draw rotation point
drawVectors(somematrix,"red"); // transformed matrix... somehow two points merge
<div id="whoa" style="position:relative;top:50px;left:150px;background-color:green;color:red;width:400px;height:300px;">
</div>