Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS3 Matrix rotation

Tags:

I have a CSS 3D cube that I'm trying to rotate left/right/up/down straight as it appears to user. If I use css rotation functions, then I rotate the axis, not the cube.

There are lots of articles on the web about X,Y,Z matrix rotation calculation, but I've spend days now trying to set this thing and none of this information really helps me.

The work around to my problem would be a WebKitCSSMatrix object, which has its own rotation functions that work as magic. An example on Fiddle: http://jsfiddle.net/joecritch/tZBDW/. But again, that relies only uppon Webkit, but I need to be crossbrowsy here.

Now, there are 3 steps on the way of success:

1) I need to get current matrix, set directional vector (1,0,0 for up/down and 0,1,0 for left/right rotations) and set the angle. DONE.

2) I need to calculate new rotation vector based on current matrix. DONE.

3) I need to actually rotate my current matrix by new vector and angle. PROBLEM.

var newMArray = deMatrix(".cube");//getting current matrix from CSS  var v = [vecX, vecY, vecZ, 0];//current vector (1,0,0) or (0,1,0)  var newV = newMVector(newMArray, v);//calculating new vector for current matrix  //getting the angle for each axis based on new vector angleX = newV[0]*angle; angleY = newV[1]*angle; angleZ = newV[2]*angle;  this.rotateX -= angleX; this.rotateY -= angleY; this.rotateZ -= angleZ;   //calculating the rotation matrix var rotationXMatrix, rotationYMatrix, rotationZMatrix, s, transformationMatrix; rotationXMatrix = $M([[1, 0, 0, 0], [0, Math.cos(this.rotateX * deg2rad), Math.sin(-this.rotateX * deg2rad), 0], [0, Math.sin(this.rotateX * deg2rad), Math.cos(this.rotateX * deg2rad), 0], [0, 0, 0, 1]]); rotationYMatrix = $M([[Math.cos(this.rotateY * deg2rad), 0, Math.sin(this.rotateY * deg2rad), 0], [0, 1, 0, 0], [Math.sin(-this.rotateY * deg2rad), 0, Math.cos(this.rotateY * deg2rad), 0], [0, 0, 0, 1]]); rotationZMatrix = $M([[Math.cos(this.rotateZ * deg2rad), Math.sin(-this.rotateZ * deg2rad), 0, 0], [Math.sin(this.rotateZ * deg2rad), Math.cos(this.rotateZ * deg2rad), 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]);  transformationMatrix = rotationXMatrix.x(rotationYMatrix).x(rotationZMatrix);//getting all axis rotation into one matrix 

Than I'm setting new transformation matrix to my CSS Cube. The problem is - it doesn't rotate as it should. Now I'm using Sylvester plugin to do all matrix calculation.

So, please help me on how to use my new vector for proper matrix rotation.

like image 893
Alex Under Avatar asked Nov 16 '12 04:11

Alex Under


People also ask

Which CSS3 property can help us to rotate an element by 120 degrees?

The transform property applies a 2D or 3D transformation to an element. This property allows you to rotate, scale, move, skew, etc., elements.

How is the CSS transformation matrix method used?

The CSS matrix() function can be used with CSS transforms to style elements in a two-dimensional space. The matrix() function is an alternative to the two-dimensional transform functions rotate() , skew() , scale() , and translate() . In other words, you can use the matrix() function instead of those functions.

What is Matrix CSS?

The matrix() CSS function defines a homogeneous 2D transformation matrix. Its result is a <transform-function> data type.


1 Answers

I am having a very hard time following your code. But if I understand it correctly you are going around a basic problem really backwards.

Your starting point is an object that has a matrix transform. You want to change that transform. At this point it is very tempting to just try things and see what sticks. No offense, but that is what your code looks like it is doing. What you really need is to understand how matrices work. There are lots of good tutorials. (first google hit: http://chortle.ccsu.edu/vectorlessons/vectorindex.html) It will take some time but help a lot in the long run.

The basic issue you are facing is that matrix multiplication is no commutative. A * B != B * A for matrices. Depending on what matrix you are setting it includes a lot of transformations where order matter: (A) Move the object to it's origin (B) Rotate the object around it's origin (C) Move the object to a position in the world (D) Move the object to where the camera is at the origin (E) Rotate around the camera. The matrix you see is just A * B * C * D * E. Now depending on what you want to do you better have a good plan. In most cases you either want to rotate the object or the camera and you can just multiply either on the left or right side. Your code looks a little bit like you are multiplying on the wrong side and trying to jump through hoops to compensate for that which somewhat works because a lot of the matrices are identity.

So even more practical: Get your cube matrix, make a rotation matrix independent of it (no -angle!), and set back rotation*cubematrix as your new transform.

like image 68
starmole Avatar answered Oct 13 '22 21:10

starmole