立方体の頂点とその三角形を印刷する


9

立方体の頂点の座標を出力します。次に、立方体をカバーする12個の三角形のリストを出力します。各三角形は、一貫して方向付けられた3つの頂点インデックスのリストです。出力は、異なる10進数のASCII文字列でなければなりません。このゴルフには入力がありません。勝者は最も少ない文字で、文字セットはUnicodeです。

例として、0,0,0の角にある1x1x1の立方体を考えます。立方体の8つの頂点は、3Dデカルトグリッド上の次のxyz座標で記述できます。

x y z = (0,0,1) (1,0,1) (1,1,1) (0,1,1) (0,0,0) (1,0,0) (1,1,0) (0,1,0)

各頂点にはインデックスを与えることができます: x y z->index: 0 0 1->0, 1 0 1->1, 1 1 1->2, 0 1 1->3, 0 0 0->4, 1 0 0->5, 1 1 0->6, 0 1 0->7

次に、上面を考慮します。頂点のインデックスは0〜3です。2つのカバーする三角形は、それぞれ3つのインデックスで表すことができます。

[0,1,2] [2,3,0]

キューブの上から見たこの上面の写真は次のとおりです。

 3_____2
 |    /| 
 |   / |                  
 |  /  |
 | /   |
 0_____1                

