# Using Linear Transformations In PaperJS

I was recently developing a 2D board game and wanted to skew and rotate the game board to give it a more 3D look. After skewing the board though, I wasn’t able to easily place the game pieces at the correct positions. I didn’t want to manually position the game pieces, because that would mean I couldn’t easily change the skew and rotation of the board.

Since I was using PaperJS, it was easy to skew and rotate the game board…

```
// Create the basic shapes
let boardSpaces = [new Shape(...), ...]
let boardBase = [new Shape(...)];
// Group them and then transform them with
// skew and rotation.
let board = new Group(boardBase.concat(boardSpaces));
board.transform(new Matrix(1.0, 0.0, 0.3, 1.0, 0.0, 0.0));
board.rotation = 146.98;
```

The problem was, if I queried PaperJS for the position of a game space, the return value was the position in the board’s transformed space. So if I tried to place an object in the global context at the same position as a game space, it didn’t line up with the game space (Remember they’re both in two different coordinate systems.)

```
// Get the item named "1,1", which is a board space.
let boardSpacePosition = project.getItem({name : "1,1"});
// This position is not where you think it is.
console.log(boardSpacePosition.position);
```

So what I needed to do was transform the game space’s position into the global coordinate system. To do that, I used the matrix property on the Group I created earlier.

```
var globalPosition = board.matrix.transform(
boardSpacePosition.bounds.center
);
```

Then I was able to use the globalPosition Point to place a game piece at the same position as a game space in the global coordinate system.

## Transforming Coordinates Without PaperJS

Before I started using PaperJS, I was using the HTML5 canvas and worked out the transformations that converts a point in one coordinate system to the coordinate system of another. The HTML5 Game Canvas uses the following matrix transformation in it’s transform function.

```
HorizontalScaling, VerticalSkewing, HorizontalMoving
HorizontalSkewing, VerticalScaling, VerticalMoving
0, 0, 1
transform(HorizontalScaling, HorizontalSkewing, VerticalSkewing, VerticalScaling, HorizontalMoving, VerticalMoving)
```

In my game, I as using `transform(1.0, 0.0, 0.3, 1.0, 0.0, 0.0)`

. If we convert

that into a matrix and multiply by [x,y,0] we get…

```
[1.0, 0.3, 0.0, [x,
0.0, 1.0, 0.0, y,
0.0, 0.0, 1.1] 0]
```

And if we simplify…

```
[1.0, 0.3, [x,
0.0, 1.0] y]
```

This matrix transforms points from regular space into a skewed coordinate space. This means, we can take take the global x and y position and get the new coordinates by multiplying the two matrices together.

```
newX = 1x + .3y
newY = 0x + y
```

If we want to think more generally, the equation is..

```
newX = (hscale * x) + (vskew * y)
newY = (hskew * x) + (vscale * y)
```

And if we want to transform a point into a rotated coordinate space, we can multiply our global point by the rotation matrix transformation.

```
[ cos a, -sin a [x,
, sin a, cos a] y]
newX = (cos a) * x + (sin a) * y
newY = -(sin a) * x + (cos a) * y
```