クリスマスの星を描く/星形十二面体


10

紙の星は私の家族のクリスマスの大物なので、私は仮想の星がクールだと思いました。

以下は、正十二面体の画像です(https://en.wikipedia.org/wiki/Dodecahedronから、そこで言及された作者に帰属します)。

ここに画像の説明を入力してください

星座のプロセス(ウィキペディア)を多面体に適用すると、他の面と交差するまで面が拡張されます。したがって、通常の12面体から始めて、次の形状を取得します。

小さな十二面体、大きな十二面体、そして大きな十二面体

http://jwilson.coe.uga.edu/emat6680fa07/thrash/asn1/stellations.htmlからの画像

ここに画像の説明を入力してください

これらは、十二面体(ウルフラム)の3つの可能な星座です。それらは、12面体から小さな12面体、大きな12面体、そして大きな12面体へと自然に進行します。

仕事

プログラムまたは関数は、次の多面体の1つである画像ファイルを表示または出力する必要があります。正十二面体、小さい星形十二面体、大きい十二面体または大きい星形十二面体

配色は上の2番目の画像のようになります。6対の向かい合う面のそれぞれは、赤、黄、緑、シアン、青、マゼンタの6色のいずれかになります。言語またはそのドキュメントでこれらの名前のデフォルトの色を使用するか、FF0000、FFFF00、00FF00、00FFFF、0000FF、FF00FFの色を使用できます(必要に応じて、強度を最低75%に下げることで、これらのトーンを下げることができます。たとえば、FをCに減らすなど)。

「面」を同じ平面内のすべての領域として定義することに注意してください。したがって、上の画像の前面は黄色です(平行な背面も黄色になります)。

背景は黒、灰色、または白でなければなりません。エッジは省略できますが、描画する場合は黒にする必要があります。

ルール

表示される多面体の幅は500〜1000ピクセルである必要があります(幅は、表示される2つの頂点間の最大距離として定義されます)。

表示される多面体は、透視投影(多面体から少なくとも5幅離れた視点)、または正射影(事実上、視点が無限遠にある透視投影)でなければなりません。

多面体はどの角度からでも表示できる必要があります。(可能な限り簡単な角度を選択してハードコードされた2D形状を作成することはできません。)角度は、次のいずれかの方法でユーザーが指定できます。

  1. stdinから、または関数またはコマンドラインパラメータとして、3つの回転に対応する3つの角度の入力。これらは、オイラー角(最初と最後の回転が同じ軸を中心とする)またはテイトブライアン角(x、y、z軸を中心に1回転)のいずれかになります。https://en.wikipedia.org/ wiki / Euler_angles(簡単に言えば、各回転がx、y、またはz軸を中心とし、連続した回転が垂直軸を中心とするものであれば何でもかまいません。)

  2. ユーザーが多面体をx軸とy軸を中心に10度以下のステップで回転させ、任意の回数だけ画面を更新するための機能(画面に垂直なz軸を想定)。

多面体はワイヤーフレームではなく、ソリッドでなければなりません。

多面体を描画するための組み込み関数は許可されていません(Mathematicaであなたを探しています!)

得点

これはコードゴルフです。バイト単位の最短コードが優先されます。

ボーナス

3D描画にビルトインを使用しない場合は、スコアに0.5を掛けます。

12面体の星座を3つすべて表示できる場合は、スコアに0.7を掛けます。これは、ユーザーがstdinから入力した1〜3の整数で選択するか、関数またはコマンドラインパラメーターで選択できます。

両方のボーナスを獲得すると、スコアに0.5 * 0.7 = 0.35が掛けられます。

役立つ情報(以下のソース)

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

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

十二面体には20個の頂点があります。それらのうちの8つは、次のデカルト(x、y、z)座標を持つ立方体の頂点を形成します。

(±1、±1、±1)

残りの12は次のとおりです(ファイは黄金比です)

(0、±1 /φ、±φ)

(±1 /φ、±φ、0)

(±φ、0、±1 /φ)

小さい星形の十二面体と大きい十二面体の凸包は明らかに正十二面体です。外側の頂点は二十面体を表します。

ウィキペディアによると、正二十面体の12個の頂点は、(0、±1、±φ)の巡回置換と同じように記述できます。小さな星形の十二面体と大きい十二面体(上記の十二面体と同じスケール)の外側の頂点は、より大きな二十面体を形成し、頂点の座標は(0、±φ^ 2、±φ)の巡回置換です。

12面体と20面体の面間の角度は、それぞれ2 arctan(phi)とarccos(-(√5)/ 3)です。

回転のヒントについては、https://en.wikipedia.org/wiki/Rotation_matrixを参照してください

編集:誤って、正十二面体を許可しましたが、今は後退できません。星状多面体の3つすべてを描画するためのx0.7ボーナスは残っています。元日には、4つの多面体のほとんどを表示できる回答に対して100の賞金を発行します。タイブレイクとして最短のコードを使用します。


多面体を描画するための@ LegionMammal978ビルトイン(例:)dodecahedronは許可されていません。一部の言語には、などのコマンドを使用して3Dモデルを作成する機能がありますtriangle[[a,b,c],[p,q,r],[x,y,z]]。これらの言語には通常、モデルを回転して表示する組み込み機能があり、自動的に隠された顔が表示されないようにします。これらのようなソリューションは許可されていますが、ボーナスを引き付けません。ボーナスの目的は、これらの機能を持たない言語が競争力を持つことを可能にし、さらに興味深いソリューションを引き付けることです。
Level River St

@ LegionMammal978ははは、Mathematicaが問題を引き起こす言語になることは知っていました。Polyhedrondata多面体を描画するための組み込み関数であることは明らかであるため、許可されていません。あなたの答えが多面体の描画にビルトインを使用せず、他のルールに準拠している場合、それは許容されます。あなたのポイントは、あなたが顔を正しく着色しなければならないという事実を与えられたとしてPolyhedrondataも、とにかくあなたをそれほど救わないだろうということであるように思われます。ある程度は同意しますが、投稿後にルールを変更しないようにした方が公平です。
Level River St

回答:


3

Python 2.7、949バイト

以下は、matplotlibを使用してプロットされた通常の12面体の解です。ここには示されていないコードの大まかな概要を以下に示します。

  • 頂点を作成エッジを作成(3つの最近傍、モジュールscipy.spatial.KDtreeに基づく)
  • 長さ5のグラフサイクルに基づいて面を作成(モジュールnetworkx)
  • 面法線を作成します(外向きの法線を持つものを選択します、numpy.cross)
  • 顔の法線に基づいて色を生成する
  • 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()

ここに画像の説明を入力してください


3

Ruby、784バイト* 0.5 * 0.7 = 274.4

私自身の回答なので、賞金の対象にはなりません。

3D以外のビルトインボーナスと描画のすべての星座ボーナスの両方が対象です。

->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}

