Vẽ một ngôi sao Giáng sinh / Dodecahedron Stellated


10

Ngôi sao giấy là một điều lớn trong gia đình tôi vào Giáng sinh, vì vậy tôi nghĩ rằng một người ảo sẽ rất tuyệt.

Dưới đây là hình ảnh của một khối mười hai mặt thông thường (từ https://en.wikipedia.org/wiki/Dodecahedron , được quy cho tác giả được đề cập ở đó.)

nhập mô tả hình ảnh ở đây

Quá trình sao chép (wikipedia) khi áp dụng cho khối đa diện liên quan đến việc mở rộng các mặt cho đến khi chúng vượt qua các mặt khác. Do đó, bắt đầu với khối mười hai mặt thông thường, chúng ta có được các hình dạng sau:

Dodecahedron Stellated nhỏ, Dodecahedron lớn và Dodecahedron Stellated lớn

Hình ảnh từ http://jwilson.coe.uga.edu/emat6680fa07/thrash/asn1/stellations.html

nhập mô tả hình ảnh ở đây

Đây là ba Stellations of the dodecahedron (Wolfram). Chúng tạo thành một sự tiến triển tự nhiên từ khối mười hai mặt, đến khối mười hai sao nhỏ, khối mười hai mặt lớn và khối mười hai mặt lớn, khi chúng ta mở rộng khuôn mặt ra xa hơn.

Bài tập

Chương trình hoặc chức năng của bạn sẽ hiển thị hoặc xuất ra một tệp hình ảnh một trong các khối đa diện sau: Khối mười hai mặt thông thường, khối mười hai mặt nhỏ, khối mười hai mặt lớn hoặc Dodecahedron vĩ đại .

Bảng màu nên như hình ảnh thứ hai ở trên. Mỗi sáu cặp mặt đối diện sẽ là một trong sáu màu Đỏ, Vàng, Xanh lục, Lục lam, Xanh lam và Đỏ tươi. Bạn có thể sử dụng các màu mặc định với các tên này trong ngôn ngữ hoặc tài liệu của nó hoặc sử dụng các màu FF0000, FFFF00, 00FF00, 00FFFF, 0000FF và FF00FF (bạn có thể giảm các màu này xuống bằng cách giảm cường độ xuống tối thiểu 75% nếu muốn, ví dụ: bằng cách giảm F xuống còn C.)

Lưu ý rằng chúng tôi xác định "khuôn mặt" là tất cả các khu vực trong cùng một mặt phẳng. Do đó, trong các hình ảnh phía trên mặt trước có màu vàng (và mặt sau song song cũng sẽ có màu vàng.)

Nền nên có màu đen, xám hoặc trắng. Các cạnh có thể được bỏ qua, nhưng nên có màu đen nếu được vẽ.

Quy tắc

Đa diện được hiển thị phải có chiều rộng từ 500 đến 1000 pixel (chiều rộng được xác định là khoảng cách tối đa giữa hai đỉnh được hiển thị.)

Khối đa diện được hiển thị phải nằm trong hình chiếu phối cảnh (điểm quan sát cách khối đa diện ít nhất 5 chiều rộng) hoặc hình chiếu chính tả (có hiệu quả là hình chiếu phối cảnh với điểm nhìn ở vô cực).

Khối đa diện phải được hiển thị từ mọi góc độ. (Không thể chấp nhận chọn góc dễ nhất có thể và tạo hình dạng 2D được mã hóa cứng.) Người dùng có thể chỉ định góc theo một trong các cách sau:

  1. Đầu vào của ba góc tương ứng với ba góc quay, từ stdin hoặc dưới dạng tham số hàm hoặc dòng lệnh. Đây có thể là các góc Euler (trong đó các góc quay đầu tiên và cuối cùng nằm trên cùng một trục) hoặc các góc Tait-Bryan (trong đó có một góc xoay mỗi trục về trục x, y và z) https://en.wikipedia.org/ wiki / Euler_angles (nói một cách đơn giản, mọi thứ sẽ diễn ra miễn là mỗi vòng quay là về trục x, y hoặc z và các phép quay liên tiếp là về các trục vuông góc.)

  2. Thiết bị cho người dùng xoay khối đa diện theo các bước không quá 10 độ về trục x và y và làm mới màn hình, bất kỳ số lần tùy ý (giả sử trục z vuông góc với màn hình).

Khối đa diện phải chắc chắn, không phải khung dây.

Không có nội dung nào để vẽ đa diện được cho phép (Tôi đang nhìn bạn, Mathicala!)

Chấm điểm

Đây là cá tuyết. Mã ngắn nhất trong byte thắng.

Tiền thưởng

Nhân số điểm của bạn với 0,5 nếu bạn không sử dụng nội trang cho bản vẽ 3D.

Nhân số điểm của bạn với 0,7 nếu bạn có thể hiển thị cả ba ngôi sao của khối mười hai mặt, người dùng có thể chọn bởi một số nguyên 1-3 được nhập từ stdin hoặc theo tham số hàm hoặc dòng lệnh.

Nếu bạn nhận được cả hai phần thưởng, điểm của bạn sẽ được nhân với 0,5 * 0,7 = 0,35

Thông tin hữu ích (nguồn như dưới đây)

https://en.wikipedia.org/wiki/Regular_dodecahedron

https://en.wikipedia.org/wiki/Regular_icosahedron

Khối mười hai mặt có 20 đỉnh. 8 trong số chúng tạo thành các đỉnh của một khối lập phương có tọa độ cartesian (x, y, z) sau đây:

(± 1, ± 1, ± 1)

12 số còn lại như sau (phi là tỷ lệ vàng)

(0, ± 1 /, ± φ)

(± 1 /, ± φ, 0)

(±, 0, ± 1 /)

Vỏ lồi của khối mười hai mặt nhỏ và khối mười hai mặt rõ ràng là một khối mười hai mặt thông thường. Các đỉnh bên ngoài mô tả một icosahedron.

Theo Wikipedia, 12 đỉnh của icosahedron có thể được mô tả theo cách tương tự như hoán vị theo chu kỳ của (0, ± 1, ±). Các đỉnh bên ngoài của dodecaheron nhỏ và dodechahedron lớn (có cùng tỷ lệ với dodecahedron ở trên) tạo thành một icosahedron lớn hơn, trong đó tọa độ của các đỉnh là hoán vị tuần hoàn của (0, ± φ ^ 2, ±).

Các góc giữa các mặt của khối mười hai mặt và icosahedron lần lượt là 2 arctan (phi) và arccos (- (√5) / 3).

Để biết các mẹo về xoay vòng, hãy xem https://en.wikipedia.org/wiki/Rotation_matrix

EDIT: Do nhầm lẫn, tôi đã cho phép khối mười hai mặt thông thường và không thể rút lại ngay bây giờ. Phần thưởng x0.7 cho việc vẽ cả ba khối đa diện vẫn còn. Vào ngày đầu năm, tôi sẽ phát hành tiền thưởng 100 cho câu trả lời có thể hiển thị hầu hết bốn khối đa diện, với mã ngắn nhất là ngắt kết nối.


Các bản dựng @ LegionMammal978 để vẽ các khối đa diện (ví dụ dodecahedron) không được phép. Một số ngôn ngữ có phương tiện để xây dựng mô hình 3D với các lệnh như triangle[[a,b,c],[p,q,r],[x,y,z]]. Các ngôn ngữ này thường có tích hợp để xoay và hiển thị mô hình, tự động chú ý không hiển thị các mặt ẩn, v.v ... Các giải pháp như những thứ này được cho phép nhưng sẽ không thu hút được phần thưởng. Mục đích của phần thưởng là cho phép các ngôn ngữ không có các cơ sở này có khả năng cạnh tranh và cũng để thu hút các giải pháp thú vị hơn.
Cấp sông St

@ LegionMammal978 haha, tôi biết Mathicala sẽ là ngôn ngữ gây ra vấn đề. Polyhedrondatakhông được phép vì nó rõ ràng là một nội dung để vẽ các khối đa diện. Nếu câu trả lời của bạn không sử dụng nội dung để vẽ khối đa diện và tuân thủ các quy tắc khác, thì có thể chấp nhận được. Quan điểm của bạn dường như là do thực tế là bạn phải tô màu cho khuôn mặt một cách chính xác, Polyhedrondatadù sao cũng sẽ không giúp bạn tiết kiệm nhiều, vì vậy thực tế nó có thể là một hạn chế tùy tiện. Tôi đồng ý ở một mức độ nào đó, nhưng sẽ công bằng hơn cho tất cả nếu tôi tránh thay đổi quy tắc sau khi đăng.
Cấp sông St

Câu trả lời:


3

Python 2.7, 949 byte

Dưới đây là giải pháp cho khối mười hai mặt thông thường được vẽ bằng matplotlib. Phác thảo sơ bộ cho mã không mã hóa (không được hiển thị ở đây) đã được phác thảo dưới đây:

  • Tạo các đỉnh Tạo các cạnh (dựa trên 3 lân cận gần nhất, mô-đun scipy.spatial.KDtree)
  • Tạo khuôn mặt dựa trên chu kỳ đồ thị với chiều dài 5 (mô-đun mạngx)
  • Tạo facenormals (và chọn những người có bề ngoài bình thường, numpy.cross)
  • Tạo màu dựa trên quy tắc khuôn mặt
  • Vẽ đồ thị bằng matplotlib
import itertools as it
import numpy as np
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
import matplotlib.pyplot as plt
v=[p for p in it.product((-1,1),(-1,1),(-1,1))]
g=.5+.5*5**.5
v.extend([p for p in it.product((0,),(-1/g,1/g),(-g,g))])
v.extend([p for p in it.product((-1/g,1/g),(-g,g),(0,))])
v.extend([p for p in it.product((-g,g),(0,),(-1/g,1/g))])
v=np.array(v)
g=[[12,14,5,9,1],[12,1,17,16,0],[12,0,8,4,14],[4,18,19,5,14],[4,8,10,6,18],[5,19,7,11,9],[7,15,13,3,11],[7,19,18,6,15],[6,10,2,13,15],[13,2,16,17,3],[3,17,1,9,11],[16,2,10,8,0]]
a=[2,1,0,3,4,5,0,1,2,3,4,5]
fig = plt.figure()
ax = fig.add_subplot((111),aspect='equal',projection='3d')
ax.set_xlim3d(-2, 2)
ax.set_ylim3d(-2, 2)
ax.set_zlim3d(-2, 2)
for f in range(12):
 c=Poly3DCollection([[tuple(y) for y in v[g[f],:]]], linewidths=1, alpha=1)
 c.set_facecolor([(0,0,1),(0,1,0),(0,1,1),(1,0,0),(1,0,1),(1,1,0)][a[f]])
 ax.add_collection3d(c)
ax.auto_scale_xyz
plt.show()

nhập mô tả hình ảnh ở đây


3

Ruby, 784 byte * 0,5 * 0,7 = 274,4

Câu trả lời của riêng tôi, do đó không đủ điều kiện cho tiền thưởng của tôi.

Đủ điều kiện cho cả phần thưởng dựng sẵn không phải 3D và phần thưởng vẽ tất cả các sao.

->t,n{o=[]
g=->a{a.reduce(:+)/5}
f=->u,v,w,m{x=u.dup;y=v.dup;z=w.dup
15.times{|i|k,l=("i".to_c**(n[i/5]/90.0)).rect
j=i%5
x[j],y[j],z[j]=y[j],x[j]*k+z[j]*l,z[j]*k-x[j]*l}
p=g[x];q=g[y];r=g[z]
a=[0,1,-i=0.382,-1][t]*e=r<=>0
b=[j=1+i,0,j,j][t]*e
c=[-i*j,-i,1,i][t]*e
d=[j*j,j,0,0][t]*e
5.times{|i|o<<"<path id=\"#{"%9.0f"%(z[i]*a+r*b+(z[i-2]+z[i-3])*c+2*r*d+999)}\"
d=\"M#{(x[i]*a+p*b)} #{(y[i]*a+q*b)}L#{(x[i-2]*c+p*d)} #{(y[i-2]*c+q*d)}L#{(x[i-3]*c+p*d)} #{(y[i-3]*c+q*d)}\"
fill=\"##{m}\"/>"}}
a=233
b=377
z=[0,a,b,a,0]
y=[a,b,0,-b,-a]
x=[b,0,-a,0,b]
w=[-b,0,a,0,-b]
f[x,y,z,'F0F']
f[w,y,z,'0F0']
f[y,z,x,'00F']
f[y,z,w,'FF0']
f[z,x,y,'F00']
f[z,w,y,'0FF']
s=File.open("p.svg","w")
s.puts'<svg xmlns="http://www.w3.org/2000/svg" viewBox="-450 -450 900 900">',o.sort,'</svg>'
s.close}

Nhập dưới dạng tham số chức năng

Một số nguyên 0..3 tương ứng với khối mười hai mặt thông thường, khối mười hai mặt nhỏ, khối mười hai mặt lớn

Một mảng gồm ba số nguyên tương ứng với các góc độ cho các phép quay về các trục x, y và x (một lần nữa) (các góc Euler thích hợp, cho phép đạt được bất kỳ phép quay nào.)

Xuất ra một tệp p.svgcó thể được hiển thị trong trình duyệt web.

Giải trình

các mảng x, y, z ở dưới cùng của mã chứa tọa độ của các điểm ngoài của một mặt của một khối mười hai mặt sao nhỏ. Điều này có thể được ghi trong icosahedron có 12 đỉnh được xác định bởi các hoán vị tuần hoàn của (+/- 377, + / - 233, + / - 0). Lưu ý rằng 377 và 233 là các số Fibonacci liên tiếp và do đó, 377/233 là một xấp xỉ tuyệt vời với tỷ lệ vàng.

một mảng bổ sung w chứa tọa độ x nhân với -1, tương đương với phản xạ trong mặt phẳng x. Hàm f được gọi 6 lần, một lần cho mỗi màu, với các hoán vị tuần hoàn khác nhau của x, y, z và w, y, z.

Ba phép quay được truyền dưới dạng tham số trong n []. để sử dụng sin và cos trong Ruby, cần phải làm include Math. để tránh điều này, cosin và sin của góc có được bằng cách nâng căn bậc hai của -1 "i"lên lũy thừa (góc tính bằng độ / 90) Phần thực và ảo của số này được lưu trữ trong k (cosine) và l ( sin)

Trước khi xoay, giá trị x và y được trao đổi. Sau đó, phép nhân ma trận được áp dụng cho các giá trị y và z để tạo ra một phép quay về trục x. Việc trao đổi các giá trị cho phép ba phép quay được thực hiện trong một vòng lặp.

Cho đến nay, chúng ta chỉ có một vòng điểm. Để có được phần còn lại, chúng ta cần tìm tâm của hình ngũ giác / ngôi sao. Điều này được thực hiện bằng cách tìm trung bình tọa độ của 5 đỉnh, được lưu trữ trong p, q, r.

Như đã đề cập trước đó, chỉ có một chức năng gọi cho mỗi màu được thực hiện. Dấu của r (trung bình của tọa độ z, và do đó tọa độ của mặt) được kiểm tra. Nếu nó là dương tính, khuôn mặt là một mặt trước và do đó có thể nhìn thấy. Nếu nó là âm tính, khuôn mặt là một mặt sau. Nó là vô hình, và chúng tôi không có chức năng gọi cho mặt đối diện. Do đó, cả ba tọa độ phải được đảo ngược. Dấu hiệu của r được lưu trữ trong e để tạo điều kiện này.

Mặt được xây dựng gồm 5 hình tam giác, có các đỉnh là sự kết hợp tuyến tính của các đỉnh bên ngoài của khối mười hai mặt nhỏ và tâm của mặt. Trong trường hợp của khối mười hai mặt nhỏ, cho các đầu của các tam giác, chúng ta đặt a = 1 và b = 0 (đóng góp 1 từ x, y, z và 0 từ p, q, r). Đối với 2 đỉnh cơ sở của tam giác, chúng ta đặt c = -0.382 (đóng góp 1 / tỷ lệ vàng ^ 2 từ x, y, z) và d = 1.382 (đóng góp từ p, q, r.) Lý do cho đóng góp âm là rằng các đỉnh cơ sở của tam giác được xác định theo các mẹo đối diện, nằm ở phía đối diện của khuôn mặt. Các tọa độ thu được được nhân với e khi cần thiết.

Bốn mảng không được đặt tên có các giá trị được gán để a,b,c,dchứa các giá trị cần thiết cho khối mười hai mặt thông thường, khối mười hai mặt nhỏ, khối mười hai mặt lớn và khối sợi hình sao lớn, được chọn theo biến tLưu ý rằng cho khối hình sao nhỏ d = 1. Mối quan hệ a + b = c + d áp dụng cho các hình dạng khác, nhưng một tỷ lệ khác được áp dụng.

Một dòng mã svg được tạo cho mỗi tam giác. Điều này chứa một ID xuất phát từ tổng tọa độ z của 3 đỉnh của tam giác, mô tả các đỉnh của ba tọa độ của tam giác và một màu. lưu ý rằng chúng ta xem thẳng trục z trong phép chiếu chính tả. Do đó 2D x = 3D x và 2D y = 3D y. Dòng được thêm vàoh.

cuối cùng, sau khi tất cả các lệnh gọi kết thúc, h được sắp xếp sao cho các tam giác có giá trị z cao nhất (ở phía trước) được vẽ sau cùng, và toàn bộ điều được lưu dưới dạng tệp svg với văn bản đầu trang và chân trang phù hợp.

Ungolfed trong chương trình thử nghiệm

h=->t,n{                                              #t=type of polygon,n=angles of rotation
o=[]                                                  #array for output
g=->a{a.reduce(:+)/5}                                 #auxiliary function for finding average of 5 points

f=->u,v,w,m{x=u.dup;y=v.dup;z=w.dup                   #function to take 5 points u,v,w and plot one face (5 triangles) of the output in colour m 

  15.times{|i|                                        #for each of 3 rotation angle and 5 points
    k,l=("i".to_c**(n[i/5]/90.0)).rect                #calculate the cos and sine of the angle, by raising sqrt(-1)="i" to a power
    j=i%5                                             #for each of the 5 points
    x[j],y[j],z[j]=y[j],x[j]*k+z[j]*l,z[j]*k-x[j]*l}  #swap x and y, then perform maxtrix rotation on (new) y and z.

  p=g[x];q=g[y];r=g[z]                                #find centre p,q,r of the face whose 5 points (in the case of small stellated dodecahedron) are in x,y,z

  e=r<=>0                                             #if r is positive, face is front. if negative, face is back, so we need to transform it to opposite face.
  a=[0,              1,    -0.382,    -1][t]*e        #contribution of 5 points x,y,z to triangle tip vertex coordinates
  b=[1.382,          0,     1.382,     1.382][t]*e    #contribution of centre p,q,r to triangle tip vertex coordinates
  c=[-0.528,        -0.382, 1,         0.382][t]*e    #contribution of 5 points x,y,z to coordinates of each triangle base vertex 
  d=[1.901,          1.382, 0,         0][t]*e        #contribution of centre p,q,r to coordinates of each triangle base vertex

  5.times{|i|
  o<<"<path id=\"#{"%9.0f"%(z[i]*a+r*b+(z[i-2]+z[i-3])*c+2*r*d+999)}\"
d=\"M#{(x[i]*a+p*b)} #{(y[i]*a+q*b)}L#{(x[i-2]*c+p*d)} #{(y[i-2]*c+q*d)}L#{(x[i-3]*c+p*d)} #{(y[i-3]*c+q*d)}\"
fill=\"##{m}\"/>"}                                    #write svg code for this triangle 
}

  a=233                                               #a,b =coordinate standard values 
  b=377
  z=[0,a,b,a,0]                                       #z coordinates for one face of stellated dodecahedron 
  y=[a,b,0,-b,-a]                                     #y coordinates
  x=[b,0,-a,0,b]                                      #x coordinates
  w=[-b,0,a,0,-b]                                     #alternate  x coordinates

  f[x,y,z,'F0F']                                      #call f
  f[w,y,z,'0F0']                                      #to plot
  f[y,z,x,'00F']                                      #each
  f[y,z,w,'FF0']                                      #face
  f[z,x,y,'F00']                                      #in
  f[z,w,y,'0FF']                                      #turn

  s=File.open("p.svg","w")                            #sort output in o, plot front triangles last
  s.puts'<svg xmlns="http://www.w3.org/2000/svg" viewBox="-450 -450 900 900">',o.sort,'</svg>'
  s.close                                             #add header and footer, and save as svg
}

t=gets.to_i
n=[]
3.times{n<<gets.to_i}
h[t,n]

Đầu ra

cho khối mười hai sao nhỏ (sẽ thêm một số hình ảnh của các đa giác khác sớm)

Vị trí nhà 1,0,0,0

nhập mô tả hình ảnh ở đây

1,30,0,0 xoay xuống 30 độ

nhập mô tả hình ảnh ở đây

1,0,30,0 xoay phải 30 độ (lưu ý: để có góc nhìn hoàn hảo, góc quay sẽ là atan(1/golden ratio)= 31,7 độ, do đó chúng ta vẫn có thể thấy một mảnh nhỏ màu xanh)

nhập mô tả hình ảnh ở đây

1,0,20,0 xoay phải 20 độ

nhập mô tả hình ảnh ở đây

1,60,10, -63 xoay xuống, phải và lên (ví dụ về định hướng chỉ có thể có với 3 lần quay)

nhập mô tả hình ảnh ở đây

0,30,0,0 dodecahedron thường xuyên

nhập mô tả hình ảnh ở đây

2,0,20,0 cây đại thụ

nhập mô tả hình ảnh ở đây

3,45,45,45 dodecahedron tuyệt vời nhập mô tả hình ảnh ở đây


3

Toán học, 426 424 byte

Graphics3D[{Red,Yellow,Green,Cyan,Blue,Magenta}~Riffle~(a=Partition)[Polygon/@Uncompress@"1:eJxtkjEKwkAURNeoySYgeAVP4QFsrcTGTiyUBcEith7A2wgKgpVH8/vgs2TYZmAyw9/5k784XDbHVwihnxisU39N9SiEdI8GO/uWHpXBtjFAgJ7HToFl5WabEdJ+anCqDb6dU9RP65NR59EnI0CZDAWYjFmomBmPCn3/hVVwc9s4xYd66wYqFJVvhMz75vWlHIkhG2HBDJ1V3kYps7z7jG6GomIu/QUJKTGkdtlX2pDM8m6pydyzHIOElBhyG6V9cxulzPldaVJ6lpuUkKUTzWcm+0obkrn0f3OT0rMc0jDkD37nlUo="~a~3~a~5,2],Boxed->1<0]

Sử dụng tích hợp Graphics3Dđể hiển thị hình dạng. Tuy nhiên, hầu hết các byte được đưa lên bởi các vị trí đỉnh được nén, sau đó được Partitionchuyển thành một dạng có thể sử dụng được Polygon. Cuối cùng:

Lưu ý rằng hình dạng này có thể được xoay bằng cách nhấp và kéo.


OMG, tôi sẽ xóa dodecahedron thường xuyên! Theo như tôi có thể nói (tôi không biết hoặc có Mathicala) thì điều này tuân thủ các quy tắc, vì vậy +1.
Cấp sông St

@steveverrill Tôi không nghĩ rằng nó sẽ thay đổi kích thước quá nhiều, nhưng tôi không muốn phải viết lại từ đầu.
LegionMammal978

Câu trả lời của bạn vẫn còn hiệu lực, tôi sẽ không thay đổi các quy tắc, nó sẽ là hình thức xấu. Tuy nhiên, ngoài phần thưởng 0,7 cho ba khối đa diện, tôi đã đưa ra một tiền thưởng cho câu trả lời có thể tạo ra hầu hết bốn khối đa diện. Nếu bạn đã quyết định cập nhật câu trả lời của mình, tôi cho rằng bạn có thể tiết kiệm rất nhiều byte bằng cách tạo tọa độ theo thuật toán (xem phần thông tin hữu ích của câu hỏi.)
Level River St

@steveverrill, tôi sẽ, nhưng rõ ràng, các vị trí đỉnh liên quan đến gốc rễ của tứ phân, và tôi không thể tìm thấy một mô hình.
LegionMammal978
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.