Hiperbolik bir düzlem mozaik çizme


10

Hiperbolik bir düzlemde mozaiklemenin bir çizimini (Poincare diski) yapın, örneğin:

resim açıklamasını buraya girin

Program dört girdi alır :

1) Kaç kenar / çokgen (bu örnekte üç).

2) Her tepe noktasında kaç tane kesişiyor (bu örnekte yedi).

3) Orta tepe noktasından kaç adım uzakta oluşturulacaktır (bu örnekte 5, yakından bakarsanız). Bu, merkezden 5 veya daha az adımda ulaşılabilmesi durumunda bir tepe noktasının dahil edildiği anlamına gelir. Kenarlar, her iki tepe noktası da dahil edildiğinde oluşturulur.

4) Görüntünün çözünürlüğü (tek piksel sayısı, görüntü karedir).

Çıktı bir resim olmalıdır. Kenarlar, çizgiler değil daire-yaylar olarak oluşturulmalıdır (Poincaré disk projeksiyonu çizgileri dairelere dönüştürür). Puanların verilmesi gerekmez. Kullanıcı hiperbolik olmayan bir şey (her köşede toplanan 5 üçgen) koyduğunda , programın düzgün çalışması gerekmez. Bu kod golf, bu yüzden en kısa cevap kazanır.


Daha açık hale getirildi.
Kevin Kostlan

Çok daha net şimdi :)
trichoplax

Örtük, ancak açıkça belirtmek daha iyi olabilir: a) Poincaré disk modeli kullanılmalıdır (ayrıca yarım düzlemli model cevaplarına da açık değilseniz); b) bir çokgenin merkezinde değil, diskin merkezinde bir tepe noktası oluşturulmalıdır.
Peter Taylor

Diskin merkezinde bir tepe noktası olmalı mı? Veya diskin merkezi bir çokgenin merkezi olabilir mi?
DavidC

1
Bunun gerçekten daha fazla arka plan bilgisine ihtiyacı var. Ben birkaç siteye baktım (soruda adı geçen hiçbiri yoktur) ve genel durumdan bağımsız olarak, örnek figürü çizmek için kesin spesifikasyonu anlayamıyorum. Belirtilmezse, insanların çok çalıştığı geçersiz cevaplar alabilirsiniz (örneğin, radyal olmayan çizgilerin çevrelerin yayları olarak temsil edildiğini anlıyorum, ancak birisi bir kısayol alıp düz çizgiler yapabilir.) Ayrıca, öyle görünüyor. merkez tepe noktasındaki çizgilerin kenar uzunluğunun (daire yarıçapının yüzdesi olarak) belirtilmesi gerekir.
Level River St

Yanıtlar:


2

Mathematica, 2535 bayt

Alındığı burada (dolayısıyla neden 's topluluk wiki). Gerçekten o golfed. Yazarın kodunu açıklaması için sağlanan bağlantıyı görüntüleyin.

Ayrıca, ben Mathematica uzmanı değilim, ama eminim Martin kod uzunluğunda mucizeler yapabilir. Arkasındaki matematiği bile anlamıyorum.

Okunabilir halde bıraktım, ancak soru kapanmazsa, okunabilirliği geçerek golf oynatacağım ve arayan fonksiyon içindeki diğer 2 parametreyi taşıyacağım.

Şu anda geçersiz , geliştirmeye yardımcı olmaktan çekinmeyin:

  • Bence bu yaylar yerine çizgiler kullanıyor.

  • Bir tepe yerine bir yüze odaklanmıştır.

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]

Şöyle denir:

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

fayans


1
Bu metnin nihai duvarı gibi görünüyor. +1
kirbyfan64sos

@ kirbyfan64sos Evet, bunun deşifre edilmesi bir canavar. Hiperbolik çizgiler yerine yay yapmak için sadece birkaç değişiklik gerektiğinden eminim. Ayrıca, işlevlerin / parametrelerin tek karakterlik adlarla değiştirilmesi, boyutu çok azaltacaktır.
mbomb007

1
@steveverrill Aynı zamanda yanlış olan yaylar yerine çizgiler de var. Her iki sorunu da düzeltmek için nasıl değiştirileceğinden emin değilim. Bu CW, böylece herkes onu geliştirmeye yardımcı olmaktan çekinmeyin.
mbomb007

1
Çizgi mi yoksa yay mı olduğunu merak ediyordum. Bu düşük çözünürlükte söylemek zor, ama aslında yaylar olabilir, sadece ... arcy değil. Örneğin, orta poligonun sağ tarafındaki çizgi içeriye hafifçe bükülmüş gibi görünüyor.
Reto Koradi

1
Başka bir kişinin koduna dayanarak 1100 bayta indirebileceğim başka bir yaklaşımım var. Ancak, bir kez golf, kod çözülemez hale gelir. Gönderiminizi golf oynarsak aynı şeyin olacağına inanıyorum. Şu anda, bunların ayrıntılı biçimde nasıl çalıştıklarını anlamaya çalışıyorum.
DavidC
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.