Traccia una tassellazione del piano iperbolico


10

Crea una trama (disco Poincare) di una tassellatura su un piano iperbolico, come ad esempio:

inserisci qui la descrizione dell'immagine

Il programma accetta quattro input:

1) Quanti spigoli / poligoni (tre in questo esempio).

2) Quanti si intersecano in ciascun vertice (sette in questo esempio).

3) Quanti passi di distanza dal vertice centrale visualizzare (5 in questo esempio, se guardi da vicino). Ciò significa che è incluso un vertice se può essere raggiunto in 5 o meno passi dal centro. I bordi sono resi se sono inclusi entrambi i loro vertici.

4) La risoluzione dell'immagine (un singolo numero di pixel, l'immagine è quadrata).

L'output deve essere un'immagine. I bordi devono essere resi come archi circolari, non linee (la proiezione del disco di Poincaré trasforma le linee in cerchi). Non è necessario rendere i punti. Quando l'utente inserisce qualcosa che non è iperbolico (ovvero 5 triangoli che si incontrano in ciascun vertice), il programma non deve funzionare correttamente. Questo è code-golf, quindi vince la risposta più breve.


Reso più chiaro.
Kevin Kostlan,

Molto più chiaro ora :)
trichoplax

È implicito, ma potrebbe essere meglio chiarire che a) dovrebbe essere usato il modello del disco di Poincaré (a meno che non si sia aperti anche a risposte del modello a mezzo piano); b) un vertice dovrebbe essere reso al centro del disco e non al centro di un poligono.
Peter Taylor,

Un vertice deve trovarsi al centro del disco? O il centro del disco può essere il centro di un poligono?
DavidC,

1
Ciò richiede davvero più informazioni di base. Ho esaminato un paio di siti (non ce ne sono nessuno menzionato nella domanda) e non riesco a capire l'esatta specifica per disegnare la figura di esempio, per non parlare del caso generale. Se non specificato, potresti ottenere risposte non valide su cui le persone hanno lavorato duramente (ad esempio, capisco che le linee non radiali sono rappresentate come archi di cerchi, ma qualcuno potrebbe prendere una scorciatoia e fare linee rette.) Inoltre, sembra la lunghezza del bordo delle linee dal vertice centrale (come percentuale del raggio del cerchio) deve essere specificata.
Level River St

Risposte:


2

Mathematica, 2535 byte

Tratto da qui (quindi perché è wiki della comunità). Non proprio quello da golf. Visualizza il link fornito per la spiegazione dell'autore del suo codice.

Inoltre, non sono un esperto di Mathematica, ma scommetto che Martin potrebbe fare miracoli sulla lunghezza del codice. Non capisco nemmeno la matematica dietro di esso.

L'ho lasciato leggibile, ma se la domanda non viene chiusa, passerò oltre la leggibilità e sposterò gli altri 2 parametri all'interno della funzione chiamante.

Attualmente non valido , sentiti libero di aiutarti a migliorarlo:

  • Penso che questo usi linee piuttosto che archi.

  • Centrato su una faccia, piuttosto che su un vertice.

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]

Chiamato come:

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

piastrelle


1
Questo sembra l'ultimo muro di testo. +1
kirbyfan64sos

@ kirbyfan64sos Sì, decifrare questa è una bestia. Sono abbastanza sicuro che ci siano solo alcune modifiche necessarie per renderlo archi anziché linee iperboliche. Inoltre, la modifica delle funzioni / dei parametri in nomi a carattere singolo ridurrebbe le dimensioni di molto.
mbomb007,

1
@steveverrill Sono anche linee invece di archi, il che è anche sbagliato. Non sono sicuro di come modificarlo per risolvere entrambi i problemi. È in CW, quindi chiunque può sentirsi libero di aiutarlo a migliorarlo.
mbomb007,

1
Mi chiedevo se fossero linee o archi. È difficile dirlo a questa bassa risoluzione, ma in realtà potrebbero essere archi, ma non molto ... arcani. Ad esempio, sembra che la linea sul lato destro del poligono centrale sia leggermente piegata verso l'interno.
Reto Koradi,

1
Ho un altro approccio, basato sul codice di un'altra persona, che sono stato in grado di ridurre a 1100 byte. Ma, una volta golfato, il codice diventa indecifrabile. Credo che lo stesso accadrà se invochiamo la tua richiesta. Al momento, sto cercando di capire come funzionano in formato dettagliato.
DavidC
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.