双曲線平面テッセレーションをプロットする


10

次のような双曲線平面上のテッセレーションのプロット(ポアンカレ円盤)を作成します。

ここに画像の説明を入力してください

プログラムは4つの入力を受け取ります。

1)エッジ/ポリゴンの数(この例では3つ)。

2)各頂点で交差する数(この例では7つ)。

3)レンダリングする中心の頂点から何ステップ離れているか(詳しく見ると、この例では5)。これは、中心から5ステップ以内で到達できる頂点が含まれることを意味します。エッジは、両方の頂点が含まれている場合にレンダリングされます。

4)画像の解像度(単一のピクセル数、画像は正方形)。

出力は画像でなければなりません。エッジは、線ではなく円弧としてレンダリングする必要があります(ポアンカレ円盤投影は線を円に変換します)。ポイントをレンダリングする必要はありません。ユーザーが双曲線でないもの(つまり、各頂点で5つの三角形が出会う)を入力する場合、プログラムは正しく動作する必要はありません。これはコードゴルフなので、最も短い答えが優先されます。


より明確に。
Kevin Kostlan、2015

非常に明確になりました:)
trichoplax

これは暗黙的ですが、次のことを明示的にすることをお勧めします。a)ポアンカレ円板モデルを使用する必要があります(半平面モデルの解答も受け入れない限り)。b)頂点は、ポリゴンの中心ではなく、ディスクの中心にレンダリングする必要があります。
Peter Taylor、

頂点はディスクの中心になければなりませんか?または、ディスクの中心をポリゴンの中心にすることはできますか?
DavidC

1
これには本当に背景情報がもっと必要です。私はいくつかのサイトを見ましたが(質問には何も記載されていません)、一般的なケースはもちろんのこと、サンプルの図を描くための正確な仕様を理解できません。それが指定されていない場合、人々が懸命に取り組んだ無効な回答が返される可能性があります(たとえば、非放射状の線が円弧として表されることを理解していますが、誰かがショートカットを使って直線を実行する可能性があります)。また、中心の頂点からの線のエッジ長(円の半径のパーセンテージとして)を指定する必要があります。
Level River St

回答:


2

Mathematica、2535バイト

ここから取られ(それがなぜコミュニティウィキなのか)。実際にはゴルフをしていません。提供されたリンクで、著者のコードの説明を確認してください。

また、私はMathematicaの専門家ではありませんが、マーティンがコードの長さについて不思議に思うかもしれません。その背後にある数学すら理解できません。

私はそれを読みやすいままにしましたが、質問が閉じられない場合は、読みやすさを超えてゴルフし、呼び出し元の関数内に他の2つのパラメーターを移動します。

現在は無効です。改善にご協力ください。

  • これは弧ではなく線を使用していると思います。

  • 頂点ではなく面を中心とします。

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]

次のように呼び出されます:

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

タイリング


1
これはテキストの究極の壁のように見えます。+1
kirbyfan64sos

@ kirbyfan64sosええ、これを解読するのは獣です。双曲線ではなく円弧にするために必要な変更はほんのわずかしかないと確信しています。また、関数/パラメーターを単一文字の名前に変更すると、サイズが大幅に削減されます。
mbomb007

1
@steveverrill弧ではなく線でもあり、これも間違っています。どちらの問題を修正するためにそれを変更するかわかりません。これはCWなので、誰でも気軽に改善を手伝ってください。
mbomb007

1
線なのか円弧なのか。この低解像度ではわかりにくいですが、実際には弧である可能性があります。たとえば、中央のポリゴンの右側の線が少し内側に曲がっているように見えます。
Reto Koradi、2015

1
他の人のコードに基づいて、1100バイトまで削減できる別のアプローチがあります。しかし、いったんゴルフをすると、コードは判読できなくなります。私たちがあなたの提出物をゴルフするならば、私は同じことが起こると思います。現在、私はそれらが冗長形式でどのように機能するかを理解しようとしています。
DavidC
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.