가스켓 제직-Sierpiński 매듭 그리기


33

정수 N> = 2가 주어지면 N 도의 Sierpiński 매듭을 보여주는 이미지를 생성하십시오.

예를 들어, 2, 3, 4 및 5 도의 매듭은 다음과 같습니다.

학위 2 학위 3 학위 4 학위 5

이미지를 클릭하면 전체 크기로 볼 수 있습니다 (도가 높을수록 이미지가 커짐).

사양

  1. N 등급의 Sierpiński 매듭은 N 등급의 Sierpiński 삼각형의 꼭지점을 안내 점으로 사용하여 그려집니다. N 등급의 Sierpiński 삼각형은 N-1 등급의 3 개의 Sierpiński 삼각형이 더 큰 삼각형으로 배열됩니다. 0 도의 Sierpiński 삼각형은 정삼각형입니다.
  2. 가장 작은 구성 요소 삼각형의 측면 길이는 64이며, 매듭이 전체 측면 길이의 기준이되는 Sierpiński 삼각형을 제공합니다. 64 * 2 ^ N
  3. 외부 삼각형의 중심은 이미지의 중심에 위치합니다. 이것은 위와 아래에 동일한 공백을 제공 하지 않습니다 .
  4. 출력 측면 길이의 정사각형 이미지 인 천장 (64 * 2 ^ N * 2 / ROOT3)천장 (x)이고 ceiling(x),보다 작은 정수 x 크거나. 이것은 삼각형의 중심이 이미지의 중앙에있을 때 기본 Sierpiński 삼각형의 상단 정점이 이미지 내에 포함될 수있을만큼 충분히 큽니다.
  5. 단일 곡선은 그 자체로 위와 아래를 통과해야합니다. 솔루션은 그 이후 또는 다음 중에서 선택할 수 있습니다.
  6. 예제 이미지는 검은 색 전경과 흰색 배경을 보여줍니다. 쉽게 구별되는 두 가지 색상을 선택할 수 있습니다. 앤티 앨리어싱은 허용되지만 필요하지는 않습니다.
  7. 두 개의 호가 만나거나 커브가 그 위로 또는 아래로 지나가는 틈이 없어야합니다.
  8. 출력은 모든 래스터 형식 이미지 파일 또는 올바른 기본 표시 크기를 포함하는 벡터 형식 이미지 파일로 출력 될 수 있습니다. 화면에 직접 표시하는 경우 화면보다 큰 경우 스크롤하여 전체 이미지를 볼 수있는 형식이어야합니다.

호 중심, 반경 및 두께 결정

  1. 매듭은 탄젠트가 평행 한 지점에서 만나 일련의 원호로 구성되어 원활한 결합을 제공합니다. 이 호는 환형 섹터 (두께가있는 호)로 표시됩니다.
  2. 이 호의 중심은 가장 작은 거꾸로 된 삼각형의 정점입니다. 이러한 각 정점은 정확히 하나의 호의 중심입니다.
  3. 각 호의 반경은 64 * ROOT3 / 2
  4. 단, 가장 바깥 쪽 3 개의 삼각형 (큰 삼각형의 모퉁이)에있는 호의 중심은 2 개의 인접한 내부 정점의 중간 점이므로 반지름이 64 * (루트 3 / 2-1 / 2)
  5. 각 호는 총 두께 (내부 반경과 외부 반지름의 차이)로 표시 64 * (루트 3/2) / 4되며 검은 테두리의 두께는 각각 두께입니다 64 * (루트 3/2) / 16.

측정 단위

  1. 모든 거리는 픽셀 단위입니다 (1은 인접한 두 픽셀 사이의 수평 또는 수직 거리).
  2. 3의 제곱근은 유효 숫자 7 자리까지 정확해야합니다. 즉, 계산은 ROOT3을 사용하는 것과 같아야합니다.1.7320505 <= ROOT3 < 1.7320515

채점

바이트 단위의 가장 짧은 코드가 이깁니다.


N = 0과 N = 1은 N> = 2에 적용되는 패턴과 일치하지 않는 원과 개미 자리에 해당하기 때문에 포함되지 않습니다. 이 과제에 대한 대부분의 접근 방식은 0과 1에 대한 특수 사례 코드를 추가해야 할 것으로 기대하므로 생략했습니다.


1
모든 숫자와 관련된 것을 보여주는 다이어그램을 만드는 것이 도움이됩니까?
trichoplax

