Cetak simpul kubus dan segitiga penutupnya

9

Koordinat keluaran dari simpul kubus. Kemudian, buatlah daftar dua belas segitiga yang akan menutupi kubus, setiap segitiga menjadi daftar tiga indeks-simpul, yang berorientasi secara konsisten. Output harus berupa string ASCII dengan angka desimal yang berbeda. Golf ini tidak memiliki input. Pemenang adalah karakter paling sedikit, di mana set karakter adalah Unicode.

Sebagai contoh, pertimbangkan kubus 1x1x1 terpojok pada 0,0,0. Delapan simpul kubus dapat dijelaskan oleh koordinat xyz berikut pada kisi Cartesian 3d:

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)

Setiap simpul dapat diberi indeks: 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

Sekarang perhatikan wajah teratas, verteks diindeks nol ke tiga. Dua segitiga penutup dapat dijelaskan oleh tiga indeks masing-masing:

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

Ini adalah gambar wajah atas ini, dilihat dari atas kubus:

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

Dan ini adalah pemandangan dari sudut pandang.

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

Perhatikan orientasi, atau 'belitan', dari kedua segitiga ini adalah 'berlawanan arah jarum jam' bila dilihat dari 'luar' kubus yang langsung melihat wajah yang dipermasalahkan (bayangkan mengunjungi setiap simpul sebagaimana tercantum, ia berlawanan arah jarum jam). Sekarang bayangkan ini dilakukan untuk semua enam sisi kubus.

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]

Anda dapat menampilkan berbagai ukuran kubus yang terletak di koordinat apa pun. Anda dapat memberi nomor dan memesan koordinat titik sesuai keinginan Anda. Indeks dapat berbasis 0 atau berbasis 1. Orientasi segitiga bisa searah jarum jam atau berlawanan arah jarum jam jika dilihat dari luar kubus selama itu konsisten untuk semua segitiga.

Output dapat diformat sesuai keinginan Anda, selama setiap angka desimal ASCII dipisahkan oleh setidaknya satu karakter ASCII non-numerik. Sebagai contoh, contoh di atas juga bisa berupa output sebagai berikut:

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

Golf ini terinspirasi oleh berbagai sistem dan format grafik 3d, termasuk OpenGL, OBJ, OFF, AMF, CGAL, dll. Golf ini mirip dengan golf oleh Hobi Calvin bernama Output a Face on a Numbered Cube , perbedaan besar yang Anda butuhkan untuk menghasilkan koordinat xyz dari simpul sendiri dan indeks output segitiga. Terima kasih sudah membaca.

Per inspirasi pengguna di sini adalah program validasi "pembantu" dalam python2 (non-golfy) yang akan mencetak 'ok' atau 'tidak ok' untuk data keluaran uji dalam variabel vertstr dan idxstr. Itu tidak berfungsi dengan baik ... tetapi dapat menangkap beberapa kesalahan.

Edit: contoh kesalahan tetap dan bug dalam kode validasi.

    

#vertstr = '0 0 0 0 0 1 0 1 0 0 1 1 1 0 0 1 0 1 1 0 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'

