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.577≈tan(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.866≈cos⁡(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)=[(x−z)cos⁡(a)(x+z)sin⁡(a)+y]Pz(x,y,z)=[(x−y)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)