{"id":24076683,"url":"https://github.com/apirogov/tilezz","last_synced_at":"2026-02-23T16:33:24.323Z","repository":{"id":267884485,"uuid":"900311622","full_name":"apirogov/tilezz","owner":"apirogov","description":"perfect-precision polygonal tiles over cyclotomic integer rings","archived":false,"fork":false,"pushed_at":"2025-02-11T19:41:22.000Z","size":476,"stargazers_count":0,"open_issues_count":21,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-19T16:46:23.792Z","etag":null,"topics":["geometry","math","tilings"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/apirogov.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,"zenodo":null}},"created_at":"2024-12-08T13:08:01.000Z","updated_at":"2025-02-11T19:41:25.000Z","dependencies_parsed_at":"2024-12-13T03:18:20.894Z","dependency_job_id":"b9521812-0912-468a-aaf0-2e9b7b17bb83","html_url":"https://github.com/apirogov/tilezz","commit_stats":null,"previous_names":["apirogov/rational-tiles","apirogov/tilezz"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/apirogov/tilezz","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apirogov%2Ftilezz","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apirogov%2Ftilezz/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apirogov%2Ftilezz/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apirogov%2Ftilezz/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/apirogov","download_url":"https://codeload.github.com/apirogov/tilezz/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apirogov%2Ftilezz/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29748210,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-23T07:44:07.782Z","status":"ssl_error","status_checked_at":"2026-02-23T07:44:07.432Z","response_time":90,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["geometry","math","tilings"],"created_at":"2025-01-09T20:00:10.745Z","updated_at":"2026-02-23T16:33:24.305Z","avatar_url":"https://github.com/apirogov.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# tilezz\n\nThis repository provides the following main features:\n\n1. practical implementation of various [cyclotomic rings and fields](https://en.wikipedia.org/wiki/Cyclotomic_field), which are subsets of complex numbers that admit exact representation\n2. exact representation of a rich family of polygonal tiles based on these rings, using a minimalistic and discrete form of [turtle semantics](https://en.wikipedia.org/wiki/Turtle_graphics)\n3. some useful string-based algorithms to work with these objects and visualize them\n\nThese features taken together grant us multiple freedoms:\n\n1. freedom of floating-point numbers and subtle bugs due to numerical issues\n2. freedom of coordinates, as polygons are described by relative angles and movements to trace out their boundary\n3. freedom of a (typical) grid, when using the polygons in the context of tiles and tilings\n\nThe target audience are primarily math enthusiasts (like myself) or researchers\nworking on (a)periodic tiles or other areas where exact representation of\npolygons is crucial and where numerical approximation and the use of floating\npoint arithmetic are not acceptable for the given purpose, yet the use of more\ngeneric solutions, such as computer algebra systems is not desirable, too\ninconvenient or too inefficient.\n\nThe concepts this work is based on are described in the following blog posts:\n\n* https://pirogov.de/blog/perfect-precision-2d-geometry-complex-integers/\n* https://pirogov.de/blog/intersecting-segments-without-tears/\n* (more posts will probably added over time)\n\nNote that due to time constraints, this is a work-(not-so-fast-)in-progress.\n\n## Demonstration\n\n*To be able to execute the demos on your computer, make sure to build the crate with the `examples` feature enabled.*\n\n### Exploring the cyclotomic ring ZZ12\n\n\u003cimg src=\"https://github.com/user-attachments/assets/a7d1d698-8e7c-41a8-b2a8-49a8fed80c2e\" width=\"45%\" /\u003e\n\u003cimg src=\"https://github.com/user-attachments/assets/d246fd60-bfed-4ff8-9393-2ae14e77e4d2\" width=\"45%\" /\u003e\n\nLeft: BFS from the origin, Right: BFS in the unit square, starting in the corners and normalizing discovered point modulo unit square.\nEach image shows the new points discovered in the corresponding round.\n\nTo generate images like these, check out the [cyc_explore](./src/bin/cyc_explore.rs) example.\n\n### Enumerating simple polygons constructible over cyclotomic rings\n\n\u003cimg src=\"https://github.com/user-attachments/assets/3940b499-8a11-40e0-a53f-3b145bc0b894\" width=\"45%\" /\u003e\n\u003cimg src=\"https://github.com/user-attachments/assets/198814da-471f-49f3-81e1-784c4252c388\" width=\"45%\" /\u003e\n\nLeft: All 965 distinct polyominos with boundary length up to 16 over ZZ4 (computation time: a few minutes),\nRight: All 933 distinct matchstick polygons with boundary length up to 8 over ZZ12 (computation time: around 2,5h).\nThe polygon sets were computed using a naive brute-force approach with a single thread on an old Thinkpad T460.\n\nTo generate images like these, check out the [rat_enum](./src/bin/rat_enum.rs) example.\n\n## Usage\n\n### Essential Concepts\n\nThis crate provides the abstract geometric API for using concrete\nrepresentations of constructible cyclotomic rings for some fixed root of unity,\nand polygonal tiles build on top of these rings.\n\nInstead of representing polygons by segments and coordinates, they are described\nusing a form of turtle semantics, i.e. interpreting a sequence of discrete\n[external angles](https://en.wikipedia.org/wiki/Internal_and_external_angles) as\ninstructions for tracing out a polygon or segment chain from a given starting\npoint by performing unit-length steps in some direction. This, together with the\nfact that we use cyclotomics for actual coordinates, helps avoiding dependence\non floating point numbers and explicit coordinates.\n\nHere is a conceptual mapping for the relevant geometrical objects:\n\n* a **point** corresponds to a **turtle**, which is an \"oriented point\" (it has an angle, defining its facing direction)\n* a **polygonal chain** corresponds to a **snake**, which consists of instructions for a turtle\n* a **polygon** corresponds to a *closed* snake, which I call a **rat** (for *rational tile*)\n* a **tile patch** corresponds to a **pack**, which is a collection of combined rats\n\nA **tile** is a [simple polygon](https://en.wikipedia.org/wiki/Simple_polygon),\ni.e. a polygon without holes or self-intersections, and a segment chain, polygon, or tile\nis *rational* if all the side lengths can be expressed as integer multiples of a\ncommon length.\n\nBy using cyclotomic integers for coordinates and expressing all geometric\nobjects in terms of unit steps into some direction, each simple polygon allows\nfor a natural representation as a sequence of exterior angles along its boundary.\nAs the sequence is cyclic, there is one cyclicaly shifted sequence for each\nstarting vertex.\n\nThe **canonical representation** is then simply the [lexicographically\nminimal](https://en.wikipedia.org/wiki/Lexicographically_minimal_string_rotation)\nsuch sequence. Note that this gives us a **simple and efficient equivalence\ncheck on polygons**: two polygons are equal iff they have the same canonical\nangle sequence. Treating (rational) polygons as strings of angles also allows us\nto use other efficient string-based algorithms, e.g. to compute combinations of\ntiles.\n\nThis library also provides some plotting functionality based on\n[plotterrs](https://github.com/plotters-rs/plotters), which means that you can\neasily render tiles built with this crate into various backends, including PNG,\nSVG, web pages (HTML5/WASM), including interactive usage in Jupyter.\n\n### Interactive (Jupyter Notebook)\n\nThanks to the capabilities of the `plotters` library, it is easy to use\n[Jupyter notebooks](https://jupyter.org/) with this crate to visualize polygonal tiles.\n\n#### Requirements\n\n* [Jupyter Notebook](https://jupyter.org/install#jupyter-notebook) (Arch Linux users see [here](https://wiki.archlinux.org/title/Jupyter))\n* [evcxr](https://github.com/evcxr/evcxr)\n* [evcxr_jupyter](https://github.com/evcxr/evcxr)\n\nIf you have all the dependencies installed correctly and can create/open Jupyter\nNotebooks using a Rust kernel (check out the official\n[evcxr documentation](https://plotters-rs.github.io/plotters-doc-data/evcxr-jupyter-integration.html)),\nthen you are already set up for using this crate interactively.\n\n#### Rendering the Spectre Tile Over the Cyclotomic Integer Ring ZZ12\n\nHere is how you can quickly construct and render the\n[spectre tile](https://en.wikipedia.org/wiki/Einstein_problem):\n\n**Step 1:** **(Recommended)** *This step is only needed if you want to use the most recent development version from this repository.*\n\nClone this repository and change to its directory, i.e. in a terminal run:\n\n```bash\ngit clone https://github.com/apirogov/tilezz\ncd tilezz\n```\n\n**Step 2:** Run `jupyter notebook`\n\n**Step 3:** Open the [minimal example notebook](./examples/minimal.ipynb) **OR**\n    Create a new Rust notebook (which is powered by `evcxr`) and add the following code into a cell:\n\n```rust\n// Build and load the crate\n:dep plotters = { version = \"^0.3.7\", features = [\"evcxr\", \"all_series\"] }\n// 1(a) if you want to use a published version of this crate:\n// :dep tilezz = \"*\"\n// 1(b) (RECOMMENDED) if you cloned this repository and want to use the current development version:\n:dep tilezz = { path = \"..\" }\n\n// Import what we need\nuse tilezz::cyclotomic::*;\nuse tilezz::snake::Turtle;\nuse tilezz::rat::Rat;\n\nuse plotters::prelude::*;\nuse tilezz::plotters::{plot_tile, TileStyle};\n\nevcxr_figure((500,500), |root| {\n    // Prepare the canvas\n    let _ = root.fill(\u0026WHITE);\n    let root = root.margin(10, 10, 10, 10);\n\n    // Define a sequence of external angles. As all segments have unit length, this fully determines a polygon\n    let external_angles: \u0026[i8] = \u0026[3, 2, 0, 2, -3, 2, 3, 2, -3, 2, 3, -2, 3, -2];\n    // Instantiate an abstract polygon over the cyclotomic ring ZZ12 (one full turn = 12 rotational unit steps)\n    let s: Rat\u003cZZ12\u003e = external_angles.try_into().unwrap();\n    // Trace out the polygon in the cartesian plane using a canonical starting point and facing direction\n    let p = s.to_polyline_f64(Turtle::default());\n    // Plot the concretized polygon with default settings\n    plot_tile(\u0026root, \u0026p, \u0026TileStyle::default());\n\n    Ok(())\n})\n```\n\nAfter waiting for some seconds (the required dependencies have to be built\nfirst, after that it is faster), you should see a plot showing the spectre tile.\n\n## See Also\n\n### Tiles and Tilings\n\nIt seems that people who work on/with tiles use software like:\n\n* computer algebra systems, such as [SageMath](https://doc.sagemath.org/html/en/reference/number_fields/index.html)\n* SAT or SMT solvers, such as [Z3](https://github.com/Z3Prover/z3)\n* [PolyForm Puzzle Solver](https://www.jaapsch.net/puzzles/polysolver.htm)\n\nSageMath or similar systems are of course much more heavy and require deeper\nalgebraic understanding to even ask what you want. This crate provides much\nsimpler (and I hope more efficient) solutions to much more specific problems.\n\nSimilarly, SAT or SMT solvers are excellent tools for certain NP-complete\nproblems (I have some experience using them), but encoding tiling problems into\nsuitable formulas is far from trivial and requires some thought and work (even\nthough it sometimes is [possible](https://www.hgreer.com/HatTile/)). It can\nreally pay off and work well if you have enough knowledge about SAT/SMT encoding\ntricks and also have a deeper grasp on the structure of the problem at hand. But\nit is not something I'd pull out to just quickly come up with a polygon and\ncheck its behavior as a tile.\n\nThe PolyForm Solver seems to have\n[some adoption](https://hedraweb.wordpress.com/2023/03/23/its-a-shape-jim-but-not-as-we-know-it/)\nby the tiling community and looks like a mature and feature-rich package that I\neventually want to try out myself. From a cursory look, it seems like the\nbiggest conceptual difference is that **the PolyForm Solver is grid-based** - it\nrequires selecting some underlying grid of primitive cells from which the\npolyform tiles can be built from. **My approach is grid-free**, so it is more\ngeneral. Technically, the cyclotomic integers *do* provide another kind of grid,\nbut it is not a typical periodic cell grid as typically used to describe tiles\nand tilings.  This means that more exotic and irregular tiles can be expressed,\nbut also that there is less fixed structure to work with and exploit, and I\ndon't provide any sophisticated solvers (yet).\n\n### Cyclotomic Integer Rings (i.e. Complex Integers)\n\nI have no clue about abstract algebra and number theory (I just stumbled into\nthis topic trying to represent some tiles exactly), but it seems like there are\na few very general implementations of cyclotomic fields.\n\n* https://github.com/CyclotomicFields/cyclotomic (Rust)\n* https://github.com/walck/cyclotomic (Haskell)\n\nCompared to these packages, I do not try to implement the full set of cyclotomic\nintegers (i.e. one type that includes and works with all roots of unity at\nonce). This crate provides **a *separate* ring/field for each supported root of\nunity** instead, which then serves as the backbone for representing geometry of\nsuitable polygons.\n\nThe corresponding underlying representations are optimized for and limited to\nthe respective ring, there is **no overhead due to management of symbolic\nrepresentations** or anything like that, because for each ring, the provided\ndata type encodes the values of each ring as vectors over a linearly independent\nset base of units (and all their distinct symbolic products), together with a\nring-specific implementation of multiplication, which hard-codes the symbolic\nsimplifications of expressions that appear during the evaluation of\nmultiplication.\n\nI have have not tried to compare this crate to the other approaches or benchmark\nanything yet, because the implementations of the complex integers were not the\nintended main feature of this crate. If someone is mainly interested in this\ncrate for the implementation of the cyclotomic integer rings, I would be happy\nto get some feedback on how this compares to the more generic implementations\nwith similar features.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapirogov%2Ftilezz","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fapirogov%2Ftilezz","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapirogov%2Ftilezz/lists"}