`transform`

function, which can be found in `math.js`

.
```
var cube = {
vertices: [ [-1,-1,1], [1,-1,1], [1,1,1], [-1,1,1], [-1,-1,-1], [1,-1,-1], [1,1,-1], [-1,1,-1] ],
edges: [ [0,1], [1,2], [2,3], [3,0], [4, 5], [5,6], [6,7], [7,4], [3,7], [2,6], [0,4], [1,5] ]
};
```

`var camera = [0,0,-5];`

Keep in mind that the camera is not moving; the objects are moving.

We start with initiating the canvas object. We will set a

`width`

, `height`

, and the colors.
var canvas = document.getElementById("example1"); canvas.width = 650; canvas.height = 400; var ctx = canvas.getContext("2d"); ctx.fillStyle = "#fff"; ctx.strokeStyle = "#000"; var fov = Math.min(canvas.width, canvas.height);Because the canvas is centered in the top-left, and we want it in the center, we apply an offset to the $x$ and $y$ coordinates. In other words, the point $[0,0,0]$ should be in the center of the screen.

var canvasOffsetX = canvas.width / 2; var canvasOffsetY = canvas.height / 2;Then we create a function

`transform`

, that will apply the perspective projection.
var transform = function(v) { var f = fov / v[2]; return [v[0] * f, v[1] * f]; }Another function,

`add`

, which adds two vectors (vector-addition). This is used to add the camera position to the vertex.
var add = function(v,u) { return [v[0] + u[0], v[1] + u[1], v[2] + u[2]]; }This is optional, and can be left out. I am using it to rotate the cube, as animation. If you want to know how it works, Google is your friend.

var rotateY = function(v, angle) { return [v[0] * Math.cos(angle) - v[2] * Math.sin(angle), v[1], v[0] * Math.sin(angle) + v[2] * Math.cos(angle)]; }Finally, the main drawing loop. First we clear the screen. Then we apply the rotation to the cube's vertices. We also want to find the edges, and their vertices, add the camera position, and transform them. Finally, we draw a line between the two transformed points.

var draw = function() { requestAnimationFrame(draw); // Clear the canvas. ctx.fillRect(0, 0, innerWidth, innerHeight); // Rotate the cube. for(var i=0; i < cube.vertices.length; i++) { cube.vertices[i] = rotateY(cube.vertices[i], 0.01); } // Find all the edges, transform the vertices, and draw a line. for(var i=0; i < cube.edges.length; i++) { // Draw cube. var edge = cube.edges[i]; var v = transform(add(cube.vertices[edge[0]], camera)); var u = transform(add(cube.vertices[edge[1]], camera)); ctx.beginPath(); ctx.moveTo(v[0] + canvasOffsetX, v[1] + canvasOffsetY); ctx.lineTo(u[0] + canvasOffsetX, u[1] + canvasOffsetY); ctx.stroke(); } }Having everything in place, we simply call:

draw();

Voila, there it is! Which is also, sadly, the end of the explanation. Because I only wanted to show the basic projection, topics such as drawing the faces, painter's algorithm, and animations are left out.

It is important to note that perhaps the orientation of the coordinate system is flipped, but verifying and fixing that is left as an excercise for the reader.

- Modify the code to add the diagonal edges. The first edge can be added by opening the console (F12), and pasting:
`cube.edges.push([1,6])`

. - If the $\text{fov}=10$, and the camera is at $[0,0,-3]$, calculate all the projected vertices of the cube. Draw all the points on a piece of paper, and connect them.