{"id":15103940,"url":"https://github.com/jehadel/3x3-2d-transformations_demo","last_synced_at":"2026-02-02T22:19:18.713Z","repository":{"id":231592840,"uuid":"781999969","full_name":"Jehadel/3x3-2D-transformations_demo","owner":"Jehadel","description":"Shows 3x3 matrices use for simple 2D transformations (translation, rotation, scaling…)","archived":false,"fork":false,"pushed_at":"2024-12-15T14:37:35.000Z","size":144,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-12-15T15:32:18.790Z","etag":null,"topics":["2d-transformation","computer-graphics","love2d","lua","matrices"],"latest_commit_sha":null,"homepage":"https://jehadel.github.io/3x3-2D-transformations_demo/","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Jehadel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-04-04T12:54:49.000Z","updated_at":"2024-12-15T14:37:39.000Z","dependencies_parsed_at":null,"dependency_job_id":"847ee580-5610-4d88-94ac-aa42dd9c7706","html_url":"https://github.com/Jehadel/3x3-2D-transformations_demo","commit_stats":{"total_commits":24,"total_committers":2,"mean_commits":12.0,"dds":0.125,"last_synced_commit":"49f03efeef9df9b612c711e9e78aea24133e33c4"},"previous_names":["jehadel/3x3-2d-transformations_demo"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jehadel%2F3x3-2D-transformations_demo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jehadel%2F3x3-2D-transformations_demo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jehadel%2F3x3-2D-transformations_demo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jehadel%2F3x3-2D-transformations_demo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Jehadel","download_url":"https://codeload.github.com/Jehadel/3x3-2D-transformations_demo/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230326296,"owners_count":18209039,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["2d-transformation","computer-graphics","love2d","lua","matrices"],"created_at":"2024-09-25T19:43:51.279Z","updated_at":"2026-02-02T22:19:18.554Z","avatar_url":"https://github.com/Jehadel.png","language":"Lua","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 3x3-2D-transformations_demo\nShows 3x3 matrices use for simple 2D transformations (translation, rotation, scaling…)\n\n[You can try the demo online](https://jehadel.github.io/3x3-2D-transformations_demo/)\n\n## The translation problem\n\nAs seen [here](https://github.com/Jehadel/2D_transformations_demo) we can use 2x2 matrices to performs some 2D transformations (rotations, flips…) but this method has major drawbacks : we can’t perform translation, some transformations lead to unwanted translations, and the transformations are relative to the coordinates origin/axes.\n\nHow could we uses matrices to perform translations ?\n\nPoint translation of 10 units along the x axis and 8 units along the y axis, we can just be expressed by :\n\n$$ x_t = x + 10 $$\n\n$$ y_t = y + 8 $$\n\nbut 2x2 matrices can’t express such transformation by multiplication (I will represent coordinates by a row vector, when using a column vector just transpose the matrices used) :\n\n$$ \\begin{bmatrix} x \u0026 y \\end{bmatrix} . \n    \\begin{bmatrix} a \u0026 c \\\\\\ \n    b \u0026 d\\end{bmatrix} = \n    \\begin{bmatrix} x.a + y.b \u0026\n    x.c + y.d\\end{bmatrix} \n$$\n\nEach term is either a multiple of x or a multiple of y. We can’t add a constant.\n\n*Note : Of course, this operation is trivial if we add two 2x1 matrices, but the point here is to limit to product operation only, because we then could chain transformations by chaining multiplications.*  \n\nHowever, if we note that \n\n$$ x + 10 = x.1 + y.0 + 1.10 $$ \n\nwe can write :\n\n\n$$ \\begin{bmatrix}x \u0026 y \u0026 1\\end{bmatrix} . \n    \\begin{bmatrix} 1 \\\\\\ 0 \\\\\\ 10 \\end{bmatrix} = \n    \\begin{bmatrix} x + 10 \\end{bmatrix} \n$$\n\nfor y :\n\n$$ \\begin{bmatrix}x \u0026 y \u0026 1\\end{bmatrix} . \n    \\begin{bmatrix} 0 \\\\\\ 1 \\\\\\ 8 \\end{bmatrix} = \n    \\begin{bmatrix} y + 8 \\end{bmatrix}\n$$\n\nand finally :\n\n$$ \\begin{bmatrix}x \u0026 y \u0026 1\\end{bmatrix} . \n    \\begin{bmatrix} 0 \\\\\\ 0 \\\\\\ 1 \\end{bmatrix} = \n    \\begin{bmatrix} 1 \\end{bmatrix}\n$$\n\nSo, if we accept to add a third term equal to 1 at the coordinates (that will be ignored when drawing figures) we can perform translation with a 3x3 matrix multiplication :\n\n$$ \\begin{bmatrix} x \u0026 y \u0026 1 \\end{bmatrix} . \n    \\begin{bmatrix} 1 \u0026 0 \u0026 0 \\\\\\ \n                0 \u0026 1 \u0026 0 \\\\\\ \n                t_x \u0026 t_y \u0026 1 \\end{bmatrix} =\n    \\begin{bmatrix} x + t_x \u0026 y + t_y \u0026 1\\end{bmatrix}\n$$\n\n2D coordinates with such a third term are called *homogenous coordinates*, with a condition on the third term : \n\n$$\n\\begin{bmatrix} h.x \u0026 h.y \u0026 h \\end{bmatrix}\n$$\n\nh=1 is often a convenient choice in 2D (other values can be better choices in 3D)\n\n## 3x3 matrices for other transformations\n\nFollowing the same process, we can build 3x3 matrices for the transformations seen before :\n\n### Rotation (clockwise)\n\n$$ \\begin{bmatrix} \\cos \\theta \u0026 -\\sin \\theta \u0026 0 \\\\\\\n                   \\sin \\theta \u0026 \\cos \\theta \u0026 0 \\\\\\\n                   0 \u0026 0 \u0026 1 \\end{bmatrix} \n$$\n\n### Rotation (anti-clockwise)\n\n$$ \\begin{bmatrix} \\cos \\theta \u0026 \\sin \\theta \u0026 0 \\\\\\\n                   -\\sin \\theta \u0026 \\cos \\theta \u0026 0 \\\\\\\n                   0 \u0026 0 \u0026 1 \\end{bmatrix} \n$$\n\n*Note : to obtain an anti-clockwise rotation, we could also just use -θ with the clockwise rotation matrix*\n\n### Horizontal flip\n\n$$ \\begin{bmatrix} -1 \u0026 0 \u0026 0 \\\\\\\n                   0 \u0026 1 \u0026 0 \\\\\\\n                   0 \u0026 0 \u0026 1 \\end{bmatrix}\n$$\n\n### Vertical flip\n\n$$ \\begin{bmatrix} 1 \u0026 0 \u0026 0 \\\\\\\n                   0 \u0026 -1 \u0026 0 \\\\\\\n                   0 \u0026 0 \u0026 1 \\end{bmatrix}\n$$\n\n### Scaling\n\n$$ \\begin{bmatrix} S_x \u0026 0 \u0026 0 \\\\\\\n                   0 \u0026 S_y \u0026 0 \\\\\\\n                   0 \u0026 0 \u0026 1 \\end{bmatrix} \n$$\n\n### x-axis shearing/tearing\n\n$$ \\begin{bmatrix} 1 \u0026 0 \u0026 0 \\\\\\\n                   S_x \u0026 1 \u0026 0 \\\\\\\n                   0 \u0026 0 \u0026 1 \\end{bmatrix} \n$$\n\n### y-axis shearing/tearing\n\n$$ \\begin{bmatrix} 1 \u0026 S_y \u0026 0 \\\\\\\n                   0 \u0026 1 \u0026 0 \\\\\\\n                   0 \u0026 0 \u0026 1 \\end{bmatrix} \n$$\n\nAll those 3x3 matrices correspond to axes/origin centered transformations, as with 2x2 matrices. Let’s see how the new possibility of translation can help us to generalise those transformations, via a combination of transformations.\n\n## Generalized transformations\n\nTo process a rotation centered on any point, we just have to follow a 3 steps process : translate the figure to bring the rotation point to the origin, rotate, and translate back the figure to its original position\n\n![Translation exemple](./img/Transformation1.png)\n\nthis 3 steps process is correct for any chosen point, here the bottom left vertex of the rectangle :\n\n![Second translation exemple](./img/Transformation2.png)\n\nHow do we combine those 3 transformations ? By successively applying the corresponding transformation matrices (translation consist to bring the point C - center of the rotation - of coordinates \n\n$$\\begin{bmatrix} C_x \u0026 C_y \\end{bmatrix} $$  \n\nto the origin \n\n$$ \\begin{bmatrix} 0 \u0026 0 \\end{bmatrix} $$\n\nPerform the rotation and then translate back the figure to C. It means that C\u003csub\u003ex\u003c/sub\u003e and C\u003csub\u003ey\u003c/sub\u003e are not only the coordinates of C, but also the parameters of the translation.\n\n$$ \\begin{bmatrix} x \u0026 y \u0026 1 \\end{bmatrix} . T1 . R . T2 = \\\\\n    \\begin{bmatrix} x \u0026 y \u0026 1 \\end{bmatrix} . \n    \\begin{bmatrix} 1 \u0026 0 \u0026 0 \\\\\\ \n                0 \u0026 1 \u0026 0 \\\\\\ \n                -C_x \u0026 -C_y \u0026 1 \\end{bmatrix} .\n    \\begin{bmatrix} \\cos 20\\degree \u0026 \\sin 20\\degree \u0026 0 \\\\\\\n                    –\\sin 20\\degree \u0026 \\cos 20\\degree \u0026 0 \\\\\\\n                    0 \u0026 0 \u0026 1 \\end{bmatrix} .\n    \\begin{bmatrix} 1 \u0026 0 \u0026 0 \\\\\\\n                    0 \u0026 1 \u0026 0 \\\\\\\n                    C_x \u0026 C_y \u0026 1 \\end{bmatrix}\n$$\n\nWe can of course multiply the transformations matrices together to obtain a combined transformation matrix, using the associative property of matrix product. Just be aware that matrix product however is non-commutative : the order is important.\n\n$$ T1 . R . T2 = \\\\\n\\begin{bmatrix} \\cos 20\\degree \u0026 \\sin 20\\degree \u0026 0 \\\\\\\n                -\\sin 20\\degree \u0026 \\cos 20\\degree \u0026 0 \\\\\\\n                C_x(1-\\cos 20\\degree) + C_y \\sin 20\\degree \u0026 C_y(1-\\cos 20\\degree) - C_x \\sin 20\\degree \u0026 1 \\end{bmatrix}\n$$\n\nWe can apply the same logics to all transformations.\n\nSee the source code comments for more details !\n\n## How to\n\nTo run the demo :\n\n```bash\nmake run\n```\n\nBuild .js executable for the web :\n\n```bash\nmake js\n```\n\n## To do \n\n* Give user the ability to move (translate) only the figure\n* Explicit the chaining of transformation/multiplication. Why not record all transformations in a string given by the user, for exemple 'rmtsr' -\u003e rotate / translate (move) / shear (tear) / scale / rotate) and show the resulting transformation matrix obtained by multiplications of primitives/transformation matrix ?\n\n## Issues\n\n* The .js version seems to have some issues detecting simultaneous key press.\n\n* For simplicity, a lot of transformations parameters are hard coded, not very elegant.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjehadel%2F3x3-2d-transformations_demo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjehadel%2F3x3-2d-transformations_demo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjehadel%2F3x3-2d-transformations_demo/lists"}