Tracer une pavage plan hyperbolique

10

Faire un tracé (disque de Poincaré) d'une tessellation sur un plan hyperbolique, tel que:

entrez la description de l'image ici

Le programme prend quatre entrées:

1) Combien d'arêtes / polygone (trois dans cet exemple).

2) Combien se croisent à chaque sommet (sept dans cet exemple).

3) Le nombre de pas du sommet central à rendre (5 dans cet exemple, si vous regardez de près). Cela signifie qu'un sommet est inclus s'il peut être atteint en 5 étapes ou moins depuis le centre. Les arêtes sont rendues si leurs deux sommets sont inclus.

4) La résolution de l'image (un seul nombre de pixels, l'image est carrée).

La sortie doit être une image. Les bords doivent être rendus sous forme d'arcs de cercle et non de lignes (la projection de disque de Poincaré transforme les lignes en cercles). Les points n'ont pas besoin d'être rendus. Lorsque l'utilisateur met quelque chose qui n'est pas hyperbolique (c'est-à-dire 5 triangles se rencontrant à chaque sommet), le programme n'a pas à fonctionner correctement. C'est le code-golf, donc la réponse la plus courte l'emporte.

Kevin Kostlan
la source
Plus clair.
Kevin Kostlan
Beaucoup plus clair maintenant :)
trichoplax
C'est implicite, mais il vaudrait peut-être mieux expliquer explicitement que a) le modèle de disque de Poincaré doit être utilisé (à moins que vous ne soyez également ouvert aux réponses du modèle demi-plan); b) un sommet doit être rendu au centre du disque, et non au centre d'un polygone.
Peter Taylor
Un sommet doit-il se trouver au centre du disque? Ou le centre du disque peut-il être le centre d'un polygone?
DavidC
1
Cela nécessite vraiment plus d'informations de fond. J'ai regardé quelques sites (il n'y en a aucun mentionné dans la question) et je ne peux pas comprendre les spécifications exactes pour dessiner la figure d'exemple, sans parler du cas général. Si ce n'est pas spécifié, vous pouvez obtenir des réponses invalides sur lesquelles les gens ont travaillé dur (par exemple, je comprends que les lignes non radiales sont représentées comme des arcs de cercles, mais quelqu'un peut prendre un raccourci et faire des lignes droites.) En outre, il semble la longueur de la bordure des lignes à partir du sommet central (en pourcentage du rayon du cercle) doit être spécifiée.
Level River St

Réponses:

2

Mathematica, 2535 octets

Tiré d' ici (d'où la raison pour laquelle c'est un wiki communautaire). Pas vraiment golfé. Voir le lien fourni pour l'explication de l'auteur sur son code.

De plus, je ne suis pas un expert de Mathematica, mais je parie que Martin pourrait faire des merveilles sur la longueur du code. Je ne comprends même pas les mathématiques derrière ça.

Je l'ai laissé lisible, mais si la question ne se ferme pas, je vais la jouer au-delà de la lisibilité et déplacer les 2 autres paramètres à l'intérieur de la fonction d'appel.

Actuellement invalide , n'hésitez pas à contribuer à son amélioration:

  • Je pense que cela utilise des lignes plutôt que des arcs.

  • Centré sur un visage plutôt que sur un sommet.

HyperbolicLine[{{Px_, Py_}, {Qx_, Qy_}}] := 
 If[N[Chop[Px Qy - Py Qx]] =!= 0., 
  Circle[OrthoCentre[{{Px, Py}, {Qx, Qy}}], 
   OrthoRadius[{{Px, Py}, {Qx, Qy}}], 
   OrthoAngles[{{Px, Py}, {Qx, Qy}}]], Line[{{Px, Py}, {Qx, Qy}}]]

OrthoCentre[{{Px_, Py_}, {Qx_, Qy_}}] := 
 With[{d = 2 Px Qy - 2 Py Qx, p = 1 + Px^2, q = 1 + Qx^2 + Qy^2}, 
  If[N[d] =!= 0., {p Qy + Py^2 Qy - Py q, -p Qx - Py^2 Qx + Px q}/d, 
   ComplexInfinity]]

OrthoRadius[{{Px_, Py_}, {Qx_, Qy_}}] := 
 If[N[Chop[Px Qy - Py Qx]] =!= 0., 
  Sqrt[Total[OrthoCentre[{{Px, Py}, {Qx, Qy}}]^2] - 1], Infinity]

OrthoAngles[{{Px_, Py_}, {Qx_, Qy_}}] := 
 Block[{a, b, c = OrthoCentre[{{Px, Py}, {Qx, Qy}}]}, 
  If[(a = N[Apply[ArcTan, {Px, Py} - c]]) < 0., a = a + 2 \[Pi]];
  If[(b = N[Apply[ArcTan, {Qx, Qy} - c]]) < 0., 
   b = b + 2 \[Pi]]; {a, b} = Sort[{a, b}];
  If[b - a > \[Pi], {b, a + 2 \[Pi]}, {a, b}]]

Inversion[Circle[{Cx_, Cy_}, r_], {Px_, Py_}] := {Cx, Cy} + 
  r^2 {Px - Cx, Py - Cy}/((Cx - Px)^2 + (Cy - Py)^2)
