{"id":22071291,"url":"https://github.com/lancejpollard/ht.js","last_synced_at":"2025-06-12T03:09:08.440Z","repository":{"id":65359459,"uuid":"590487947","full_name":"lancejpollard/ht.js","owner":"lancejpollard","description":"Hyperbolic tessellations in JavaScript.","archived":false,"fork":false,"pushed_at":"2023-01-28T05:00:03.000Z","size":18062,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"make","last_synced_at":"2025-03-23T19:16:43.103Z","etag":null,"topics":["hyperbolic-geometry","hyperbolic-tessellations","hyperbolic-tilings"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lancejpollard.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2023-01-18T14:31:46.000Z","updated_at":"2023-01-20T21:05:35.000Z","dependencies_parsed_at":"2023-02-15T14:31:57.403Z","dependency_job_id":null,"html_url":"https://github.com/lancejpollard/ht.js","commit_stats":null,"previous_names":["haresurf/ht.js","termhare/ht.js","lancejpollard/ht.js"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/lancejpollard/ht.js","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lancejpollard%2Fht.js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lancejpollard%2Fht.js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lancejpollard%2Fht.js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lancejpollard%2Fht.js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lancejpollard","download_url":"https://codeload.github.com/lancejpollard/ht.js/tar.gz/refs/heads/make","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lancejpollard%2Fht.js/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259388068,"owners_count":22849751,"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":["hyperbolic-geometry","hyperbolic-tessellations","hyperbolic-tilings"],"created_at":"2024-11-30T20:29:49.756Z","updated_at":"2025-06-12T03:09:08.404Z","avatar_url":"https://github.com/lancejpollard.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ht.js\n\nHyperbolic tessellations in the 2D plane in JavaScript.\n\n\u003cbr/\u003e\n\u003cbr/\u003e\n\u003cp align='center'\u003e\n  \u003cimg src='https://github.com/lancejpollard/ht.js/blob/make/7-3.gif?raw=true' height='500'\u003e\n\u003c/p\u003e\n\u003cbr/\u003e\n\u003cbr/\u003e\n\u003cp align='center'\u003e\n  \u003cimg src='https://github.com/lancejpollard/ht.js/blob/make/3-7.png?raw=true' height='200'\u003e\n  \u003cimg src='https://github.com/lancejpollard/ht.js/blob/make/5-4.png?raw=true' height='200'\u003e\n  \u003cimg src='https://github.com/lancejpollard/ht.js/blob/make/9-3.png?raw=true' height='200'\u003e\n\u003c/p\u003e\n\u003cbr/\u003e\n\n## Overview\n\nThis is a direct port of\n[roice3/Honeycombs](https://github.com/roice3/Honeycombs) from CSharp to\nTypeScript. It is in the process of being developed over the next few\nyears.\n\n## Inspiration\n\n- [roice3/Honeycombs](https://github.com/roice3/Honeycombs)\n- [thoszhang/hyperbolic-tiling](https://github.com/thoszhang/hyperbolic-tiling)\n- [knexator/hyperbolic-tiling](https://github.com/knexator/hyperbolic-tiling)\n- [mountain/hyperbolic-wythoff](https://github.com/mountain/hyperbolic-wythoff)\n- [cduck/hyperbolic](https://github.com/cduck/hyperbolic)\n\n## Papers\n\n- [Visualizing hyperbolic honeycombs](https://becomingborealis.com/wp-content/uploads/2018/05/Visualizing-hyperbolic-honeycombs.pdf)\n- [Abstracting Rubik’s Cube](http://roice3.org/papers/abstracting_rubiks_cube.pdf)\n\n## Notes\n\n- [Poincaré half-plane model](https://en.wikipedia.org/wiki/Poincar%C3%A9_half-plane_model)\n- [Wythoff construction](https://en.wikipedia.org/wiki/Wythoff_construction)\n- [List of hyperbolic tilings](https://en.wikipedia.org/wiki/Lists_of_uniform_tilings_on_the_sphere,_plane,_and_hyperbolic_plane)\n- [CSharp to TypeScript](http://www.carlosag.net/tools/codetranslator/)\n- [CSharp codebase](https://github.com/microsoft/referencesource/blob/master/mscorlib/system/collections/ienumerable.cs)\n- https://docs.google.com/document/d/1vUQPHvO4zOy5S1fyQIWMcy7vyzTvu5OYrUI6jmjpG90/edit\n\n## Dev\n\n```ts\nimport { Tiling } from './src/Geometry/Tiling'\nimport { TilingConfig } from './src/Geometry/Tiling'\nimport { SVG } from './src/Format/SVG'\n\nconst config = new TilingConfig(3, 7, 10000)\nconst tiling = new Tiling(config)\ntiling.Generate()\nconst polygons = tiling.m_tiles.map(tile =\u003e tile.Boundary)\nSVG.WritePolygons('example.svg', polygons)\n```\n\n```\n# count files with extension\nfind . -name \"*.ts\" -type f | wc -l\n\n# count lines in files with extension\nfind . -name '*.ts' -type f | xargs wc -l\n```\n\n## Ideas\n\nThe ideal is to have tiles, faces, points, and edges, and work with each\ntile like that.\n\n```ts\nconst tessellation = new Tessellation(3, 7, {\n  point: {\n    visibility: 'hidden',\n  },\n  edge: {\n    width: 8,\n    fill: 'black',\n  },\n  face: {\n    fill: 'gray',\n  },\n})\n\ntiling.center(tile)\ntiling.lock()\ntiling.unlock()\n// inch toward another block\ntiling.move()\ntiling.rotate()\ntiling.querySelectorAll('face')\ntiling.base\ntiline.base.neighbors\ntiline.base.points\ntiline.base.edges\ntiline.base.face\ntiline.base.face.style.fill = 0x00ff00\ntiline.base.face.addEventListener\n\ntessellation.addEventListener('keyup', e =\u003e {\n  if (e.key === 'up') {\n    tessellation.center(tessellation.center.tiles[0])\n  }\n})\n\ntessellation.addEventListener('tile:click', event =\u003e {\n  tessellation.focus(event.currentTarget)\n})\n\ntessellation.addEventListener('tile:dblclick', event =\u003e {\n  tessellation.orient(event.currentTarget)\n})\n\ntessellation.rotate(90)\n\ntessellation.addEventListener('tile:remove')\ntessellation.addEventListener('tile:create')\ntessellation.addEventListener('tile:mouseover')\ntessellation.addEventListener('tile:mouseupoutside')\ntessellation.addEventListener('tile:click')\ntessellation.addEventListener('tile:touchstart')\ntessellation.addEventListener('tile:touchend')\ntessellation.addEventListener('resize')\ntessellation.addEventListener('hover')\n\ntessellation.center.edges.forEach(point =\u003e {\n  point.style.fill = 'red'\n})\n\nfunction render() {\n  tessellation.render()\n  requestAnimationFrame(render)\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flancejpollard%2Fht.js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flancejpollard%2Fht.js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flancejpollard%2Fht.js/lists"}