関数パラメーターとして入力

通常の十二面体、小さな星形の十二面体、大きな星形の十二面体に対応する整数0..3

x、y、x(再び)軸を中心とした回転の角度に対応する3つの整数の配列(適切なオイラー角。これにより、あらゆる回転を実現できます。)

p.svgWebブラウザで表示できる ファイルを出力します。

説明

コードの下部の配列x、y、zには、小さな星形の12面体の1つの面の外側の点の座標が含まれています。これは、12の頂点が(+/- 377、+ /-233、+ /-0)の巡回置換によって定義される二十面体に刻まれています。377と233は連続したフィボナッチ数なので、377/233は黄金比の優れた近似値であることに注意してください。

追加の配列wには、-1を乗算したx座標が含まれ、x平面での反射と同等です。関数fは、色ごとに1回ずつ、6回呼び出されます。x、y、zとw、y、zの巡回置換は異なります。

3つの回転は、n []のパラメーターとして渡されます。Rubyでsinとcosを使用するには、を実行する必要がありますinclude Math。これを回避するために、角度のコサインとサインは、-1の平方根"i"を(角度の度数/ 90)で累乗することによって取得されます。この数値の実数部と虚数部は、k(コサイン)とl(正弦)

回転の前に、xとyの値が交換されます。次に、行列の乗算がyとzの値に適用され、x軸を中心に回転します。値の交換により、3つの回転をループで実行できます。

