# ShapeJS Developer Tutorials

Debugging

## Transforms

So you have a list of primitives to work with, but what if they are not in the right place? What if they need to face a different way, or stretch? Transformations are the first step in turning a primitive into something more interesting. In this tutorial we will learn how to use simple transformations to move, rotate, scale, and twist data sources.

The first concept to understand for transformations is the coordinate system we are using. ShapeJS uses a right handed Y-UP system. ```function main(args) {
var radius = 20 * MM;
var s = 20*MM;
return new Scene(sphere, new Bounds(-s,s,-s,s,-s,s));
}
```
###### Try it!

Not much to look at. But this shape will make it easy to see the transformations.

### 1. Translate

The translate function allows you to move any data source by applying a 3D vector to it. Since some shapes automatically center at the origin, this is helpful in relocating those data sources to where you want them.

```function main(args) {
var torus = new Torus(4*MM, 1*MM);
var translate = new Translation(new Vector3d(-5*MM, -5*MM, 8*MM));
torus.setTransform(translate);
var s = 10*MM;
return new Scene(torus, new Bounds(-s,s,-s,s,-s,s));
}
```

### 2. Scale

We can also scale the data source. In this case we are doing a non uniform scale, to create a severe distortion. Here we can see that a fundamental change has happened to our shape: we could not make this simply using different options for the Torus.

```function main(args) {
var torus = new Torus(4*MM, 1*MM);
var scale = new Scale(1.5, 1, 1);
torus.setTransform(scale);
var s = 10*MM;
return new Scene(torus, new Bounds(-s,s,-s,s,-s,s));
}
```
###### Try it!

(Note: Certain kinds of shapes, such as planes or cones, go to infinity in one or more directions, so scaling them will not have the same effect, and may look more like translations.)

### 3. Rotate

Rotation is useful for a lot of shapes, like the Torus, which start out facing a specific direction. We can use the Rotation transform in order to turn the object, in radians, around a specific axis. This lets us tell it to face the direction we actually want it to.

```function main(args) {
var torus = new Torus(4*MM, 1*MM);
var axis = new Vector3d(0, 1, 0);
var rotate = new Rotation(axis, Math.PI/3);
torus.setTransform(rotate);
var s = 10*MM;
return new Scene(torus, new Bounds(-s,s,-s,s,-s,s));
}
```
###### Try it!

We can also change the center for rotation, which is where the axis extends from. By default, the data source will simply rotate around the origin. But by changing its rotation center, we can change the end result dramatically.

```function main(args) {
var torus = new Torus(4*MM, 1*MM);
var axis = new Vector3d(1,2,0);
var rot_center = new Vector3d(-1*MM, -5*MM, 10*MM);
var rotate = new Rotation(axis, Math.PI/3, rot_center);
torus.setTransform(rotate);
var s = 10*MM;
return new Scene(torus, new Bounds(-s,s,-s,s,-s,s));
}
```
###### Try it!

The new rotation axis, even with the same actual rotation, has resulted in our Torus going outside the Bounds of the scene, hence the red. As always, you can fix this by upping the size of the Bounds.

```function main(args) {
var torus = new Torus(4*MM, 1*MM);
var axis = new Vector3d(1, 2, 0);
var rot_center = new Vector3d(-1*MM, -5*MM, 10*MM);
var rotate = new Rotation(axis, Math.PI/3, rot_center);
torus.setTransform(rotate);
var s = 11*MM;
return new Scene(torus, new Bounds(-s,s,-s,s,-s,s));
}
```

### 4. Twist

This transform performs a twist of space via rotation about z-axis. Try a twist on a simple box.

```function main(args) {
var box = new Box();
var twist = new Twist(0.01);
box.setTransform(twist);
var s = 10*MM;
return new Scene(box, new Bounds(-s,s,-s,s,-s,s));
}
```

(Note: A lower value means a higher rate of twist. Be careful that the data source does not become too thin.)

###### Try it!

Now let's apply a twist on a torus.

```function main(args) {
var torus = new Torus(4*MM, 1*MM);
var twist = new Twist(0.01);
torus.setTransform(twist);
var s = 10*MM;
return new Scene(torus, new Bounds(-s,s,-s,s,-s,s));
}
```
###### Try it!

There doesn't seem to be much of a twist. This is because the function twists around the same axis the torus is facing, the Z axis. The torus is completely symmetrical in that direction, so the twist will do nothing to visibly change its shape no matter what we set it to. In order to see the twist, we will need to rotate the shape first, so that it is not aligned with the Z axis. To do that, we need to learn how to apply multiple transformations to a single data source.

### 5. Composite Transform

Trying to use setTransform () to perform multiple transformations on your objects will not work. ShapeJS will only pay attention to the latest applied transform. If you need to apply multiple transformations to an data source, you will need to create a CompositeTransform() and apply it to the data source. To get a nice twist to the torus, we are going to need to rotate it first, so that when the twist takes effect it will not be in line with the torus.

```function main(args) {
var torus = new Torus(4*MM, 1*MM);
var compTransform = new CompositeTransform();