Skip to content

Instantly share code, notes, and snippets.

@lucasw
Last active October 21, 2024 00:37
Show Gist options
  • Save lucasw/a746150b986bea9337579263ea63ae6b to your computer and use it in GitHub Desktop.
Save lucasw/a746150b986bea9337579263ea63ae6b to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "6de13e4d",
"metadata": {},
"outputs": [],
"source": [
"import math\n",
"import random\n",
"\n",
"import drawsvg as draw\n",
"from drawsvg import Drawing\n",
"from hyperbolic import euclid, util\n",
"from hyperbolic.poincare import *"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1258f18a",
"metadata": {},
"outputs": [],
"source": [
"def hyp_poly_edge_construct(p, q):\n",
" pi, pi2 = math.pi, math.pi*2\n",
" th = pi2/q\n",
" phi = pi2/p\n",
" ang1 = pi-phi/2-th/2-pi/2\n",
" ang2 = th/2 + pi/2\n",
" a = math.sin(ang2)/math.sin(ang1)\n",
" b = math.sin(phi/2)/math.sin(ang1)\n",
" r_p = math.sqrt(1/(a**2-b**2))\n",
" r_c = a*r_p\n",
" r_from_c = b*r_p\n",
" #return r_c, r_from_c\n",
" t1 = pi - math.asin(r_c / (r_from_c / math.sin(phi/2)))\n",
" t2 = pi - t1 - phi/2\n",
" r = math.sin(t2) * (r_from_c / math.sin(phi/2))\n",
" return r"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "250f2d5a",
"metadata": {},
"outputs": [],
"source": [
"p = 5\n",
"corner_deg = 90\n",
"q = 360 / corner_deg\n",
"skip = 1.0\n",
"r = hyp_poly_edge_construct(p, q)\n",
"p_list = [\n",
" Point.from_polar_euclid(r, deg=-skip*i*360/p)\n",
" for i in range(p)\n",
"]\n",
"print(p_list)\n",
"\n",
"n = len(p_list)\n",
"e_list = [Line.from_points(*p_list[i], *p_list[(i+1)%n]) for i in range(n)]\n",
"poly = Polygon(e_list, join=True)\n",
"\n",
"d = Drawing(2.1, 2.1, origin='center')\n",
"d.draw(euclid.Circle(0, 0, 1), fill='silver')\n",
"for edge in e_list:\n",
" d.draw(edge, hwidth=0.05, fill='blue')\n",
"# d.draw(poly, hwidth=(0,-0.15), fill='green')\n",
"# d.draw(poly, fill='black', opacity=0.3)\n",
"# for p in p_list:\n",
"# d.draw(p, radius=0.05, stroke_width=0.01, stroke='#ccccff',\n",
"# fill='none', opacity=0.6)\n",
"\n",
"d.set_render_size(w=400)\n",
"d.save_svg('images/polyRegular.svg')\n",
"d"
]
},
{
"cell_type": "code",
"execution_count": 225,
"id": "a16f9890",
"metadata": {
"scrolled": false
},
"outputs": [],
"source": [
"def construct_poly_vertices(p, q, deg_offset=0, skip=1):\n",
" r = hyp_poly_edge_construct(p, q)\n",
" return [\n",
" Point.from_polar_euclid(r, deg=-skip*i*360/p+deg_offset)\n",
" for i in range(p)\n",
" ]\n",
" \n",
"def construct_poly_from_points(pt_list):\n",
" p = len(p_list)\n",
" e_list = [Line.from_points(*pt_list[i], *pt_list[(i + 1) % p]) for i in range(p)]\n",
" return Polygon(e_list, join=True)\n",
"\n",
"def draw_poly(poly, color=\"#ffffff\"):\n",
" d.draw(poly, fill=color, opacity=0.25)\n",
" d.draw(poly, hwidth=(0.0,0.05), fill='blue')\n",
" \n",
"def draw_points(p_list):\n",
" for pt in p_list:\n",
" d.draw(pt, hradius=0.15, hwidth=0.02,\n",
" fill='white', opacity=0.9)\n",
"\n",
"for ind in range(50):\n",
" d = Drawing(2.1, 2.1, origin='center')\n",
" d.draw(euclid.Circle(0, 0, 1), fill='#f9f9f9')\n",
"\n",
" p = 5\n",
" q = 4\n",
" # print('Inner angle:', 360/q)\n",
"\n",
" # the central polygon\n",
" pt_list = construct_poly_vertices(p, q)\n",
" rot_trans = Transform.rotation(deg=270)\n",
" offset = Transform.translation(Point(-0.5 + ind * 0.025, -0.0))\n",
" trans = Transform.merge(offset, rot_trans)\n",
" pt_list = trans.apply_to_list(pt_list)\n",
" poly = Polygon.from_vertices(pt_list)\n",
" draw_poly(poly)\n",
"\n",
" def ring(p, q, i0, i1, pt_list):\n",
" pt_list2 = construct_poly_vertices(p, q)\n",
" t0 = pt_list2[0]\n",
" t1 = pt_list2[1]\n",
" trans_to_origin = Transform.shift_origin(t0, t1)\n",
" # print(f\"trans_to_origin: {t0} {t1} -> {trans_to_origin}\")\n",
" if False:\n",
" px, py = trans_to_origin.apply_to_tuple(p_list2[-1])\n",
" # print('Inner angle:', math.degrees(math.atan2(py,px)))\n",
"\n",
" poly_list = []\n",
" pt_list_list = []\n",
" for i in range(i0, i1):\n",
" t0 = pt_list[(i + 1) % p]\n",
" t1 = pt_list[i]\n",
" trans_to_side = Transform.translation(t0, t1)\n",
" # print(f\"{i} t: {tx} {ty} -> {trans_to_side}\")\n",
" # offset = Transform.rotation(deg=5)\n",
" # offset = Transform.translation(Point(0.1, 0.0))\n",
" offset = Transform.translation(Point(0.0, 0.0))\n",
" trans = Transform.merge(offset, trans_to_origin, trans_to_side)\n",
" pt_list2r = trans.apply_to_list(pt_list2)\n",
" poly2 = Polygon.from_vertices(pt_list2r)\n",
" pt_list_list.append(pt_list2r)\n",
" poly_list.append(poly2)\n",
"\n",
" for poly2 in poly_list:\n",
" draw_poly(poly2)\n",
" # draw_points(p_list)\n",
" # for pt_list2 in pt_list_list:\n",
" # draw_points(pt_list2)\n",
"\n",
" return poly_list, pt_list_list\n",
"\n",
" poly_list, pt_list_list = ring(p, q, i0=0, i1=p, pt_list=pt_list)\n",
"\n",
" # TODO(lucasw) need to avoid drawing the same shape twice\n",
" if True:\n",
" for poly, pt_list in zip(poly_list, pt_list_list):\n",
" poly_list, pt_list_list = ring(p, q, 1, 4, pt_list)\n",
" for poly, pt_list in zip(poly_list, pt_list_list):\n",
" poly_list, pt_list_list = ring(p, q, 0, 4, pt_list)\n",
" for poly, pt_list in zip(poly_list, pt_list_list):\n",
" poly_list, pt_list_list = ring(p, q, 0, 5, pt_list)\n",
" for poly, pt_list in zip(poly_list, pt_list_list):\n",
" poly_list, pt_list_list = ring(p, q, 0, 5, pt_list)\n",
"\n",
" d.set_render_size(w=1080)\n",
" name = f'images/poly_tile_{p}_{q}_{ind:05d}'\n",
" d.save_png(name + \".png\")\n",
" d"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "myenv",
"language": "python",
"name": "myenv"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
@lucasw
Copy link
Author

lucasw commented Oct 21, 2024

poly_tile_5_4_00000
poly_tile_5_4_00010
poly_tile_5_4_00020
poly_tile_5_4_00030
poly_tile_5_4_00040

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment