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],
];
Tagged #mathematics, #programming, #js, #graphics. All content copyright James Fisher 2020. This post is not associated with my employer.