To Top

Mar
2016

By synergyseeker

# Learning WebGL 3D: Transformations – Rotation, Scale, Translation

On 20, Mar 2016 | 18 Comments | In 3D, JavaScript, Learning, WebGL | By synergyseeker

So in the first lesson, you learned about setting up the files, getting set up with a 3D helper library and doing your first render. In fact we jumped ahead in that first lesson and did a simple rotation, which is the first of our transformations we are going to look at.

Transforms in math, refer to changing the geometry of an object such that it does not affect the relative “shape” or “internal geometry” of an object. So we can flip things, scale them, rotate them and move them. But we don’t alter the geometry of the object. This is good to understand, because these are examples of things things we can do without having to touch the underlying Object Geometry ( arrays of vertices and normals ). Anyway, let’s get to it….

### Rotation

Let’s set up with our first transform, Rotation. Rotation in most 3D libs uses Radians instead of degrees, which is basically another unit of measure for rotation.
A nice quick conversion can help you if you don’t think in terms of radians. Math.PI/180 is  = 1 degree. So multiply this by degrees you want to rotate. Or you can just use radians. Example Math.PI/180 * 45 is equal to rotating 45 degrees.

Copy the code below into your main.js and run it. You should see a cylinder rotated towards you on the X axis 45 degrees.

```var scene = new THREE.Scene();
var fieldOfView= 45;
var aspect = window.innerWidth / window.innerHeight;
var nearClippingPlane = .1;
var farClippingPlane = 1000;
var camera = new THREE.PerspectiveCamera( fieldOfView, aspect, nearClippingPlane, farClippingPlane );
var renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

var geometry = new THREE.CylinderGeometry( 5, 5, 12, 32 );
var material = new THREE.MeshNormalMaterial();
var obj = new THREE.Mesh( geometry, material );
camera.position.z = 50;
obj.rotation.x=Math.PI/180 *45;

var render = function () {
requestAnimationFrame( render );
renderer.render( scene, camera );
};

render();

```

Cool. So rotation in 3D space can happen on all 3 axis x, y, and z. The Y axis goes straight up and down relative to the camera, and X runs horizontally across the width of your screen. The Z axis is the new one and it runs towards you, like it’s sticking out of the screen. So rotation on an axis turns the object along that axis. To see this in action, lets make something move on all 3 axis.  Let’s use our own easing function using COS to handle some smooth rotation animation.

Add a rot var globally to help us out. Then change the render function as below as well.

```var rot = 0;

var render = function () {
requestAnimationFrame( render );
rot+=.01;
obj.rotation.x = Math.cos(rot)*4;
obj.rotation.z = Math.cos(rot)*-2;
obj.rotation.y = Math.cos(rot)*8;
renderer.render( scene, camera );
};

render();
```

You can see it running here. Super simple, but really cool. We get a really interesting fluid motion, with easing.

### Scale

The next transform we’ll look at is scale.  Set a scale var globally to help out instead of a rot var. Also, let’s add a little baseline 1.2 scale to the range so that the object does not scale negatively. You could, but let’s keep it all pos. for this one. Scaling all 3 axis the same, so it looks to shrink and grow as one, but could easily scale just 1 or 2 axis for a different effect.

```var scale=0;
var render = function () {
requestAnimationFrame( render );
scale+=.01;
obj.scale.x = (Math.cos(scale)) + 1.2;
obj.scale.z = (Math.cos(scale)) + 1.2;
obj.scale.y = (Math.cos(scale)) + 1.2;
renderer.render( scene, camera );
};

```

You can see this in action here.

### Translation

Translation or changing position, is basically, moving things around, in x,y,z space in our 3D world. So let’s make this object move around using our math again. We’re using the techniques covered in Lesson 4, for following a path using COS. But you could use any technique really. The idea is we are updating the X, Y, Z, each render. I added a little rotation on the X axis to make it look more interesting. But the idea is you can combine any of these transforms to create interesting effects of motion, and create your own easing.

Try this out and see how it looks. Keep playing with these concepts and you’ll have objects growing, spinning, flipping and flying all around in no time.

```var angleX = 0;
var angleY = 0;
var speedX = 0.01;
var speedY = 0.05;
var xr = -10; // x radius for elliptical path
var yr = -5 ; // x radius for elliptical path
var cx = 0; // center x
var cy = 0; // center y
var rot=0;

var render = function () {
requestAnimationFrame( render );

// from cos(A) = adj/hyp = x/r OR rewritten as x = r * cos(A)
// from sin(A) = opp/hyp = y/r OR rewritten as y = r * sin(A)
var x = xr * Math.cos(angleX);
var y = yr * Math.cos(angleY);

angleX+=speedX;
angleY+=speedY;

obj.position.x = cx + x ;
obj.position.y = cy + y ;
obj.position.z = cx + x ;

rot+=.01;
obj.rotation.x = Math.cos(rot)*4;

renderer.render( scene, camera );
};
```

Wicked! This looks pretty awesome. Check it out here in case you had any trouble.

That’s enough for now, but check back often for more tutorials as we begin to explore textures, interactive textures and objects and much more.