Inversion[Circle[{Cx_, Cy_}, r_, {a_, b_}], {Px_, Py_}] := {Cx, Cy} + 
  r^2 {Px - Cx, Py - Cy}/((Cx - Px)^2 + (Cy - Py)^2)

Inversion[Circle[{Cx_, Cy_}, r_, {a_, b_}], p_Line] := 
 Map[Inversion[Circle[{Cx, Cy}, r], #] &, p, {2}]

Inversion[Circle[{Cx_, Cy_}, r_, {a_, b_}], p_Polygon] := 
 Map[Inversion[Circle[{Cx, Cy}, r], #] &, p, {2}]

Inversion[Line[{{Px_, Py_}, {Qx_, Qy_}}], {Ux_, Uy_}] := 
 With[{u = Px - Qx, 
   v = Qy - Py}, {-Ux (v^2 - u^2) - 2 u v Uy, 
    Uy (v^2 - u^2) - 2 u v Ux}/(u^2 + v^2)]
Inversion[Line[{{Px_, Py_}, {Qx_, Qy_}}], p_Polygon] := 
 Map[Inversion[Line[{{Px, Py}, {Qx, Qy}}], #] &, p, {2}]

Inversion[Circle[{Cx_, Cy_}, r_], c_List] := 
 Map[Inversion[Circle[{Cx, Cy}, r], #] &, c]


PolygonInvert[p_Polygon] := 
 Map[Inversion[HyperbolicLine[#], p] &, 
  Partition[Join[p[[1]], {p[[1, 1]]}], 2, 1]]
PolygonInvert[p_List] := Flatten[Map[PolygonInvert[#] &, p]]

LineRule = Polygon[x_] :> Line[Join[x, {x[[1]]}]];
HyperbolicLineRule = 
  Polygon[x_] :> 
   Map[HyperbolicLine, Partition[Join[x, {x[[1]]}], 2, 1]];

CentralPolygon[p_Integer, q_Integer, \[Phi]_: 0] := 
 With[{r = (Cot[\[Pi]/p] Cot[\[Pi]/q] - 1)/
     Sqrt[Cot[\[Pi]/p]^2 Cot[\[Pi]/q]^2 - 1], \[Theta] = \[Pi] Range[
       1, 2 p - 1, 2]/p}, 
  r Map[{{Cos[\[Phi]], -Sin[\[Phi]]}, {Sin[\[Phi]], Cos[\[Phi]]}}.# &,
     Transpose[{Cos[\[Theta]], Sin[\[Theta]]}]]]

PolygonUnion[p_Polygon, tol_: 10.^-10] := p
PolygonUnion[p_List, tol_: 10.^-10] := 
 With[{q = p /. Polygon[x_] :> N[Polygon[Round[x, 10.^-10]]]}, 
  DeleteDuplicates[q]]
HyperbolicTessellation[p_Integer, q_Integer, \[Phi]_, k_Integer, 
  t_: 10.^-10] := 
 Map[PolygonUnion[#, t] &, 
   NestList[PolygonInvert, Polygon[CentralPolygon[p, q, \[Phi]]], 
     k][[{-2, -1}]]] /; k > 0

HyperbolicTessellation[p_Integer, q_Integer, \[Phi]_, k_Integer, 
  t_: 10.^-10] := Polygon[CentralPolygon[p, q, \[Phi]]] /; k == 0
HyperbolicTessellationGraphics[p_Integer, q_Integer, \[Phi]_, 
  k_Integer, rule_RuleDelayed, opts___] := 
 Graphics[{Circle[{0, 0}, 1], 
   HyperbolicTessellation[p, q, \[Phi], k, 10.^-10] /. rule}, opts]

Appelé comme:

HyperbolicTessellationGraphics[3, 7, 0., 7, HyperbolicLineRule, ImageSize -> 300, PlotLabel -> "{7,7}"]

carrelage

mbomb007
la source
1
Cela ressemble au mur de texte ultime. +1
kirbyfan64sos
@ kirbyfan64sos Ouais, déchiffrer c'est une bête. Je suis sûr qu'il n'y a que quelques changements nécessaires pour en faire des arcs au lieu de lignes hyperboliques. De plus, changer les fonctions / paramètres en noms à caractère unique réduirait considérablement la taille.
mbomb007
1
@steveverrill Ce sont aussi des lignes au lieu d'arcs, ce qui est également faux. Je ne sais pas comment le modifier pour résoudre l'un ou l'autre problème. C'est CW, donc n'importe qui peut se sentir libre de l'aider à l'améliorer.
mbomb007
1
Je me demandais s'il s'agissait de lignes ou d'arcs. C'est difficile à dire à cette basse résolution, mais ils peuvent en fait être des arcs, mais pas très ... arqués. Par exemple, il semble que la ligne sur le côté droit du polygone central soit légèrement courbée vers l'intérieur.
Reto Koradi
1
J'ai une autre approche, basée sur le code d'une autre personne, que j'ai pu réduire à 1100 octets. Mais, une fois joué au golf, le code devient indéchiffrable. Je crois que la même chose se produirait si nous examinions votre proposition. En ce moment, j'essaie de comprendre comment ils fonctionnent en format verbeux.
DavidC