そして、これはある角度からの眺めです。

    3____2
   / __-/|
 0/_`__1 |
  |    | /6
  |____|/
 4     5

問題の面を直接見ている立方体の「外側」から見ると、これらの三角形の両方の向き、つまり「巻き」が「反時計回り」であることに注意してください(リストされているように各頂点にアクセスすると、反時計回りになります)。これが立方体の6辺すべてに対して行われたと想像してください。

vertices: (0,0,1) (1,0,1) (1,1,1) (0,1,1) (0,0,0) (1,0,0) (1,1,0) (0,1,0)
triangles as indices: [0,1,2], [2,3,0], [6,5,4], [4,7,6], 
  [5,2,1], [2,5,6], [0,3,4], [4,3,7], [2,6,3], [3,6,7], [0,4,1], [1,4,5]

任意の座標にある任意のサイズの立方体を出力できます。頂点座標には、必要に応じて番号を付けて順序を付けることができます。インデックスは0ベースまたは1ベースにすることができます。三角形の向きは、すべての三角形で一貫している限り、立方体の外側から見たときに時計回りまたは反時計回りのどちらでもかまいません。

各ASCII 10進数が少なくとも1つの非数値ASCII文字で区切られている限り、出力は任意にフォーマットできます。たとえば、上記の例は次のように出力することもできます。

0 0 1 1 0 1 1 1 1 0 1 1 0 0 0 1 0 0 1 1 0 0 1 0 
0 1 2 2 3 0 6 5 4 4 7 6 5 2 1 2 5 6 0 3 4 4 3 7 2 6 3 3 6 7 0 4 1 1 4 5

このゴルフは、OpenGL、OBJ、OFF、AMF、CGALなどのさまざまな3Dグラフィックスシステムおよびフォーマットに触発されています。このゴルフは、番号付きキューブの出力面という名前のCalvin's Hobbiesのゴルフに似ていますが、大きな違いは必要です。頂点のxyz座標を自分で出力し、三角形のインデックスを出力します。読んでくれてありがとう。

ここでのユーザーごとのインスピレーションは、変数vertstrおよびidxstrのテスト出力データに対して「ok」または「not ok」を出力するpython2(ゴルフではない)の「ヘルパー」検証プログラムです。それは完全に動作しません...しかし、いくつかのエラーをキャッチすることができます。

編集:例の誤植と検証コードのバグを修正しました。

    

#vertstr = '0 0 0 0 0 1 0 1 0 0 1 1 1 0 0 1 0 1 1 1 0 1 1 1'
#idxstr = '1 2 0 2 1 3 7 5 6 4 6 5 2 4 0 4 2 6 7 3 5 1 5 3 4 1 0 1 4 5 7 6 3 2 3 6'
vertstr = '0 0 1 1 0 1 1 1 1 0 1 1 0 0 0 1 0 0 1 1 0 0 1 0'
idxstr = '0 1 2 2 3 0 6 5 4 4 7 6 5 2 1 2 5 6 0 3 4 4 3 7 2 6 3 3 6 7 0 4 1 1 4 5'

クラスVector:
    def __init __(self、v):
        self.x、self.y、self.z = v [0]、v [1]、v [2]
    def __add __(self、v):
        return Vector([self.x + vx、self.y + vy、self.z + vz])
    def __sub __(self、v):
        return Vector([self.xv.x、self.yv.y、self.zv.z])
    def __str __(self):
        str(self.x)+ '、' + str(self.y)+ '、' + str(self.z)を返す

def cross(v1、v2):
    x = v1.y * v2.z-v2.y * v1.z
    z = v1.x * v2.y-v2.x * v1.y
    y = v1.z * v2.x-v2.z * v1.x
    ベクトル([x、y、z])を返す

#http://mathforum.org/library/drmath/view/55343.html&http://sympy.org
def巻線(v1、v2、v3、obs):
    x1、y1、z1、x2、y2、z2、x3、y3、z3、x4、y4、z4 = v1.x、v1.y、v1.z、v2.x、v2.y、v2.z、v3。 x、v3.y、v3.z、obs.x、obs.y、obs.z
    d = x1 *(y2 * z3-y2 * z4-y3 * z2 + y3 * z4 + y4 * z2-y4 * z3) 
    d = d + y1 *(-x2 * z3 + x2 * z4 + x3 * z2-x3 * z4-x4 * z2 + x4 * z3) 
    d = d + z1 *(x2 * y3-x2 * y4-x3 * y2 + x3 * y4 + x4 * y2-x4 * y3)
    d = d-x2 * y3 * z4 + x2 * y4 * z3 + x3 * y2 * z4-x3 * y4 * z2-x4 * y2 * z3 + x4 * y3 * z2 
    戻るd

def normals(v1、v2、v3):
    va = v2-v1
    vb = v3-v2
    vc = v1-v3
    n1 = cross(va、vb)
    n2 = cross(vb、vc)
    n3 = cross(vc、va)
    [n1、n2、n3]を返す


def triplify(str):
    nums、triples = []、[]
    str.split( '')のnumの場合:nums + = [int(num)]
    for i in range(0、len(nums)、3):
        トリプル+ = [[nums [i]、nums [i + 1]、nums [i + 2]]]
    トリプルを返す

verts = triplify(vertstr)
インデックス= triplify(idxstr)
nsum = Vector([0,0,0])
windsum = 0
xs、ys、zs = []、[]、[]
頂点のvの場合:
    xs + = [v [0]]
    ys + = [v [1]]
    zs + = [v [2]]
#print xs、ys、zs、len(xs)
center = Vector([float(sum(xs))/ len(xs)、float(sum(ys))/ len(ys)、float(sum(zs))/ len(zs)])
インデックスの三角形の場合:
    v1 = Vector(verts [triangle [0]])
    v2 = Vector(verts [triangle [1]])
    v3 = Vector(verts [triangle [2]])
    ノルム=法線(v1、v2、v3)
    v1、v2、v3、norms [0]、norms [1]、norms [2]を出力します
    ノルムのnの場合:
        nsum + = n
    w =巻線(v1、v2、v3、センター)
    'winding'、wを印刷
    w <0の場合:windsum- = 1
    elif w> 0:windsum + = 1
if abs(windsum)== 12:print 'winding ok'
else: 'winding not ok'を出力する
if(nsum.x == 0 and nsum.y == 0 and nsum.z == 0): 'normal sum ok'を出力する
else:「通常の合計は大丈夫ではない」を出力する

1
例からは明らかですが、完全に明確にするために、インデックスは0ベースであることを言及する必要があります。例としてリストするフォーマット(OBJ)の少なくとも1つは1ベースのインデックスを使用するため、これは規定ではありません。
Reto Koradi 2015年

それも機能します。この課題の難点の1つは、出力の正確さを確認するのが適度に辛いことです。ほとんどの場合、選択した頂点の順序でキューブを紙にスケッチし、12個の三角形すべてを手動で検証する必要があります。まあ、あなたは検証プログラムを書くことができます。それは実際には別の挑戦的なアイデアかもしれません...これよりも難しいと思います。
Reto Koradi 2015年

私はバリデーターのための別のゴルフのアイデアが本当に好きです。完全なデータセットを提供するように例を更新しました。再度、感謝します。
明るく

わかりました私は、各三角形のベクトルの各ペアのクロス積を取り、それらをすべて追加し、0が「ok」と言っている場合、非常に迅速でダーティな検証プログラムを追加しました。
明るく

回答:


1

Pyth、18文字

j`CM"⭧勛囃勦⾽仵ᶌﻘꚱ쥎➡˻ì

