Bir küpün köşelerini ve kaplama üçgenlerini yazdırın


9

Bir küpün köşelerinin çıktı koordinatları. Daha sonra, küpü kaplayacak on iki üçgenden oluşan bir liste çıkın, her üçgen sürekli olarak yönlendirilmiş üç köşe indeksinin bir listesidir. Çıktı, farklı ondalık sayıdan oluşan bir ASCII dizesi olmalıdır. Bu golfün girişi yok. Kazanan, karakter kümesinin Unicode olduğu en az karakterdir.

Örneğin, 0,0,0 ile köşeli 1x1x1 küpü düşünün. Küpün sekiz köşesi, 3d Kartezyen ızgarada aşağıdaki xyz koordinatları ile açıklanabilir:

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)

Her tepe noktasına bir dizin verilebilir: 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

Şimdi üst yüzü düşünün, tepe noktaları sıfırdan üçe endekslendi. İki kaplama üçgeni her biri üç endeks ile tanımlanabilir:

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

İşte bu üst yüzün, küpün üstünden bakıldığında bir resmi:

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

Ve işte bir açıdan bakış açısı.

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

Bu üçgenin her ikisinin de oryantasyonuna veya 'sargısına' dikkat edin, doğrudan söz konusu yüze bakarak küpün 'dışından' bakıldığında (saat yönünün tersine gittiğini hayal edin). Şimdi bunun küpün altı tarafı için yapıldığını hayal edin.

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]

Herhangi bir koordinatta bulunan herhangi bir boyutta küp çıktısı alabilirsiniz. Tepe koordinatlarını istediğiniz gibi numaralandırabilir ve sipariş edebilirsiniz. Endeksler 0 tabanlı veya 1 tabanlı olabilir. Üçgenin yönü, tüm üçgenler için tutarlı olduğu sürece küpün dışından bakıldığında saat yönünde veya saat yönünün tersine olabilir.

Her ASCII ondalık sayısı en az bir sayısal olmayan ASCII karakteriyle ayrıldığı sürece çıktı istediğiniz şekilde biçimlendirilebilir. Örneğin, yukarıdaki örnek aşağıdaki gibi de çıkarılabilir:

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

Bu golf OpenGL, OBJ, KAPALI, AMF, CGAL vb Bu golf adlı Calvin'in Hobiler tarafından golf benzer dahil olmak üzere çeşitli 3d grafik sistemleri ve biçimleri esinlenerek bir Numaralı Cube üzerinde Yüz Çıktı , büyük fark İhtiyacınız olan köşelerin xyz koordinatlarını kendiniz ve üçgen indekslerini çıktılamak için. Okuduğunuz için teşekkürler.

Buradaki kullanıcı ilhamı, python2'de (golf dışı), vertstr ve idxstr değişkenlerindeki test çıktısı verileri için 'tamam' veya 'tamam değil' yazdıracak bir "yardımcı" doğrulama programıdır. Mükemmel çalışmıyor ... ama bazı hataları yakalayabilir.

Düzenleme: örnekte sabit yazım hatası ve doğrulama kodundaki hatalar.

    

#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'

sınıf vektörü:
    def __init __ (öz, v):
        self.x, self.y, self.z = T [0], T [1], T [2]
    def __add __ (öz, v):
        dönüş Vektörü ([self.x + vx, self.y + vy, self.z + vz])
    def __sub __ (öz, v):
        dönüş Vektörü ([self.xv.x, self.yv.y, self.zv.z])
    def __str __ (öz):
        dönüş str (self.x) + ',' + str (self.y) + ',' + str (self.z)

