Page 1 of 1

Matrix rotation, scaling, translation help.

Posted: Thu Mar 19, 2009 1:44 pm
by Peanut
In my opengl engine I use matrices to rotate,scale and translate my vertexes.

I have tried rotating a cube by applying a matrix to each cube vertex each frame.

It rotates okay. But turns the cube into a quad.
So perhaps my math isn't correct.

Would someone who's proficient in matrix operations look if these calculations are correct?

Thanks.

Code: Select all

<script>
var rotatex = new Array(4);
rotatex[0] = new Array(4);
rotatex[1] = new Array(4);
rotatex[2] = new Array(4);
rotatex[3] = new Array(4);

var rotatey = new Array(4);
rotatey[0] = new Array(4);
rotatey[1] = new Array(4);
rotatey[2] = new Array(4);
rotatey[3] = new Array(4);

var rotatez = new Array(4);
rotatez[0] = new Array(4);
rotatez[1] = new Array(4);
rotatez[2] = new Array(4);
rotatez[3] = new Array(4);

var translate = new Array(4);
translate[0] = new Array(4);
translate[1] = new Array(4);
translate[2] = new Array(4);
translate[3] = new Array(4);

var scale = new Array(4);
scale[0] = new Array(4);
scale[1] = new Array(4);
scale[2] = new Array(4);
scale[3] = new Array(4);

var xrot=180;
var yrot=0;
var zrot=0;

var movex =-5;
var movey = 0;
var movez = 0;
var scalex = 100;
var scaley = 100;
var scalez = 100;

var i = (Math.PI/180);
 var vertex = new Object();
  vertex.x = 1.0;
  vertex.y = 6.0;
  vertex.z = 1.0;
//xrot
rotatex[0][0] = 1; rotatex[0][1] = 0; rotatex[0][2] = 0; rotatex[0][3] = 0;
rotatex[1][0] = 0; rotatex[1][1] = Math.cos(xrot*i); rotatex[1][2] = Math.sin(xrot*i); rotatex[1][3] = 0;
rotatex[2][0] = 0; rotatex[2][1] = Math.sin(xrot*i); rotatex[2][2] = Math.cos(xrot*i); rotatex[2][3] = 0;
rotatex[3][0] = 0; rotatex[3][1] = 0; rotatex[3][2] = 0; rotatex[3][3] = 1;
//yrot
rotatey[0][0] = Math.cos(yrot*i); rotatey[0][1] = 0; rotatey[0][2] = Math.sin(yrot*i); rotatey[0][3] = 0;
rotatey[1][0] = 0; rotatey[1][1] = 1; rotatey[1][2] = 0; rotatey[1][3] = 0;
rotatey[2][0] = Math.sin(yrot*i); rotatey[2][1] = 0; rotatey[2][2] = Math.cos(yrot*i); rotatey[2][3] = 0;
rotatey[3][0] = 0; rotatey[3][1] = 0; rotatey[3][2] = 0; rotatey[3][3] = 1;
//zrot
rotatez[0][0] = Math.cos(zrot*i); rotatez[0][1] = Math.sin(zrot*i); rotatez[0][2] = 0; rotatez[0][3] = 0;
rotatez[1][0] = Math.sin(zrot*i); rotatez[1][1] = Math.cos(zrot*i); rotatez[1][2] = 0; rotatez[1][3] = 0;
rotatez[2][0] = 0; rotatez[2][1] = 0; rotatez[2][2] = 1; rotatez[2][3] = 0;
rotatez[3][0] = 0; rotatez[3][1] = 0; rotatez[3][2] = 0; rotatez[3][3] = 1;
//movex movey movez
translate[0][0] = 1; translate[0][1] = 0; translate[0][2] = 0; translate[0][3] = movex;
translate[1][0] = 0; translate[1][1] = 1; translate[1][2] = 0; translate[1][3] = movey;
translate[2][0] = 0; translate[2][1] = 0; translate[2][2] = 1; translate[2][3] = movez;
translate[3][0] = 0; translate[3][1] = 0; translate[3][2] = 0; translate[3][3] = 1;
//scalex scaley scalez
scale[0][0] = scalex/100; scale[0][1] = 0; scale[0][2] = 0; scale[0][3] = 0;
scale[1][0] = 0; scale[1][1] = scaley/100; scale[1][2] = 0; scale[1][3] = 0;
scale[2][0] = 0; scale[2][1] = 0; scale[2][2] = scalez/100; scale[2][3] = 0;
scale[3][0] = 0; scale[3][1] = 0; scale[3][2] = 0; scale[3][3] = 1;

function Matrix_Multiply(mat1, mat2) {
  var i, j, k;
var mat= new Array(4);
mat[0] = new Array(4);
mat[1] = new Array(4);
mat[2] = new Array(4);
mat[3] = new Array(4);
  // For speed reasons, use the unroll-loops option of your compiler
  for(i = 0; i < 4; i++){
    for(j = 0; j < 4; j++){
      for(k = 0, mat[i][j] = 0; k < 4; k++){
        mat[i][j] += mat1[i][k] * mat2[k][j];
}}}
return mat;
}


var mat;
mat = Matrix_Multiply(translate, scale);
mat = Matrix_Multiply(mat, rotatex);
mat = Matrix_Multiply(mat, rotatey);
mat = Matrix_Multiply(mat, rotatez);

function Matrix_Vertex_Multiply(matrix, vert) {
  var v = new Object();

  v.x = Math.round((vert.x * matrix[0][0] + vert.y * matrix[0][1] + vert.z * matrix[0][2] + matrix[0][3])*100)/100;
  v.y = Math.round((vert.x * matrix[1][0] + vert.y * matrix[1][1] + vert.z * matrix[1][2] + matrix[1][3])*100)/100;
  v.z = Math.round((vert.x * matrix[2][0] + vert.y * matrix[2][1] + vert.z * matrix[2][2] + matrix[2][3])*100)/100;

  return v;
}   

function startup(){
vertex = Matrix_Vertex_Multiply(mat, vertex);
document.getElementById( 'box1' ).value = "" + vertex.x + " " + vertex.y + " " + vertex.z;
}

</script>
<body>
<input>
</body>



This is de code I use converted to a html file driven with javascript.

Just put everything between the code tags in a .html file to test it.

Posted: Thu Mar 19, 2009 4:55 pm
by joo
Uh... and why was it neccesary to convert to JS?

What was it in before? C? Java?

I'll take a look at the code, but I'm making no promises -- I don't know much of matrix tranformations... at least, in the traditional sense.

Posted: Thu Mar 19, 2009 5:34 pm
by Peanut
I was looking at matrix rotations at work. And made this script depending on the formulas I found.

Posted: Sat Mar 21, 2009 4:27 pm
by Peanut
Well I've solved it.
I was missing three - to make those sin cos values negative.

Now I'd like for people to test how well my code works on different pc specs.

clicky

Here's a spinning cube example.
Could you tell me the specs you have and the fps you get in the title bar?
Thanks

(To be sure please scan the zip file first with a virus scanner)