これまでのところ、ポイントのリングは1つしかありません。残りを取得するには、五角形/星の中心を見つける必要があります。これは、p、q、rに格納されている5つの頂点の座標の平均を見つけることによって行われます。

前述のように、色ごとに1つの関数呼び出しのみが行われます。rの符号(z座標の平均、したがって面の座標)がテストされます。正の場合、顔は正面であるため表示されます。負の場合、その面は裏面です。それは見えず、反対側の面に対する関数呼び出しはありません。したがって、3つすべての座標を反転する必要があります。これを容易にするために、rの符号がeに格納されます。

面は5つの三角形で構成され、その頂点は小さな星形の12面体の外側の頂点と面の中心の線形結合です。小さな星形の十二面体の場合、三角形の先端に対して、a = 1とb = 0を設定します(x、y、zからの寄与1、p、q、rからの寄与0)。三角形の2つのベース頂点に対して、c = -0.382(x、y、zからの寄与1 /黄金比^ 2)およびd = 1.382(p、q、rからの寄与)を設定します。負の寄与の理由は、三角形のベース頂点は、面の反対側にある反対側の先端に関して定義されていること。得られた座標には、必要に応じてeを掛けます。

その値が割り当てられている4つの名前の配列a,b,c,d変数に応じて選択正十二面体、小星型十二面体、大十二面体と大星型十二面体、のために必要な値を含むtなお小星型十二面体と大十二面体、用+ B = C + d = 1。関係a + b = c + dは他の形状に適用されますが、異なるスケールが適用されます。

三角形ごとにsvgコードの行が作成されます。これには、三角形の3つの頂点のz座標の合計から得られたID、三角形の3つの座標の頂点の説明、および色が含まれます。正投影ではz軸を真下に見ていることに注意してください。したがって、2D x = 3D xおよび2D y = 3D yです。行が追加されますh.

最後に、すべての関数呼び出しが終了すると、hがソートされて、z値が最も高い(前の)三角形が最後にプロットされ、全体が適切なヘッダーとフッターのテキストを含むsvgファイルとして保存されます。

テストプログラムに含まれていない

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]

出力

小さな星形の十二面体の場合(すぐに他のポリゴンの画像がいくつか追加されます)

1,0,0,0ホームポジション

ここに画像の説明を入力してください

1,30,0,0は30度回転

ここに画像の説明を入力してください

1,0,30,0は右に30度回転します(注:完全な側面図の場合、回転はatan(1/golden ratio)= 31.7度になるため、まだ小さな青のスライバーが表示されます)。

ここに画像の説明を入力してください

1,0,20,0右に20度回転

ここに画像の説明を入力してください

1,60,10、-63を上下左右に回転(3回転でのみ可能な方向の例)

ここに画像の説明を入力してください

0、30、0、0正十二面体

ここに画像の説明を入力してください

2,0,20,0大十二面体

ここに画像の説明を入力してください

3,45,45,45大きな星形の十二面体 ここに画像の説明を入力してください


3

Mathematica、426424バイト

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]

組み込みを使用しGraphics3Dて形状を表示します。ただし、ほとんどのバイトは圧縮された頂点の場所Partitionによって使用されPolygonますが、それらはによって使用可能な形式に編集されます。最後に:

この形状はクリックしてドラッグすることで回転できることに注意してください。


OMG、正十二面体を削除しました!私が知る限り(Mathematicaを知らないか持っていません)、これはルールに準拠しているので+1します。
Level River St

@steveverrillサイズが大きく変わるとは思いませんが、最初から書き直す必要はありません。
LegionMammal978 2015

あなたの答えは有効のままです、私はルールを変更するつもりはありません、それは悪い形でしょう。ただし、3つの星状多面体に対する0.7のボーナスに加えて、4つの多面体のほとんどを生成できる答えに賞金を提供しました。あなたがあなたの答えを更新することを決定しなかった場合、私はあなたが(。質問の有益な情報のセクションを参照してください)アルゴリズムの座標を生成することによって、バイトの多くを救うかもしれない数える
レベル川セント

@steveverrillでは、頂点の位置に四次方程式の根が含まれるように見えますが、パターンを見つけることができません。
LegionMammal978 2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.