def çapraz (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
    Dönüş Vektörü ([x, y, z])

# http://mathforum.org/library/drmath/view/55343.html & http://sympy.org
def sargı (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önüş d

def normalleri (v1, v2, v3):
    va = v2-v1
    vb = v3-v2
    vc = v1-v3
    n1 = çapraz (va, vb)
    n2 = çapraz (vb, vc)
    n3 = çapraz (vc, va)
    dönüş [n1, n2, n3]


def triplify (str):
    nums, üç katına = [], []
    str.split ('') içindeki num için: nums + = [int (num)]
    (0, len (sayı), 3) aralığında i için:
        üçlü + = [[sayı [i], sayı [i + 1], sayı [i + 2]]]
    dönüş üçlü

verts = triplify (vertstr)
endeksler = üçlü artış (idxstr)
nsum = Vektör ([0,0,0])
windsum = 0
xs, ys, ZS = [], [], []
v cinsinden v için:
    xs + = [h [0]]
    ys + = [h [1]]
    zs + = [h [2]]
#print xs, ys, zs, len (xs)
merkez = Vektör ([şamandıra (toplamı (xs)) / len (xs), şamandıra (toplamı (ys)) / len (ys), şamandıra (toplamı (ZS)) / len (ZS)])
endekslerde üçgen için:
    v1 = Vektör (veriller [üçgen [0]])
    v2 = Vektör (veriller [üçgen [1]])
    v3 = Vektör (veriller [üçgen [2]])
    normlar = normaller (v1, v2, v3)
    baskı v1, v2, v3, normlar [0], normlar [1], normlar [2]
    normlardaki n için:
        nsum + = n
    w = sargı (v1, v2, v3, merkez)
    'sargı' yazdır, w
    w <0 ise: rüzgâr- = 1
    elif w> 0: rüzgar + 1
abs (windsum) == 12 ise: 'sargı tamam' yazdırın
aksi: 'sarma tamam değil' yazdırın
if (nsum.x == 0 ve nsum.y == 0 ve nsum.z == 0): 'normal toplam tamam' yazdır
aksi: 'normal toplam uygun değil' yazdır

1
Örneğe açıktır, ancak sadece onu açık bir şekilde ortaya koymak için, endekslerin 0 tabanlı olduğunu belirtmek isteyebilirsiniz. Örnek olarak listelediğiniz biçimlerden en az birinde (OBJ) 1 tabanlı dizin kullanıldığından, bu bir bilgi verilmez.
Reto Koradi

Bu da işe yarayacak. Bu zorlukla ilgili bir zorluk, çıktının doğruluğunu doğrulamanın orta derecede acı verici olduğunu düşünüyorum. Bir parça kağıda seçilen tepe noktası sırası ile bir küp çizmeniz ve 12 üçgenin tümünü manuel olarak doğrulamanız gerekir. Bir doğrulama programı yazabilirsiniz. Bu aslında başka bir meydan okuma fikri olabilir ... sanırım bundan daha zor.
Reto Koradi

bir validator için başka bir golf fikri gerçekten seviyorum. tam bir veri kümesi vermek için örneği güncelledim. Tekrar teşekkürler.
parlak don

ok Her üçgendeki her bir vektör çiftinin çapraz ürünlerini alan, hepsini ekleyen ve 0 'tamam' derse çok hızlı ve kirli bir doğrulama programı ekledim.
don parlak

Yanıtlar:


1

Pyth, 18 karakter

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

Haskell cevabımla aynı fikir; baskılar:

[
1
1
1
1
1
,

2
1
2
1
1
...

3 farklı dilde aynı unicode dizesini kullandığınızı seviyorum
don parlak

1
Bu unicode büyüsü nedir?
RK.

2

CJam, 35 bayt

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

Çevrimiçi deneyin

Çıktı:

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

Üçgen yönü dışarıdan saat yönündedir. Bunu manuel olarak kontrol ettim ve doğru görünüyor.

Açıklama:

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.

bu gerçekten havalı. . . simetri seviyorum ...
don parlak

Bu açıkça en eğlenceli cevap, ama ben statik açıklama ve "girdi" var benim sorun tanımını berbat, bu yüzden anlaşma tutmak ve aşağıda, (aynı zamanda eğlenceli bir cevap ama farklı bir şekilde), Yanıt onay işareti. katıldığınız için teşekkürler.
Parlak don

1

JavaScript (ES6) 78

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

Üzgünüm ama hiçbir girdi olmadan bu zorlukları gerçekten anlamıyorum.


üzgünüm, bu benim ilk golf sorumuydu. sanırım şimdi değiştirmek için çok geç ...
don parlak

Bir dahaki sefere daha iyi. Yine de benim oyum var.
edc65

1

Yakut, 98 106

Reto Koradi tarafından tespit edilen hata düzeltildi.

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(//)

Koordinatların gerekli olduğu göz önüne alındığında, mantıklı olan tek köşe numaralandırma şeması, her köşenin koordinatlarının ikili temsili olduğu gibi görünüyordu. Bu, çeşitli farklı numaralandırma şemalarının denendiği bağlantılı sorudan oldukça farklıdır. Sonunda, koordinatları kirli bir sabit kodla yazdırmaya karar verdim: ondalık temsili 342391 olan s24 bitlik sayı dizgesine başlatılır. 000001010011100101110111Aslında bu yazdırma koordinatları yöntemiyle, köşelerin numaralandırması esnek olabilir, başka bir cevap ver.

Küpün ekvatoru etrafında, 1,5,4,6,2,3 köşelerini buluyoruz ve bu listedeki ardışık 3 sayıdan her bir yüz için bir üçgen tanımlayabiliriz (sonunda başa dönerek). ) Her yüzdeki diğer üçgen, rakamları ters çevirerek ve orta rakamı uygun şekilde 0 veya 7 ile değiştirerek tanımlanır.

Bu, gerekli tüm çıktıları verir, ancak ayırıcı karakterler olmadan. Bunu başarmak için, sadece bir karakter dizisine dönüştürüyorum ve diziyi yazdırıyorum, bu şekilde (kaydırmayı önlemek için eklenen çizgi satırları):

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

Sargı düzeninin tutarlı olduğundan emin misiniz? Eskizime dayanarak 1, 5, 4, CCW, 5, 4, 6CW.
Reto Koradi

@RetoKoradi 8 baytlık bir maliyetle düzeltildi. Teşekkürler. Ayrıca, farklı bir numaralandırma şemasıyla daha iyisini yapabileceğimi fark ettim.
Level River St

1

Haskell, 38 karakter

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

Çok sayıda önemsiz öğe ile ayrılmış doğru sayıları yazdırır:

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

Küpün köşesi (1, 1, 1) ila (2, 2, 2) arasındadır.


1

CJam, 20 karakter

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

Haskell cevabımla aynı fikir; baskılar:

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-6Sihirli sayıyı 64 ile çarparak kurtuldum .

Koordinatların ataması aşağıdadır. 1001 numaraya atadığım garip . Eksenleri değiştirerek ve 0011 numaraya atayarak rev 0'da bir bayt kaydedebilirdim. her şeyi tersine çevirmek zorunda kaldı. Her neyse, şimdi yaptığım değişiklikle, yapılacak ek tasarruf yok, bu yüzden koordinatları oldukları gibi bırakacağım

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

Köşeleri seçmede esneklik sağlamak için koordinat verilerinin kodlamasını kullanmak Çıktıda 54 basamak vardır, yani saf çözeltinin kod için 63-54 = 9 bayt olması gerekir. 9 baytta boşluk eklemenin bir yolunu düşünemediğim için, bunun naif çözümden daha kısa olduğuna inanıyorum.

Numaralandırma şeması (Ruby cevabımdan bağlantılı soruya uyarlandı https://codegolf.stackexchange.com/a/48867/15599 )

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

Çıktı

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'nin yönteminin dahil edilmesini gerçekten seviyorum
don parlak

@donbright Ekvatordaki ilk 6 köşeyi ve son iki sorudaki kutuplara son 2 noktayı koymayı düşünen ilk kişiydim, bu yüzden C cevabım en popüler cevaptı. Sıralı sırayla 6 köşe vardı. Runer112, ekvatordaki 6 köşeyi yeniden sıralaması nedeniyle bir miktar krediyi hak ediyor. Bir önceki soruda Ruby için yüz sırasını değiştirmek zorunda kaldım, ancak köşe sırası gerçekten Runer112'ninkiyle aynı. Phinotphi'nin ekvatordaki 6 köşeyi alternatif olarak yeniden sıralaması bana bir önceki soruda eşit uzunluk verirdi, ancak bu konuda daha uzun olurdu
Level River St

vay be awesome ... ayrıntılı açıklama için teşekkürler ... çok ilginç. i daha iyi bir meydan okuma olurdu o zaman giriş izin.
Parlak don
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.