# Homogeneous coordinates in 3D

Here is an animation of a house. It’s special because it’s drawn using my very own ✨homogeneous coordinates✨ library.

In my previous post, I showed homogeneous coordinates in 2D. I can geometrically visualize homogeneous coordinates for 2D space - the hard part being the projection matrix that warps a 3D space of homogeneous coordinates to create a 1D projection of a 2D space. But my brain melts when trying to visualize how a 4D projection matrix warps 4D space to create a 2D projection of a 3D space. Therefore, for this 3D animation, I reasoned entirely by analogy with my 2D implementation. That said, the conversion from 2D to 3D was clean and mechanical.

Here are the matrices I derived for rotation, scaling, translation and projection. They are in column-major format, which is the only sensible format, and the one used by my 5-line matrix library.

``````const rotateZHom3d = a => [
[ Math.cos(a), Math.sin(a), 0, 0], // x
[-Math.sin(a), Math.cos(a), 0, 0], // y
[0,            0,           1, 0], // z is unchanged
[0,            0,           0, 1], // w is unchanged
];
const rotateXHom3d = a => [
[1,            0,           0, 0], // x is unchanged
[0,  Math.cos(a), Math.sin(a), 0], // y
[0, -Math.sin(a), Math.cos(a), 0], // z
[0,            0,           0, 1], // w is unchanged
];
const rotateYHom3d = a => [
[ Math.cos(a), 0, Math.sin(a), 0],
[0,            1, 0,           0],  // y is unchanged
[-Math.sin(a), 0, Math.cos(a), 0],
[0,            0, 0,           1],  // w is unchanged
];
const scaleSepHom3d = (s) => [
[s[0],     0,    0, 0],  // x
[0,    s[1],     0, 0],  // y
[0,        0, s[2], 0],  // z
[0,        0,    0, 1],  // w
];
const scaleHom3d = s => scaleSepHom3d([s,s,s]);
const translateHom3d = v => [
[   1,    0,    0, 0],  // x
[   0,    1,    0, 0],  // y
[   0,    0,    1, 0],  // z
[v[0], v[1], v[2], 1],  // w
];

// Projects onto the z=1 plane from the origin
const projectHom3d = [
[1,0,0,0], // x is unchanged
[0,1,0,0], // y is unchanged
// Points scaled down in proportion with their distance from the projection plane
[0,0,1,1],
// A point's w-factor is IGNORED. For projection, we're only interested in _direction_ from the origin
[0,0,0,0],
];
``````

What can computers do? What are the limits of mathematics? And just how busy can a busy beaver be? This year, I’m writing Busy Beavers, a unique interactive book on computability theory. You and I will take a practical and modern approach to answering these questions — or at least learning why some questions are unanswerable!

It’s only \$19, and you can get 50% off if you find the discount code ... Not quite. Hackers use the console!

After months of secret toil, I and Andrew Carr released Everyday Data Science, a unique interactive online course! You’ll make the perfect glass of lemonade using Thompson sampling. You’ll lose weight with differential equations. And you might just qualify for the Olympics with a bit of statistics!

It’s \$29, but you can get 50% off if you find the discount code ... Not quite. Hackers use the console!

### More by Jim

Tagged #mathematics, #programming, #js, #graphics. All content copyright James Fisher 2020. This post is not associated with my employer.