Coordenadas de saída dos vértices de um cubo. Em seguida, produza uma lista de doze triângulos que cobrirão o cubo, cada triângulo sendo uma lista de três índices de vértices, sempre orientados. A saída deve ser uma sequência ASCII de números decimais distintos. Este golfe não tem entrada. O vencedor é o menor número de caracteres, em que o conjunto de caracteres é Unicode.
Por exemplo, considere um cubo 1x1x1 encurralado em 0,0,0. Os oito vértices do cubo podem ser descritos pelas seguintes coordenadas xyz em uma grade cartesiana 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)
Cada vértice pode receber um índice: 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
Agora considere a face superior, vértices indexados de zero a três. Os dois triângulos de cobertura podem ser descritos por três índices cada:
[0,1,2] [2,3,0]
Aqui está uma foto dessa face superior, vista de cima do cubo:
3_____2
| /|
| / |
| / |
| / |
0_____1
E aqui está uma visão de um ângulo.
3____2
/ __-/|
0/_`__1 |
| | /6
|____|/
4 5
Observe que a orientação, ou "enrolamento", desses dois triângulos é "anti-horário" quando vista de "fora" do cubo, olhando diretamente para a face em questão (imagine visitar cada vértice conforme listado, no sentido anti-horário). Agora imagine isso feito para todos os seis lados do cubo.
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]
Você pode gerar qualquer tamanho de cubo localizado em qualquer coordenada. Você pode numerar e ordenar as coordenadas do vértice da maneira que desejar. Os índices podem ser baseados em 0 ou 1. A orientação do triângulo pode ser no sentido horário ou anti-horário quando vista de fora do cubo, desde que seja consistente para todos os triângulos.
A saída pode ser formatada como você desejar, desde que cada número decimal ASCII seja separado por pelo menos um caractere ASCII não numérico. Por exemplo, o exemplo acima também pode ser exibido da seguinte maneira:
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
Este golfe é inspirado em vários sistemas e formatos de gráficos 3D, incluindo OpenGL, OBJ, OFF, AMF, CGAL, etc. Este golfe é semelhante ao golfe dos Hobbies da Calvin chamado Output a Face on a Nube Cube , a grande diferença é que você precisa para gerar as coordenadas xyz dos vértices e os índices do triângulo. Obrigado pela leitura.
Por inspiração do usuário, aqui está um programa de validação "auxiliar" em python2 (não-golfista) que imprimirá 'ok' ou 'não ok' para dados de saída de teste nas variáveis vertstr e idxstr. Não funciona perfeitamente ... mas pode detectar alguns erros.
Editar: erro de digitação corrigido no exemplo e erros no código de validação.
#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' classe Vector: def __init __ (auto, 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 __ (auto, v): return Vector ([self.xv.x, self.yv.y, self.zv.z]) def __str __ (próprio): Retorno str (self.x) + ',' + str (self.y) + ',' + str (self.z) def cruz (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 enrolamento (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 retornar d def normais (v1, v2, v3): va = v2-v1 vb = v3-v2 vc = v1-v3 n1 = cruz (va, vb) n2 = cruz (vb, vc) n3 = cruz (vc, va) retornar [n1, n2, n3] def triplicar (str): nums, triplos = [], [] para num em str.split (''): nums + = [int (num)] para i no intervalo (0, len (nums), 3): triplos + = [[nums [i], nums [i + 1], nums [i + 2]]] retorno tripla verts = triplicar (vertstr) índices = triplicar (idxstr) nsum = Vetor ([0,0,0]) windsum = 0 xs, ys, zs = [], [], [] para v em verts: xs + = [v [0]] ys + = [v [1]] zs + = [v [2]] #print xs, ys, zs, len (xs) center = Vetor ([float (soma (xs)) / len (xs), float (soma (ys)) / len (ys), float (soma (zs)) / len (zs)]) para triângulo em índices: v1 = Vetor (verts [triângulo [0]]) v2 = Vetor (verts [triângulo [1]]) v3 = Vetor (verts [triângulo [2]]) normas = normais (v1, v2, v3) imprimir v1, v2, v3, normas [0], normas [1], normas [2] para n em normas: nsum + = n w = enrolamento (v1, v2, v3, centro) imprimir 'enrolamento', w se w <0: windsum- = 1 elif w> 0: windsum + = 1 if abs (windsum) == 12: imprime 'enrolamento ok' else: print 'enrolamento não está ok' if (nsum.x == 0 e nsum.y == 0 e nsum.z == 0): imprime 'soma normal ok' else: imprimir 'soma normal não está ok'