DEV Community

Cover image for Isometric Projection
anasrin
anasrin

Posted on • Originally published at anasrin.vercel.app

Isometric Projection

TL;DR

This blog post about isometric projection math and code.

From 2D

SR45⁰

Rotate 45°=π445\degree = \frac{\pi}{4} and scale vertical direction with 0.577tan(30°)=tan(π6)=330.577 \approx tan(30\degree) = tan(\frac{\pi}{6}) = \frac{\sqrt 3}{3} .

Preview

Math

a=π/4s=tan(π/6)f(x,y)=[xcos(a)ysin(a)(xsin(a)+ycos(a))s] \begin{aligned} a &= \pi/4\\ s &= tan(\pi/6)\\ f(x,y) &= \begin{bmatrix} x \cos(a) - y \sin(a)\\ (x \sin(a) + y \cos(a)) s \end{bmatrix} \end{aligned}

Code

const ANGLE = Math.PI / 4;
const SCALE = Math.tan(Math.PI / 6);

function sr45(x: number, y: number): [number, number] {
        return [
                x * Math.cos(ANGLE) - y * Math.sin(ANGLE),
                (x * Math.sin(ANGLE) + y * Math.cos(ANGLE)) * SCALE,
        ];
}
Enter fullscreen mode Exit fullscreen mode

SSR30⁰

Scale vertical direction with 0.866cos(30°)=cos(π6)=320.866 \approx \cos(30\degree) = \cos(\frac{\pi}{6}) = \frac{\sqrt 3}{2} , Skew horizontal direction ±30°\pm30\degree , Rotate ±30°\pm30\degree .

Preview

Math

s=cos(π/6)Mscale(x,y)=[100s][xy]=[xys]Mskew(x,y,θ)=[1tan(θ)01][xy]=[x+ytan(θ)y]Mrotate(x,y,θ)=[cos(θ)sin(θ)sin(θ)cos(θ)][xy]=[xcos(θ)ysin(θ)xsin(θ)+ycos(θ)] \begin{aligned} s &= \cos(\pi/6)\\ M_{scale}(x,y) &= \begin{bmatrix} 1 & 0\\ 0 & s \end{bmatrix} \begin{bmatrix} x\\ y \end{bmatrix}\\ &= \begin{bmatrix} x\\ y s \end{bmatrix}\\ M_{skew}(x,y, \theta) &= \begin{bmatrix} 1 & \tan(\theta)\\ 0 & 1 \end{bmatrix} \begin{bmatrix} x\\ y \end{bmatrix}\\ &= \begin{bmatrix} x + y \tan(\theta)\\ y \end{bmatrix}\\ M_{rotate}(x,y,\theta) & = \begin{bmatrix} \cos(\theta) & -\sin(\theta) \\ \sin(\theta) & \cos(\theta) \end{bmatrix} \begin{bmatrix} x \\ y \end{bmatrix} \\ & = \begin{bmatrix} x \cos(\theta) - y \sin(\theta) \\ x \sin(\theta) + y \cos(\theta) \end{bmatrix} \end{aligned}

Code

const ANGLE = Math.PI / 6;
const SCALE = Math.cos(ANGLE);

function scale(x: number, y: number): [number, number] {
        return [x, y * SCALE];
}

function skew(x: number, y: number, angle: number): [number, number] {
        return [x + y * Math.tan(angle), y];
}

function rotate(x: number, y: number, angle: number): [number, number] {
        return [
                x * Math.cos(angle) - y * Math.sin(angle),
                x * Math.sin(angle) + y * Math.cos(angle),
        ];
}
Enter fullscreen mode Exit fullscreen mode

From 3D

Projection

You can directly project 3D point to 2D point and swap the up axis easily.

Preview

Math

a=π/6Py(x,y,z)=[(xz)cos(a)(x+z)sin(a)+y]Pz(x,y,z)=[(xy)cos(a)(x+y)sin(a)+z] \begin{aligned} a &= \pi/6\\ P_{y}(x,y,z) &= \begin{bmatrix} (x - z) \cos(a)\\ (x + z) \sin(a) + y \end{bmatrix}\\ P_{z}(x,y,z) &= \begin{bmatrix} (x - y) \cos(a)\\ (x + y) \sin(a) + z \end{bmatrix} \end{aligned}

Code

const ANGLE = Math.PI / 6;

function upY(x: number, y: number, z: number): [number, number] {
        return [(x - z) * Math.cos(ANGLE), (x + z) * Math.sin(ANGLE) + y];
}

function upZ(x: number, y: number, z: number): [number, number] {
        return [(x - y) * Math.cos(ANGLE), (x + y) * Math.sin(ANGLE) + z];
}
Enter fullscreen mode Exit fullscreen mode

References

Top comments (0)