골프를 치기 전에 / 코너를 추가하기 전에 선의 두께 등과 같은 작은 세부 사항에 실제로 7 개의 중요한 수치가 필요합니까? "7 자리 유효 숫자 또는 1 픽셀 중 더 큰 값"과 같은 정확도가 더 적절 해 보입니다.
Level River St

@LevelRiverSt 이미지의 크기가 입력에 따라 크기가 조정되므로 큰 N의 경우 1 픽셀 정확도로 7 유효 숫자조차 충분하지 않습니다. 채팅에서 약간의 토론 후에 7 유효 숫자로 정했습니다. 표준.
trichoplax

네, 더 큰 N에 대한 그림의 스케일링이 필요합니다. 1000000 x 1000000 이미지의 7 유효 숫자는 0.1 픽셀에 해당하지만 중간 계산에서는 그보다 나쁠 수 있습니다. stroke-width:3.464102아이디어가 1 픽셀 정확도를 얻는다면 약간 유사 하다고 생각 합니다. 그래도 판결 일 경우에는 그렇게하겠습니다.
Level River St

답변:


27

루비, 1168 (932)

어제 밤의 실수를 수정하여 명확하게 한 후 더 많은 골프를칩니다.

이것은 (현재) stdin에서 숫자를 받아 svg파일을 stdout으로 출력하는 전체 프로그램입니다 . 나는 질문의 모든 요구 사항을 충족시킬 수 있다는 것을 알고 svg를 선택했지만 몇 가지 문제가있었습니다. 특히 SVG는 path객체의 일부로 원호 만 지원 하며 중심을 기준으로 정의하지 않고 두 끝점으로 정의합니다.

암호

