シューズ(ルビー)235 231
すべてがゼロから計算されます。
Shoes.app{p,a,b,c=ARGV.map{|j|j.to_f/90}
k=1+i="i".to_c
p=(0..3).map{|j|y,z=(k*i**(j+a)).rect
x,z=(((-1)**j+z*i)*i**b).rect
q=(x+y*i)*i**c
[90*(k+q/(z-4)),90*(k+q/(4+z))]}
4.upto(15){|j|line *(p[j%4][0].rect+p[(j+j/4)%4][1].rect)}}
コマンドラインなどから呼び出す shoes cube3d.rb 0 30 0
アイデアは、3Dで四面体の4つの頂点を同時に生成/回転することです。次に、これらが2dに削減されると、逆四面体の4つの頂点が生成されます(合計8つの頂点は立方体の頂点です)。これにより、4つの対角線に対応する4組の頂点のペアが得られます。最後に、2d頂点は線で接続されます。元の四面体の各頂点は、立方体の12のエッジと4つの対角線を形成する逆四面体の各頂点に接続する必要があります。順序付けにより、ボディの対角線がプロットされなくなります。
テストケース出力
最後の2つのテストケースと一致するように、z軸を中心とした回転は、ビューアのPOVから時計回りです。しかし、これは仕様と矛盾しているようです。修正することで回転方向を逆にすることができます*i**c
->/i**c
ない
Shoes.app{
p,a,b,c=ARGV.map{|j|j.to_f/90} #Throw away first argument (script name) and translate next three to fractions of a right angle.
k=1+i="i".to_c #set up constants i=sqrt(-1) and k=1+i
p=(0..3).map{|j| #build an array p of 4 elements (each element wil be a 2-element array containing the ends of a body diagonal in complex number format)
y,z=(k*i**(j+a)).rect #generate 4 sides of square: 1+i,i-1,-1-i,-i+1, rotate about x axis by a, and store in y and z as reals
x,z=(((-1)**j+z*i)*i**b).rect #generate x axis displacements 1,-1,1,-1, rotate x and z about y axis by b, store in x and z as reals
q=(x+y*i)*i**c #rotate x and y about z axis, store result in q as complex number
[90*(k+q/(z-4)),90*(k+q/(4+z))]} #generate "far" vertex q/(4+z) and "near" vertex q/-(4-z) opposite ends of body diagonal in 2d format.
4.upto(15){|j| #iterate through 12 edges, use rect and + to convert the two complex numbers into a 4 element array for line method
line *(p[j%4][0].rect+ #cycle through 4 vertices of the "normal" tetrahedron
p[(j+j/4)%4][1].rect) #draw to three vertices of the "inverted" tetrahedron. j/4=1,2,3, never 0
} #so the three edges are drawn but the body diagonal is not.
}
歴史的な理由により、9行目で90のスケールファクターが適用されていることに注意してください(ゴルフの場合、2行目で90度と同じになるように選択されています)。任意の選択。