私のHaskellの回答と同じ考え。プリント:

[
1
1
1
1
1
,

2
1
2
1
1
...

私はあなたが3つの異なる言語で同じUnicode文字列を使用することを愛して
明るいドン

1
このユニコードの魔法は何ですか?
RK。

2

CJam、35バイト

YZm*`3{[XY4]m<)\0+_:+1$f-+_@f+W%}%`

オンラインでお試しください

出力は次のとおりです。

[[0 0 0] [0 0 1] [0 1 0] [0 1 1] [1 0 0] [1 0 1] [1 1 0] [1 1 1]] [[1 2 0 2 1 3 ] [7 5 6 4 6 5] [2 4 0 4 2 6] [7 3 5 1 5 3] [4 1 0 1 4 5] [7 6 3 2 3 6]]

三角形の向きは、外側から時計回りです。私はこれを手動で確認しましたが、私には正しいように見えます。

説明:

YZ      Push 2 and 3 on stack.
m*      Cartesian power, creates the coordinates of the 8 vertices.
`       Convert to string for output. Done with vertices.
3{      Start loop over 3 coordinate directions.
  [XY4]   Push [1 2 4], which are the vertex index offsets for the 3 directions.
  m<      Rotate by loop counter. So the remaining loop body will be executed once
          with [1 2 4], once with [2 4 1], once with [4 1 2].
  )       Pop off last offset. Will use this as index offset between the two
          parallel faces.
  \       Swap pair of remaining two offsets to top. These are the index offsets
          within the face.
  0+      Add a 0 to the list. These 3 indices define the first triangle.
  _:+     Calculate the sum. This is the vertex index of the opposite corner.
  1$      Copy first triangle to the top.
  f-      Subtract all indices from the index of the opposite corner, producing
          the second triangle of the face.
  +       Concatenate the indices of the two triangles, resulting in a list with
          the 6 vertex indices for the face.
  _       Copy the list.
  @       Bring the offset between the two faces to the top.
  f+      Add the offset to each index in the copied list.
  W%      Revert the order, resulting in the properly oriented list of the 6 vertex
          indices for the parallel face.
}%      End of loop over 3 coordinate directions.
`       Convert to string for output. Done with triangles.

これは本当にクールです。。。対称性を愛する...
明るい明るい

これは明らかに最も楽しい答えですが、問題の定義をめちゃくちゃにして静的な説明と「入力なし」にしたので、同意を維持し、以下の最小の文字数を与えなければなりません(これも楽しい答えですが、別の方法)、回答チェックマーク。参加してくれてありがとう。
明るい

1

JavaScript(ES6)78

alert([...'1010011100101110111:120213756465240426735153410145763236'].join` `)

申し訳ありませんが、私はこれらの課題を入力なしでは理解できません。


すみません、それは私の最初のゴルフの質問でした。私は...それは今それを変更するには遅すぎると思い
明るいドン

次回はもっと良いです。とにかく私の投票があります。
edc65

1

ルビー、98 106

Reto Koradiが発見したエラーを修正しました。

s=sprintf'%024b',342391
6.times{|i|t='15462315'[i,3];t+=t.reverse;t[1+i%2*3]='07'[i%2];s+=t}
p s.split(//)

座標が必要であることを考えると、各コーナーがその座標のバイナリ表現である場合に、意味のある唯一のコーナーの番号付けスキームが考えられました。これは、さまざまな番号付け方式が試行されたリンクされた質問とはかなり異なります。最後に、ダーティなハードコードで座標を印刷することにしました。これは、10進表現が342391 sである24ビットの数値の文字列バージョンに初期化されます。000001010011100101110111別の答えをしてください。

立方体の赤道を回ると、頂点1、5、4、6、2、3が見つかり、このリストの3つの連続する数値から各面に1つの三角形を定義できます(最後の最初に折り返します)。 )各面のもう1つの三角形は、数字を逆にし、中央の数字を0または7に適宜置き換えて定義します。

これにより、必要なすべての出力が得られますが、分離文字はありません。これを実現するには、次のように文字の配列に変換して出力するだけです(スクロールを防ぐために改行を挿入します)。

["0", "0", "0", "0", "0", "1", "0", "1", "0", "0", "1", "1", "1", "0", "0",
 "1", "0", "1", "1", "1", "0", "1", "1", "1", "1", "0", "4", "4", "5", "1",
 "5", "4", "6", "6", "7", "5", "4", "0", "2", "2", "6", "4", "6", "2", "3",
 "3", "7", "6", "2", "0", "1", "1", "3", "2", "3", "1", "5", "5", "7", "3"]

巻き順は一貫していますか?私のスケッチに基づいて、1, 5, 4CCW、5, 4, 6CWです。
Reto Koradi 2015年

@RetoKoradiは8バイトのコストで修正されました。ありがとう。また、別の番号付け方式を使用した方がよい場合があることに気付きました。
Level River St

1

Haskell、38文字

f=mapM(mapM print.show)"⭧勛囃勦⾽仵ᶌﻘꚱ쥎➡˻ì"

大量のジャンクで区切られた適切な数値を出力します。

'\''
'\\'
'1'
'1'
'1'
'1'
'1'
'\''
'\''
'\\'
'2'
'1'
'2'
'1'
'1'
...

立方体の対角は(1、1、1)から(2、2、2)です。


1

CJam、20文字

"⭧勛囃勦⾽仵ᶌﻘꚱ쥎➡˻ì":isS*

私のHaskellの回答と同じ考え。プリント:

1 1 1 1 1 2 1 2 1 1 2 2 2 1 1 2 1 2 2 2 1 2 2 2 1 2 0 2 1 3 7 5 6 4 6 5 2 4 0 4 2 6 7 3 5 1 5 3 4 1 0 1 4 5 7 6 3 2 3 6

1

Ruby、Rev 1 62

29.downto(0){|c|p c>5?73888640>>c&1:[c,c^1,c|6,c|6,(c+3)%6,c]}

c-6マジックナンバーに64を掛けて、を取り除きました。

座標の割り当ては以下のとおりです。奇数100番号1 に割り当てたのは奇妙です。軸を交換し001て番号1に割り当てることで、rev 0に1バイトを保存することができたでしょう。マジックストリングのすべてを逆に配置する必要がありました。とにかく、今行った変更で、追加の保存は必要ないので、座標はそのままにしておきます

Cube rotated with 0163 face at back
Top layer from above
01   000 100
74   010 110    
Bottom layer from above
36   001 101   
25   011 111

Ruby、Rev 0 63

29.downto(0){|c|p c>5?1154510>>c-6&1:[c,c^1,c|6,c|6,(c+3)%6,c]}

座標データのハードコーディングを使用して、コーナーを選択する際の柔軟性を提供します。出力には54桁あります。つまり、単純な解決策では、コードに63-54 = 9バイトを使用できます。9バイトでスペースを挿入する方法を考えることができないので、これは単純な解決策よりも短いと思います。

番号付けスキーム(リンクされた質問https://codegolf.stackexchange.com/a/48867/15599への私のRubyの回答から適応)

4---7
|  /|
| / |
|/  |
1---0---7
|  /|  /|
| / | / |
|/  |/  |
6---3---2---7
    |  /|  /|
    | / | / |
    |/  |/  |
    6---5---4
        |  /|
        | / |
        |/  |
        6---1

出力

0
0
0
1
0
0
0
1
1
0
0
1
1
1
0
1
1
1
0
0
1
1
1
0
[5, 4, 7, 7, 2, 5]
[4, 5, 6, 6, 1, 4]
[3, 2, 7, 7, 0, 3]
[2, 3, 6, 6, 5, 2]
[1, 0, 7, 7, 4, 1]
[0, 1, 6, 6, 3, 0]

私は@ Runer112のメソッドの組み込みが本当に好きです
明るく

@donbright最初の6つの頂点を赤道に置き、最後の2つの頂点を前の質問の極に置くことを最初に考えたので、C回答が最も人気があります。私は6つの頂点を順番に並べました。Runer112は、赤道上の6つの頂点の並べ替えにある程度の価値があります。前の質問でRubyの面の順序を変更する必要がありましたが、頂点の順序は実際にはRuner112の順序と同じです。赤道上の6つの頂点のPhinotphiの代替の並べ替えは、前の質問では同じ長さを私に与えたでしょうが、この質問ではより長くなります
Level River St

うわーすごい...詳細な説明ありがとう...とても興味深い 私は入力を許可するべきでしたが、それはより良い挑戦だったでしょう。
2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.