쌍곡면 평면 테셀레이션 플로팅


10

다음과 같이 쌍곡면에 테셀레이션의 도표 (Poincare 디스크)를 만듭니다.

여기에 이미지 설명을 입력하십시오

이 프로그램은 4 가지 입력을 받습니다 :

1) 얼마나 많은 모서리 / 다각형 (이 예에서는 3 개).

2) 각 정점에서 교차하는 수 (이 예에서는 7 개)

3) 렌더링 할 중심 정점에서 몇 단계 떨어져 있는가 (이 예에서는 자세히 보시면 5). 이것은 정점이 중심에서 5 단계 이하로 도달 할 수있는 경우 포함된다는 것을 의미합니다. 모서리는 꼭지점이 모두 포함 된 경우 렌더링됩니다.

4) 이미지의 해상도 (단일 픽셀 수, 이미지는 정사각형).

출력은 이미지 여야합니다. 가장자리는 선이 아닌 원호로 렌더링해야합니다 (Poincaré 디스크 투영은 선을 원으로 바꿉니다). 포인트를 렌더링 할 필요는 없습니다. 사용자가 쌍곡선 이 아닌 무언가 (예 : 각 정점에서 만나는 5 개의 삼각형)를 넣을 때 프로그램이 제대로 작동하지 않아도됩니다. 이것은 코드 골프이므로 가장 짧은 대답이 이깁니다.


더 명확하게 만들었습니다.
Kevin Kostlan

훨씬 명확
해짐

암시 적이지만, a) Poincaré 디스크 모델을 사용해야합니다 (반면 모델 답변을 공개하지 않은 경우). b) 꼭짓점은 다각형의 중심이 아닌 디스크의 중심에 렌더링되어야합니다.
피터 테일러

꼭짓점이 디스크 중앙에 있어야합니까? 아니면 디스크의 중심이 다각형의 중심 일 수 있습니까?
DavidC

1
더 많은 배경 정보가 필요합니다. 나는 두 사이트를 살펴 보았고 (질문에 언급되지 않은) 일반적인 경우는 물론 예제 그림을 그리는 정확한 사양을 알 수는 없습니다. 지정하지 않으면 사람들이 열심히 일한 잘못된 답변을 얻을 수 있습니다 (예 : 비 방사형 선은 원호로 표시되지만 누군가가 바로 가기를 사용하고 직선을 할 수 있음을 이해합니다). 중심 정점에서 선의 가장자리 길이 (원 반경의 백분율로)를 지정해야합니다.
Level River St

답변:


2

수학, 2535 바이트

여기 에서 찍은 (따라서 커뮤니티 위키 인 이유). 그렇게 골프는 아니었다. 저자의 코드 설명에 대한 제공된 링크를보십시오.

또한 Mathematica 전문가는 아니지만 Martin은 코드 길이에 대해 궁금 할 수 있습니다. 나는 그 배후의 수학을 이해조차하지 못합니다.

읽을 수 있도록 남겨 두었지만 질문이 닫히지 않으면 가독성을 넘어서 골퍼 함수 내부의 다른 두 매개 변수를 이동합니다.

현재 유효하지 않습니다 . 개선에 도움을 주시기 바랍니다.

  • 나는 이것이 호가 아닌 선을 사용한다고 생각합니다.

  • 꼭짓점이 아닌면을 중심으로합니다.

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

그래, 이것을 해독하는 것은 야수다. 쌍곡선 대신 호를 만드는 데 필요한 몇 가지 변경 사항이 있다고 확신합니다. 또한 함수 / 매개 변수를 단일 문자 이름으로 변경하면 크기가 크게 줄어 듭니다.
mbomb007

1
@steveverrill 그것은 호 대신에 선이기도합니다. 두 가지 문제를 해결하기 위해 수정하는 방법을 잘 모르겠습니다. CW이므로 누구나 쉽게 개선 할 수 있습니다.
mbomb007

1
그것이 선인지 호인지 궁금합니다. 이 낮은 해상도에서 말하기는 어렵지만 실제로는 아크가 아닐 수도 있습니다. 예를 들어 중앙 다각형의 오른쪽 선이 안쪽으로 약간 구부러진 것처럼 보입니다.
Reto Koradi

1
다른 사람의 코드를 기반으로 1100 바이트로 파싱 할 수있는 또 다른 접근법이 있습니다. 그러나 일단 골프를 치면 코드를 해독 할 수 없게됩니다. 귀하의 제출물을 골프로 처리해도 마찬가지입니다. 현재, 나는 그들이 자세한 형식으로 작동하는 방식을 이해하려고 노력하고 있습니다.
DavidC
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.