vektor kelas:
    def __init __ (mandiri, 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 __ (mandiri, v):
        return Vector ([self.xv.x, self.yv.y, self.zv.z])
    def __str __ (mandiri):
        return str (self.x) + ',' + str (self.y) + ',' + str (self.z)

lintas silang (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
    return Vector ([x, y, z])

# http://mathforum.org/library/drmath/view/55343.html & http://sympy.org
def berliku (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 
    kembali d

normals def (v1, v2, v3):
    va = v2-v1
    vb = v3-v2
    vc = v1-v3
    n1 = silang (va, vb)
    n2 = silang (vb, vc)
    n3 = silang (vc, va)
    return [n1, n2, n3]


def triplify (str):
    nums, tiga kali lipat = [], []
    untuk num di str.split (''): nums + = [int (num)]
    untuk saya dalam kisaran (0, len (nums), 3):
        tiga kali lipat + = [[num [i], num [i + 1], num [i + 2]]]
    tiga kali lipat kembali

verts = triplify (vertstr)
indeks = triplify (idxstr)
nsum = Vektor ([0,0,0])
windsum = 0
xs, ys, zs = [], [], []
untuk v in verts:
    xs + = [v [0]]
    ys + = [v [1]]
    zs + = [v [2]]
# print xs, ys, zs, len (xs)
center = Vektor ([float (jumlah (xs)) / len (xs), float (jumlah (ys)) / len (ys), float (jumlah (zs)) / len (zs)])
untuk segitiga dalam indeks:
    v1 = Vektor (verts [segitiga [0]])
    v2 = Vektor (verts [segitiga [1]])
    v3 = Vektor (verts [segitiga [2]])
    norma = normal (v1, v2, v3)
    cetak v1, v2, v3, norma [0], norma [1], norma [2]
    untuk n dalam norma:
        nsum + = n
    w = belitan (v1, v2, v3, tengah)
    cetak 'berliku', w
    jika w <0: windsum- = 1
    elif w> 0: windsum + = 1
if abs (windsum) == 12: print 'winding ok'
lain: cetak 'berliku tidak ok'
if (nsum.x == 0 dan nsum.y == 0 dan nsum.z == 0): cetak 'jumlah normal ok'
lain: cetak 'jumlah normal bukan ok'
jangan cerah
sumber
1
Jelas dari contoh, tetapi hanya untuk membuatnya sangat jelas, Anda mungkin ingin menyebutkan bahwa indeks berbasis 0. Ini bukan diberikan, karena setidaknya salah satu format yang Anda sebutkan sebagai contoh (OBJ) menggunakan indeks berbasis 1.
Reto Koradi
Itu akan bekerja juga. Saya pikir satu kesulitan dengan tantangan ini adalah cukup menyakitkan untuk memverifikasi kebenaran output. Anda cukup harus membuat sketsa kubus dengan urutan simpul pilihan pada selembar kertas, dan secara manual memvalidasi semua 12 segitiga. Nah, Anda bisa menulis program validasi. Itu mungkin sebenarnya ide tantangan lain ... lebih sulit daripada yang ini, saya pikir.
Reto Koradi
Saya sangat suka ide golf lain untuk validator. Saya memperbarui contoh untuk memberikan dataset lengkap. Terima kasih lagi.
don bright
ok saya menambahkan program validasi sangat cepat dan kotor yang mengambil produk silang dari setiap pasangan vektor di setiap segitiga, menambahkan semuanya, dan jika 0 mengatakan 'ok'.
don bright

Jawaban:

1

Pyth, 18 karakter

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

Ide yang sama dengan jawaban Haskell saya; cetakan:

[
1
1
1
1
1
,

2
1
2
1
1
...
Lynn
sumber
Saya suka bahwa Anda menggunakan string unicode yang sama dalam 3 bahasa yang berbeda
don bright
1
Apa sihir unicode ini?
RK.
2

CJam, 35 byte

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

Cobalah online

Outputnya adalah:

[[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]]

Orientasi segitiga searah jarum jam dari luar. Saya memeriksa ini secara manual, dan itu terlihat benar bagi saya.

Penjelasan:

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.
Reto Koradi
sumber
ini sangat keren. . . cinta simetri ...
jangan cerah
ini jelas jawaban yang paling menyenangkan, tetapi saya mengacaukan definisi masalah saya untuk memiliki deskripsi statis dan "tidak ada input", jadi saya harus menjaga perjanjian dan memberi penghargaan jumlah karakter terendah, di bawah ini (yang juga merupakan jawaban yang menyenangkan tetapi dalam dengan cara yang berbeda), tanda centang Jawab. terima kasih telah berpartisipasi.
don bright
1

JavaScript (ES6) 78

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

Maaf tapi saya benar-benar tidak mengerti tantangan ini tanpa masukan.

edc65
sumber
maaf, itu pertanyaan golf pertama saya. kurasa sudah terlambat untuk mengubahnya sekarang ...
jangan terang
Lebih baik lain kali. Anda tetap memilih saya.
edc65
1

Ruby, 98 106

Memperbaiki kesalahan yang dilihat oleh 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(//)

Mengingat bahwa koordinat diperlukan, satu-satunya skema penomoran sudut yang masuk akal tampaknya adalah di mana setiap sudut adalah representasi biner dari koordinatnya. Itu sangat berbeda dari pertanyaan terkait, di mana berbagai skema penomoran yang berbeda dicoba. Pada akhirnya saya memutuskan untuk mencetak koordinat dengan hardcode kotor: sdiinisialisasi ke versi string nomor 24-bit 000001010011100101110111yang representasi desimalnya adalah 342391. Sebenarnya dengan metode pencetakan koordinat ini, penomoran simpul fleksibel, jadi saya dapat lakukan jawaban lain.

Mengitari garis khatulistiwa, kita menemukan simpul 1,5,4,6,2,3 dan kita dapat mendefinisikan satu segitiga untuk setiap wajah dari 3 angka berurutan dalam daftar ini (membungkus kembali ke awal di akhir. ) Segitiga lainnya pada setiap wajah ditentukan dengan membalikkan digit, dan mengganti digit tengah dengan 0 atau 7 yang sesuai.

Ini memberikan semua output yang diperlukan, tetapi tanpa karakter pemisah. Untuk mencapai itu, saya cukup mengkonversi ke array karakter dan mencetak array, seperti ini (linebreak dimasukkan untuk mencegah pengguliran):

["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"]
Level River St
sumber
Apakah Anda yakin bahwa urutan belitan konsisten? Berdasarkan sketsa saya, 1, 5, 4adalah CCW, 5, 4, 6adalah CW.
Reto Koradi
@RetoKoradi diperbaiki dengan biaya 8 byte. Terima kasih. Juga, saya menyadari bahwa saya dapat melakukan yang lebih baik dengan skema penomoran yang berbeda.
Level River St
1

Haskell, 38 karakter

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

Mencetak angka yang tepat, dipisahkan oleh banyak sampah:

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

Diagonal kubus adalah dari (1, 1, 1) hingga (2, 2, 2).

Lynn
sumber
1

CJam, 20 karakter

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

Ide yang sama dengan jawaban Haskell saya; cetakan:

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
Lynn
sumber
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]}

Singkirkan c-6dengan mengalikan angka ajaib dengan 64.

Penugasan koordinat di bawah ini. Sungguh aneh bahwa saya ditugaskan 100ke nomor 1. Saya bisa menyimpan byte di rev 0 dengan menukar sumbu dan menugaskan 001ke nomor 1. Alasannya seperti itu adalah karena awalnya saya sudah menghitung dalam loop, yang berarti saya harus meletakkan semuanya terbalik di string sihir. Ngomong-ngomong, dengan perubahan yang saya buat sekarang, tidak ada penghematan tambahan yang harus dilakukan, jadi saya akan membiarkan koordinat seperti apa adanya

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

Menggunakan hardcoding data koordinat untuk memberikan fleksibilitas dalam memilih sudut. Ada 54 digit dalam output, yang berarti bahwa solusi naif akan memiliki 63-54 = 9 byte yang tersedia untuk kode. Karena saya tidak bisa memikirkan cara untuk memasukkan spasi dalam 9 byte, saya percaya ini lebih pendek dari solusi naif.

Skema penomoran (diadaptasi dari jawaban Ruby saya ke pertanyaan yang ditautkan https://codegolf.stackexchange.com/a/48867/15599 )

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

Keluaran

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]
Level River St
sumber
Saya sangat suka penggabungan metode @ Runer112
don bright
@donbright Saya adalah orang pertama yang berpikir untuk menempatkan 6 simpul pertama di garis khatulistiwa dan 2 terakhir pada kutub dalam pertanyaan sebelumnya, itulah mengapa jawaban C saya adalah jawaban yang paling populer. Saya memiliki 6 simpul secara berurutan. Runer112 layak mendapatkan kredit untuk pemesanan ulang 6 simpul di khatulistiwa. Saya harus mengubah urutan wajah untuk Ruby pada pertanyaan sebelumnya, tetapi urutan simpul memang identik dengan Runer112. Penataan ulang alternatif Phinotphi dari 6 simpul di khatulistiwa akan memberi saya panjang yang sama pada pertanyaan sebelumnya, tetapi akan lebih panjang untuk yang satu ini
Level River St
wow hebat ... terima kasih untuk penjelasan terperinci ... sangat menarik. saya seharusnya mengizinkan input maka itu akan menjadi tantangan yang lebih baik.
don bright