鞋(红宝石)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中同时生成/旋转四面体的四个顶点。然后,当将它们减少到2d时,我们生成反四面体的四个顶点(总共8个顶点是立方体的顶点)。这给出了对应于4个对角线的4对顶点。最后,二维顶点通过线连接:原始四面体的每个顶点必须连接到反四面体的每个顶点,从而形成立方体的12个边和4个对角线。该顺序确保不绘制车身对角线。
测试用例输出
请注意,与后两个测试用例一致,围绕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度相同),但最终使用此特定值并没有高尔夫球优势,因此它已成为任意选择。