ガスケットウィービング-シェルピエスキーノットを描く


33

N> = 2の整数を指定すると、N次のシェルピスキーノットを示す画像が生成されます。

たとえば、2、3、4、5次のノットがあります。

学位2 学位3 学位4 学位5

画像をクリックしてフルサイズで表示します(次数が高いほど画像が大きくなります)。

仕様

  1. 次数Nのシェルピエスキーノットは、次数Nのシェルピエスキー三角形の頂点をガイドポイントとして使用して描画されます。次数Nのシェルピエスキー三角形は、より大きな三角形に配置された次数N-1の3つのシェルピエスキー三角形です。次数0のシェルピスキー三角形は正三角形です。
  2. 最小のコンポーネント三角形の辺の長さは64であり、ノエルの基になるSierpiński三角形は、 64 * 2 ^ N
  3. 外側の三角形の中心は、画像の中心に配置されます。これは、上部と下部に等しい空白を与えませ
  4. 出力は、辺の長さの正方形の画像です。天井(64 * 2 ^ N * 2 / ROOT3)ここで天井(x)ceiling(x)、x以上の最小の整数です。これは、三角形の中心が画像の中心にあるときに、基になるSierpiński三角形の頂点が画像内に含まれるのに十分な大きさです。
  5. 単一の曲線は、厳密に交互に上下に通過する必要があります。ソリューションは、アンダーザオーバー、オーバーザアンダー、オーバーザアンダーのいずれかを選択できます。
  6. サンプル画像は、黒い前景と白い背景を示しています。簡単に区別できる2つの色を選択できます。アンチエイリアスは許可されていますが、必須ではありません。
  7. 2つの円弧が交わる場所、または曲線がそれ自体の上または下を通る場所に隙間があってはなりません。
  8. 出力は、任意のラスター形式の画像ファイル、または正しいデフォルトの表示サイズを含む任意のベクター形式の画像ファイルになります。画面に直接表示する場合は、画面よりも大きいときにスクロールして画像全体を表示できる形式にする必要があります。

アークの中心、半径、厚さの決定

  1. 結び目は、接線が平行な点で交わる一連の円弧として構築され、シームレスな結合を提供します。これらの円弧は、環状の扇形(太さのある円弧)として表示されます。
  2. これらの円弧の中心は、最小の逆さまの三角形の頂点です。そのような各頂点は、正確に1つの円弧の中心です。
  3. 各円弧の半径は 64 * ROOT3 / 2
  4. 例外は、3つの最も外側の三角形(大きな三角形の角にある)の円弧の中心が2つの隣接する内側の頂点の中点であり、したがって半径が 64 *(ROOT3 / 2-1 / 2)
  5. 各弧は、合計の厚さ(内側半径と外側半径の差)で表され、それぞれ64 *(ROOT3 / 2)/ 4の黒い境界線の厚さは64 *(ROOT3 / 2)/ 16、曲線だけでなく、これらの境界線を持つ必要があります。

測定の単位

  1. すべての距離はピクセル単位です(1は2つの隣接するピクセル間の水平または垂直距離です)。
  2. 3の平方根は、7つの有効数字に対して正確でなければなりません。つまり、計算は、ROOT3を使用するのと同等である必要があります。1.7320505 <= ROOT3 < 1.7320515

得点

バイト単位の最短コードが優先されます。


不思議な人には、N = 0とN = 1は含まれません。これらは円と三葉に対応しているため、N> = 2に適用されるパターンとは完全には一致しません。この課題へのほとんどのアプローチでは、0と1に特別なケースコードを追加する必要があると予想されるため、それらを省略することにしました。


1
すべての数字が何に関係するのかを示す図を用意すると役立ちますか?
-trichoplax

答えを出したり、コーナーを追加したりする前に、線の太さなどの細部に7つの重要な数字が本当に必要ですか?「7桁の有効数字または1ピクセルのいずれか大きい方」などの精度がより適切と思われます。
レベルリバーセント

@LevelRiverStは入力に応じて画像のサイズが拡大するため、7桁の有効数字でも大きいNの1ピクセルの精度には不十分です。標準。
センモウヒラムシ

はい、より大きいNの画像のスケーリングが必要です。1000000x 1000000画像の有効数字7桁は0.1ピクセルに相当しますが、中間計算ではそれよりも悪い場合があります。私が考えstroke-width:3.464102ているのは、1ピクセルの精度を得るという考えであれば、似たようなものは少し過剰だということです。しかし、もしそれが判決であれば、そのようにそれを含めます。
レベルリバーセント

回答:


27

ルビー、1168 932

昨夜の間違いを修正し、明確化した後にゴルフをするようにしました。

これは(現在)stdinから数値を受け取り、svgファイルをstdoutに出力する完全なプログラムです。質問のすべての要件を満たすことが可能であることを知っていたため、svgを選択しましたが、いくつかの問題がありました。特に、SVGはpathオブジェクトの一部として円弧のみをサポートし、中心ではなく2つの端点で定義します。

コード

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のようなものを考えました。三角形は3つの異なる色のストランドに分割され、それぞれが1つのコーナーから別のコーナーへのパスを形成します。不完全な円は、そこに不完全な六角形として表示されます。六角形の内側に円を刻むと、円の半径に辺の長さをsqrt(3)/2掛けたものになるはずです。ストランドは図のように再帰的に構築できますが、角を丸くする必要があり、どの方向に湾曲するかを知るのが難しいため、さらに複雑になります。したがって、このアプローチは使用しませんでした。

私がしたことは次のとおりでした。

下の画像では、N = 2ユニット(緑色)に属する水平方向のねじれが、シエルピンスキーの三角形に配置されており、追加の架橋ねじれ(青色)があります。

パスカルの三角形の奇数がシエルピンスキーの三角形を形成することはよく知られています。2進数のsierpinski三角形は、数値で開始し、p=1で繰り返しxorすることにより、同様の方法で取得できますp<<1

私はこのアプローチを修正p=2しましたp*4。これにより、ゼロの列と交互にシエルピンスキーの三角形が得られます。

これでpを右シフトし、を使用して最後の3ビットを検査できます%8。もしそうであれば010、N = 2ユニットに属する緑のツイストを描く必要があります。もしそうなら101、青い、橋を架けるねじれを描く必要があります。これらの数値の両方を一緒にテストするには、モジュロを見つけます。%3これが2の場合、ツイストを描く必要があります。

最後に、水平方向のねじれに加えて、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画像をクリックすることは私には起こりませんでした。しかし、とにかく、これはPNGです。スタック交換はsvg画像を受け入れないため、エッジが意図的にぼやけています。私のローカルSVGファイルには、より鮮明なエッジがあり、見た目もずっと良くなっています。
レベルリバーセント

画像サイズの@trichoplaxクイックフィックスが完了しました。さらに別の日にゴルフをします。
レベルリバーセント

1
+1すばらしい仕事。私は特に色分けされた図での詳細な説明が好きです。
センモウヒラムシ

1
ハイパーリンクは無効です。
mbomb007 16
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.