n=gets.to_i
r=64*w=0.75**0.5
m=1<<n-2
z=128*m/w
a=(s="<path style='fill:none;stroke:black;stroke-width:3.464102' transform='translate(%f %f)'
")%[0,r-r*m*8/3]+"d='M18.11943,-2A#{b=r-6*w-32} #{b} 0 0,0 #{-b} 0#{k='A%f %f 0 0 '%([58*w]*2)}0 0,38.71692
M28.58980,1.968882#{l='A%f %f 0 0 '%([70*w]*2)}0 #{c=r+6*w-32} 0A#{c} #{c} 0 0,0 #{-c} 0#{l}0 -9 44.65423'/>"
p=2
m.times{|i|(i*2+1).times{|j|(p>>j)%8%3==2&&a<<s%[128*(j-i),r*3+r*i*4-r*m*8/3]+
"d='M-55,44.65423#{k}0 11.5,25.11473#{l}1 35.41020,1.968882
M-64,51.48786#{l}0 20.5,30.31089#{k}1 36.82830,13.17993
M-82.17170,-2.408529#{l}1 -11.5,25.11473#{k}0 0,38.71692
M-81.52984 8.35435#{k}1 -20.5,30.31089#{l}0 -9,44.65423
M9,44.65423#{k}0 81.52984,8.35435
M0,51.48786#{l}0 91.17169,13.17993'/>"}
p^=p*4}
puts "<svg xmlns='http://www.w3.org/2000/svg' viewBox='#{-z} #{-z} #{e=2*z+1} #{e}' width='#{e}px' height='#{e}px'>"+
"<g transform='rotate(%d)'>#{a}</g>"*3%[0,120,240]+"</svg>"

출력 N = 4

스택 교환에 의해 재조정됩니다. 원본보다 훨씬 나아 보입니다.

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

처음에 나는 삼각형이 세 개의 다른 색깔의 가닥으로 나뉘는 http://euler.nmt.edu/~jstarret/sierpinski.html 과 같은 것을 고려했는데 , 각 삼각형은 한 모서리에서 다른 모서리로 경로를 형성합니다. 불완전한 원은 불완전한 육각형으로 표시됩니다. 육각형 안에 원을 sqrt(3)/2그리면 원의 반지름이 측면 길이의 곱 이어야한다는 것을 알 수 있습니다 . 스트랜드는 그림과 같이 재귀 적으로 구축 될 수 있지만 모서리를 둥글게해야하고 곡선 방향을 알기가 어렵 기 때문에 합병증이 추가되어 있으므로이 접근법을 사용하지 않았습니다.

내가 한 것은 다음과 같습니다.

아래 이미지에서 sierpinski 삼각형으로 배열 된 N = 2 단위 (녹색)에 속하는 수평 트위스트와 추가 브리징 트위스트 (파란색)가 있습니다.

파스칼 삼각형의 홀수는 sierpinski 삼각형을 형성한다는 것은 일반적인 지식입니다. 이진수의 sierpinski 삼각형은 숫자로 시작하여 p=1반복적으로 xoring 하여 유사한 방식으로 얻을 수 있습니다.p<<1 .

에서 시작하여 p=2반복적으로 xoring 하여이 접근법을 수정했습니다 p*4. 이것은 0의 열로 번갈아가는 sierpinski 삼각형을 제공합니다.

이제 p를 오른쪽으로 시프트하고을 사용하여 마지막 3 비트를 검사 할 수 있습니다 %8. 그것들이 있다면 010N = 2 단위에 속하는 녹색 트위스트를 그려야합니다. 만약 그들이 101우리 라면 , 푸른 색의 다리를 꼬 아야합니다. 이 두 숫자를 함께 테스트하려면 모듈로를 찾고 %3이것이 2 인 경우 꼬임을 그려야합니다.

마지막으로 수평 비틀림 외에도 120도 및 240도 회전하여 두 개의 사본을 만들어 대각선 비틀기를 그려 그림을 완성합니다. 남아있는 것은 모서리를 추가하는 것입니다.

주석이 달린 코드

n=gets.to_i

#r=vertical distance between rows 
r=64*w=0.75**0.5

#m=number of rows of horizontal twists
m=1<<n-2

#z=half the size of the viewport
z=128*m/w

#s=SVG common to all paths
s="<path style='fill:none;stroke:black;stroke-width:3.464102' transform='translate(%f %f)'
"

#initialize a with SVG to draw top corner loop. Set k and l to the SVG common to all arcs of 58*w and 70*w radius 
a=s%[0,r-r*m*8/3]+
"d='M18.11943,-2A#{b=r-6*w-32} #{b} 0 0,0 #{-b} 0#{k='A%f %f 0 0 '%([58*w]*2)}0 0,38.71692
M28.58980,1.968882#{l='A%f %f 0 0 '%([70*w]*2)}0 #{c=r+6*w-32} 0A#{c} #{c} 0 0,0 #{-c} 0#{l}0 -9 44.65423'/>"

#p is the pattern variable, top row of twists has one twist so set to binary 00000010
p=2

#loop vertically and horizontally
m.times{|i|
 (i*2+1).times{|j|

   #leftshift p. if 3 digits inspected are 010 or 101 
   (p>>j)%8%3==2&&

   #append to a, the common parts of a path...
   a<<s%[128*(j-i),r*3+r*i*4-r*m*8/3]+

   #...and the SVG for the front strand and left and right parts of the back strand (each strand has 2 borders)
"d='M-55,44.65423#{k}0 11.5,25.11473#{l}1 35.41020,1.968882
M-64,51.48786#{l}0 20.5,30.31089#{k}1 36.82830,13.17993
M-82.17170,-2.408529#{l}1 -11.5,25.11473#{k}0 0,38.71692
M-81.52984 8.35435#{k}1 -20.5,30.31089#{l}0 -9,44.65423
M9,44.65423#{k}0 81.52984,8.35435
M0,51.48786#{l}0 91.17169,13.17993'/>"}

#modify the pattern by xoring with 4 times itself for the next row
p^=p*4}

#output complete SVG of correct size with three copies of the finished pattern rotated through 0,120,240 degrees.
puts "<svg xmlns='http://www.w3.org/2000/svg' viewBox='#{-z} #{-z} #{e=2*z+1} #{e}' width='#{e}px' height='#{e}px'>"+
"<g transform='rotate(%d)'>#{a}</g>"*3%[0,120,240]+"</svg>"

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


"원본보다 훨씬 나아 보인다"고 말하는 곳을 모르는 사람에게는 "(이미지를 클릭하여 전체 크기로보기)"와 같은 것을 추가하는 것이 좋습니다.
trichoplax

@trichoplax 이미지를 클릭해도 발생하지 않았습니다. 그러나 스택 교환은 svg 이미지를 허용하지 않으므로 가장자리가 의도적으로 흐리게 표시되기 때문에 어쨌든 이것은 PNG입니다. 내 로컬 SVG 파일은 가장자리가 훨씬 선명하고 훨씬 좋아 보입니다.
Level River St

이미지 크기에 @trichoplax 빠른 수정. 하루 더 골프를 할 것입니다.
Level River St

1
대단한 일 +1. 특히 색상 코드 다이어그램으로 자세한 설명을 좋아합니다.
trichoplax

1
하이퍼 링크가 죽었습니다.
mbomb007
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.