Introdução
Um hipercubo / tesserato é o equivalente em 4 dimensões de um cubo normal. É feito pegando uma rede de cubos, estendendo-a para a 3ª dimensão e depois - usando a 4ª dimensão - dobrando-a em um hipercubo. É basicamente um cubo, onde cada lado é um cubo.
Para criar um hipercubo, você precisa de 16 vetores 4d (um vetor com um x
, a y
, a z
e um w
componente). Esses vetores são os seguintes:
A(0, 0, 0, 0); B(1, 0, 0, 0); C(1, 0, 1, 0); D(0, 0, 1, 0); E(0, 1, 0, 0); F(1, 1, 0, 0); G(1, 1, 1, 0); H(0, 1, 1, 0);
I(0, 0, 0, 1); J(1, 0, 0, 1); K(1, 0, 1, 1); L(0, 0, 1, 1); M(0, 1, 0, 1); N(1, 1, 0, 1); O(1, 1, 1, 1); P(0, 1, 1, 1);
O hipercubo tem 24 faces. A lista a seguir contém todos eles (cada grupo marca um quad):
ABFE, CDHG, BCGF, DAEH, DCBA, FEHG
IJNM, KLPO, JKON, LIMP, LKJI, PMNO
ABJI, DCKL, BCKJ, DAIL, FEMN, GHPO, FGON, EHPM, EAIM, BFNJ, CGOK, HDLP
Com todas essas informações, você tecnicamente tem um hipercubo no código. Para girar isso, você precisa de 6 matrizes diferentes para cada plano de rotação, uma para os planos YZ, XZ, XY, XW, YW e ZW. Depois de ter todas as matrizes, você precisa multiplicar os vértices do cubo com eles.
As seguintes imagens mostram a estrutura de cada matriz:
Para a rotação no plano YZ:
Para a rotação no plano XZ:
Para a rotação no plano XY:
Para a rotação no plano XW:
Para a rotação no plano YW:
Para a rotação no plano ZW:
As rotações são aplicadas nesta ordem.
Depois de tudo isso, você tem um hipercubo girado. Agora você precisa desenhá-lo. Você deve usar uma projeção ortogonal combinada com uma projeção em perspectiva para enviar (x, y, z, w)
para (2x/(2+z), 2y/(2+z))
.
Entrada
Sua entrada é de 6 números inteiros entre 0 (inclusive) e 360 (exclusivamente). Eles representam as rotações em graus nos diferentes planos de rotação do hipercubo.
Saída
Sua saída deve ser uma única imagem contendo o hipercubo. A tela pode ser uma imagem rasterizada, uma imagem vetorial ou uma arte ASCII. A imagem de saída deve ter pelo menos 100 * 100 pixels e o cubo precisa ocupar pelo menos 50% da tela. Qualquer formato de saída de imagem padrão é permitido.
Casos de teste
0 0 0 0 0 0
0 0 0 0 0 30
30 0 0 0 0 30
0 0 0 30 30 30
45 45 45 0 0 0
45 45 45 45 45 45
Abra as imagens em uma nova guia, para vê-las em tamanho real.
Regras
- Aplicam-se regras padrão
- As brechas padrão são proibidas
- O menor código em bytes ganha
fonte
Respostas:
Oitava,
474433429 bytesRodado:
As matrizes de rotação ainda consomem muitos bytes, mas o ciclo euleriano funcionou muito bem, reduzindo o número de vértices visitados de
96120 para 33.Os vértices são gerados considerando a representação binária de 4 bits
[0:15]
e considerando o msb como coordenada x e o lsb como coordenada w.Edit: A pré-multiplicação de todas as matrizes de rotação foi um pesadelo, razão pela qual eu não a usei inicialmente, mas a pré-multiplicação em pares salvou 41 bytes.
Agora, procure a combinação ideal. :)Multiplicar as matrizes por três foi pior do que nenhuma pré-multiplicação, por isso ficarei feliz com a abordagem em pares.Saída:
fonte
Postscript
1075732683640631601590545542526514478470Usa mat.ps e G .
Edit: -343 Geração aplicada de codificação binária de vetores e circuito euleriano
roubadoemprestado de outras respostas. E aplicou strings binárias de tokens da biblioteca G.Editar: -49 Redefinidos
sin
cos
eneg
com nomes mais curtos.Edit: -43 Nomes abreviados definidos para sequências
0 0
0 1
1 0
.Edit: -9
al
(ie.aload
) É menor que(")@
. O fator 3 chama paraidi
(ie.idiv
) Ao custo de um não fazer nada1 idiv
.Edit: -30 Bloco de definição implícita aplicado de G.
Edit: -10 Mais algumas sequências triplamente usadas.
Edit: -45 Remova variáveis
i
j
k
l
m
n
para os ângulos e sempre defina o ângulo atual, pois ast
funções dos ângulos usam o valor de (global)t
variável. Adie a execução da descrição de código da matriz de rotação até que seut
valor esteja pronto.Edit: -3 Remover
<16>$
ie.closepath
. E um espaço.Edit: -16 Suportes de matriz de fator fora dos vetores unitários nas matrizes de rotação (
J
K
L
eM
). Reaplicar retiradomo
paramod
esu
parasub
.Edit: -12 In-line a função project-and-draw e remova (agora vazio) o dicionário anexo.
Edit: -36 Codificou o circuito (isto é, as faces ) em uma string.
Edit: -8 Remova a definição da matriz de vértices
V
. Em vez disso, deixe na pilha edup
cópias de trabalho conforme necessário (uma vez, no início e novamente no final do loop). Além disso, traduzimos alguns operadores de seqüências binárias de token de volta para nomes abreviados nos quais o BTS não deu economia, o mesmo(I)$
acontece agorafora
(ie.forall
).if du
poderia ser(T8)$
, masif du
é claramente uma escolha melhor (é golfe , não ofuscação por si só). Além disso, execute oscale
antestranslate
, para que as coordenadas traduzidas possam ser3
e em4
vez de300
e400
.A
3
4
e100
na primeira linha do segundo bloco são parâmetros que representam o centro-x, y e centro-escala, respectivamente, do desenho na página (coordenadas do centro são dimensionadas emscale
). (300.400) é aproximadamente o centro do papel tamanho carta dos EUA (612.792) em unidades PS.Se você pode seguir aproximadamente o postscript, as coisas bizarras importantes são o bloco de procedimento implícito e as seqüências de caracteres codificadas do operador. Conforme mostrado pelos comentários no arquivo de trabalho, abaixo, cada linha do primeiro bloco é implicitamente nomeada por A, B, C, etc. Então, por exemplo.
F E D
produziria1 0 0 1 0 0
. Para as cadeias de operadores codificadas, qualquer coisa que seja um argumento$
#
ou@
uma sequência de chamadas do operador, usando os bytes para selecionar operadores da tabela de nomes do sistema, PLRM 3ed Apêndice F. Esses recursos e mais estão disponíveis para PostScript na biblioteca G ( agora também inclui as funções mat.ps).Arquivo de trabalho:
Ungolfed e levemente comentou:
Algumas das minhas saídas são imagens espelhadas dos exemplos da pergunta.
Pois
gs -- hc.ps 0 0 0 0 0 0
eu recebo:gs -- hc.ps 0 0 0 0 0 30
gs -- hc.ps 30 0 0 0 0 30
gs -- hc.ps 0 0 0 30 30 30
gs -- hc.ps 45 45 45 0 0 0
gs -- hc.ps 45 45 45 45 45 45
Animação bônus que acabei de criar com este programa. Esta imagem corresponde à sequência de rotação 0 30 60 0 i i , onde i varia de 0 a 360 por 2.
fonte
C # + Unidade,
1060845835 bytesC # ≈ Java
Supõe que esta função esteja em um script colocado em
MainCamera
.Edit:
Obrigado a @TuukkaX pelas sugestões para salvar 19 bytes salvos ~ 200 bytes usando o ciclo euleriano.
Golfe:
Novas linhas + recuo + shell completo:
Não consegui descobrir uma fórmula simples para construir as matrizes de rotação nem as "faces" que desenhar, de modo que custam muitos bytes para codificar.Peguei emprestado o ciclo euleriano da @beaker. Além disso, os integrados do Unity são extremamente detalhados.Você pode verificar todos os casos de teste online .
fonte
0.5f
pode ser reduzido para.5f
e0.01f
para.01f
. Eu também acho que as matrizes inteiras podem ser separadas por vírgula em vez de dizerint[]
várias vezes.int[,]
. Ainda assim, obrigada.Vector4(0.5f,0.5f,0.5f,0.5f)
que pode ser reduzido aVector4(.5f,.5f,.5f,.5f)
.Javascript ES6, 584 bytes
"Ungolfed":
Veja em ação (modificado para girar continuamente):
A função retorna um objeto de tela HTML5, é necessário adicioná-lo à página, por
document.body.appendChild(f(0,0,0,0,0,0))
exemplo.Atualmente, as rotações são aplicadas fora de ordem, estou trabalhando na reordenação, mas, como é, gira um hipercubo corretamente.
fonte
Mathematica,
453415 bytes *Encurtado usando o tour euleriano e limpando tudo em uma única instrução sem definir funções nas variáveis. Isso torna o código mais lento por algum motivo. Suponho que o Mathematica reavalia as funções várias vezes agora que não estão armazenadas em uma variável.
* Estou contando
°
e==
como bytes únicos cada, pois são representados como um único caractere no Mathematica. Eu acho que isso é justo, pois muitas línguas usam codificações de caracteres estranhas.Ungolfed com comentários. A entrada é codificada no topo como
a={30,0,0,0,0,30};
. Eu não contei isso na minha pontuação.0 0 0 0 0 30
0 0 0 30 30 30
405 10 -14 -8 -9 205
fonte