Rotar un hipercubo


27

Introducción

Un hipercubo / tesseract es el equivalente de 4 dimensiones de un cubo normal. Se hace tomando una red de cubos, extendiéndola a la tercera dimensión, luego, usando la cuarta dimensión, doblándola en un hipercubo. Básicamente es un cubo, donde cada lado es un cubo.

Para crear un hipercubo, necesita 16 vectores 4d (un vector con un x, a y, ay zun wcomponente). Estos vectores son los siguientes:

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);

El hipercubo tiene 24 caras. La siguiente lista contiene todos ellos (cada grupo marca un 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

Con toda esta información, técnicamente tiene un hipercubo en el código. Para rotar esto, necesita 6 matrices diferentes para cada plano de rotación, una para los planos YZ, XZ, XY, XW, YW y ZW. Después de tener cada matriz, debe multiplicar los vértices del cubo con ellas.

Las siguientes imágenes muestran la estructura de cada matriz:

Para la rotación en el plano YZ:

Para la rotación en el plano XZ:

Para la rotación en el plano XY:

Para la rotación en el plano XW:

Para la rotación en el plano YW:

Para la rotación en el plano ZW:

Las rotaciones se aplican en este orden.

Después de todo esto, tienes un hipercubo rotado. Ahora necesitas dibujarlo. Debe utilizar una proyección ortogonal combinado con una proyección en perspectiva para enviar (x, y, z, w)a (2x/(2+z), 2y/(2+z)).

Entrada

Su entrada es de 6 enteros entre 0 (inclusive) y 360 (exclusivamente). Estos representan las rotaciones en grados en los diferentes planos de rotación del hipercubo.

Salida

Su salida debe ser una sola imagen que contenga el hipercubo. La pantalla puede ser una imagen rasterizada, una imagen vectorial o un arte ASCII. La imagen de salida debe tener al menos 100 * 100 píxeles, y el cubo debe ocupar al menos el 50% de la pantalla. Se permite cualquier formato de salida de imagen predeterminado.

Casos de prueba

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 las imágenes en una nueva pestaña para verlas en tamaño completo.

Reglas

  • Aplican reglas predeterminadas
  • Las lagunas estándar están prohibidas
  • El código más corto en bytes gana

¿Por qué atacaste la otra publicación?
Rɪᴋᴇʀ

@ EᴀsᴛᴇʀʟʏIʀᴋ Lo publiqué en el chat para una última revisión
Bálint

77
Como he señalado en dos ocasiones separadas en la caja de arena, la descripción de la proyección para la visualización es incompleta porque supone que el objeto a proyectar es tridimensional, mientras que, de hecho, obviamente es de 4 dimensiones.
Peter Taylor

2
@luserdroog Creo que la 'U' debe ser 'N'.
vaso de precipitados

2
@ Bálint Gracias por el desafío, lo disfruté. Con suerte obtendremos más respuestas y diferentes enfoques. : D
vaso

Respuestas:


9

Octava, 474 433 429 bytes

function H(a,b,c,d,e,f) C=@cosd;S=@sind;R=[1,0,0,0;0,C(e),0,-S(e);0,-S(e)*S(f),C(f),-C(e)*S(f);0,S(e)*C(f),S(f),C(e)*C(f)]*[C(c)*C(d),-S(c)*C(d),0,S(d);S(c),C(c),0,0;0,0,1,0;-C(c)*S(d),S(c)*S(d),0,C(d)]*[C(b),S(a)*S(b),C(a)*S(b),0;0,C(a),-S(a),0;-S(b),S(a)*C(b),C(a)*C(b),0;0,0,0,1]*(dec2bin(0:15)'-48.5);Z=R(3,:)+2;R=2*R./Z;Q=[1,2,10,12,11,9,10,14,16,12,4,8,16,15,11,3,7,15,13,9,1,5,13,14,6,8,7,5,6,2,4,3,1];plot(R(1,Q),R(2,Q));

Rotado:

function H(a,b,c,d,e,f) 
C=@cosd;S=@sind;
R=[1,0,0,0;0,C(e),0,-S(e);0,-S(e)*S(f),C(f),-C(e)*S(f);0,S(e)*C(f),S(f),C(e)*C(f)]*
  [C(c)*C(d),-S(c)*C(d),0,S(d);S(c),C(c),0,0;0,0,1,0;-C(c)*S(d),S(c)*S(d),0,C(d)]*
  [C(b),S(a)*S(b),C(a)*S(b),0;0,C(a),-S(a),0;-S(b),S(a)*C(b),C(a)*C(b),0;0,0,0,1]*
  (dec2bin(0:15)'-48.5);
Z=R(3,:)+2;
R=2*R./Z;
Q=[1,2,10,12,11,9,10,14,16,12,4,8,16,15,11,3,7,15,13,9,1,5,13,14,6,8,7,5,6,2,4,3,1];
plot(R(1,Q),R(2,Q));

Las matrices de rotación aún consumen muchos bytes, pero el ciclo de Eulerian funcionó bastante bien, reduciendo el número de vértices visitados de 96 120 a 33.

Los vértices se generan tomando la representación binaria de 4 bits [0:15]y considerando que el msb es la coordenada xy el lsb la coordenada w.

Editar: Multiplicar previamente todas las matrices de rotación fue una pesadilla, es por eso que no lo usé inicialmente, pero multiplicarlas previamente en pares ahorró 41 bytes. Ahora para buscar la combinación óptima. :) Multiplicar las matrices por tres fue peor que ninguna multiplicación previa, así que estaré contento con el enfoque por pares.


Salida:

H(0,0,0,0,0,0)

H (0,0,0,0,0,0)

H(0,0,0,0,0,30)

H (0,0,0,0,0,30)

H(30,0,0,0,0,30)

H (30,0,0,0,0,30)

H(0,0,0,30,30,30)

H (0,0,0,30,30,30)

H(45,45,45,0,0,0)

H (45,45,45,0,0,0)

H(45,45,45,45,45,45)

H (45,45,45,45,45,45)


Editar: soy estúpido. engañado por la misma variable en todas partes ... [¿Estás seguro de que no quieres la matriz pre-multiplicada completa? :) i.imgur.com/nkM6y6g.png]
algmyr

@algmyr Sí, la matriz completamente multiplicada salió aproximadamente el doble de tiempo, si no recuerdo mal.
vaso

Esto debería ser más parecido, disfrute de las "simplificaciones" estúpidas de Maxima: i.imgur.com/klkXLPf.png
algmyr

Para compensar el fracaso miserable en matemáticas, aquí hay una versión más golfizada de su código, 330 bytes: paste.ee/p/2GRyJ
algmyr

14

Posdata 1075 732 683 640 631 601 590 545 542 526 514 478 470

Utiliza mat.ps y G .

Edición: -343 Generación de codificación binaria aplicada de vectores y circuito eulerianorobadoprestado de otras respuestas. Y aplicó cadenas de tokens binarios de la biblioteca G.
Editar: -49 Redefinido sin cosy negcon nombres más cortos.
Editar: -43 Nombres cortos definidos para secuencias 0 0 0 1 1 0.
Editar: -9 al (es decir aload) es más corto que (")@. Llamadas factorizadas a 3 idi(es decir idiv) a costa de un no hacer nada 1 idiv.
Edición: -30 Bloque de definición implícita aplicado de G.
Edición: -10 Algunas secuencias más triplicadas.
Editar: -45 Eliminar variables i j k l m npara los ángulos y siempre definir el ángulo actual como ty las funciones de los ángulos usan el valor de (global)tvariable. Aplazar la ejecución de la descripción del código de la matriz de rotación hasta que su tvalor esté listo.
Editar: -3 Eliminar <16>$ie. closepath. Y un espacio
Editar: -16 paréntesis de matriz de factores de vectores unitarios en las matrices de rotación ( J K Ly M). Vuelva a aplicar eliminado mopor mody supara sub.
Editar: -12 En línea la función de proyecto y dibujar y eliminar (ahora vacío) diccionario adjunto.
Editar: -36 Codificó el circuito (es decir, las caras ) en una cadena.
Editar: -8 Eliminar definición de matriz de vértices V. En cambio, deje en la pila ydupcopias de trabajo según sea necesario (una vez, al principio, y nuevamente al final del ciclo). Además, tradujo algunos operadores de cadenas de tokens binarios a nombres abreviados donde el BTS no dio ahorros, por (I)$lo que ahora es fora(es decir forall). if dupodría ser (T8)$, pero if dues claramente una mejor opción (es golf , no ofuscación per se). Además, realice el scale antes translate , para que las coordenadas traducidas puedan ser 3y en 4lugar de 300y 400.

(mat.ps)run 3(G)run $
t sin
A neg
t cos
0 0
0 1
1 0
2 mu Z 2(!V)@
idi 2 mo .5 su
(>8)$
[F D]
[D E]
[E D]
[D F]

3 4 100(&>88)$(,)# div(<N)#[E 15{[I 1 H I 2 H I 4 H ex 8 H]}fo]E
5{ARGUMENTS 1(XK/)$/t ex d{{J[0 C B 0][0 A C 0]K}{[C 0 A 0]L[B 0
C 0]K}{[C B D][A C D]M K}{[C D A]L M[B D C]}{J[0 C 0 B]M[0 A 0
C]}{J L[D C B][D A C]}}(>K)$[(>?)$]transpose matmul}fo
du(019;:89=?;37?>:26><804<=576451320){48 su get al po{W
Z Y X}{(>3)$}fora X G Y G{li}(D)#{mov}if du}fora(HB)#

Los 3 4y 100en la primera línea del segundo bloque son parámetros que representan centro-x, centro-y y escala, respectivamente, del dibujo en la página (las coordenadas centrales se escalan por scale). (300,400) es aproximadamente el centro del papel tamaño carta estadounidense (612,792) en unidades PS.

Si puede seguir aproximadamente PostScript, las cosas extrañas importantes son el bloque de procedimiento implícito y las cadenas de operador codificadas. Como se muestra en los comentarios en el archivo de trabajo, a continuación, cada línea del primer bloque está implícitamente nombrada por A, B, C, etc. Entonces, por ejemplo. F E Dproduciría 1 0 0 1 0 0. Para las cadenas de operador codificadas, cualquier cosa que sea un argumento $ #o @una secuencia de llamadas de operador, utilizando los bytes para seleccionar operadores de la tabla de nombres del sistema, PLRM 3ed Apéndice F. Estas características y más están disponibles para PostScript con la biblioteca G ( ahora también incluye las funciones mat.ps).

Archivo de trabajo:

(mat.ps)run 3(G)run $
t sin %/A
A neg %/B
t cos %/C
0 0 %/D
0 1 %/E
1 0 %/F
2 mu Z 2(!V)@ %/G  %ad div %add div %108 1 54
idi 2 mo .5 su %idiv mod sub %/H %106 169 51
(>8)$ %/I %exch dup
[F D] %/J
[D E] %/K
[E D] %/L
[D F] %/M


3 4
100(&>88)$ %currentlinewidth exch dup dup %38
(,)#  %scale %139-95=44
div(<N)# %div setlinewidth %54 155-95=60 %translate %173-95=78
%/V
[E 15{[ I
    1 H I
    2 H I
    4 H ex
    8 H]}fo]

E 5{ARGUMENTS 1(XK/)$ %index get cvr %88 75 47
    /t ex d %exch def %62 51
    {{J[0 C B 0][0 A C 0]K} 
     {[C 0 A 0]L[B 0 C 0]K} 
     {[C B D][A C D]M K} 
     {[C D A]L M[B D C]}
     {J[0 C 0 B]M[0 A 0 C]}
     {J L[D C B][D A C]}}
    (>K)$ %exch get %62 75
    [
        (>?)$ %exch exec %62 63
    ]
    transpose matmul
}fo %for
du %dup
%d %def
%{transpose matmul}fora d

%[E 9 11 10 8 9 13 15 11 3 7 15 14 10 2 6 14 12 8 0 4 12 13 5 7 6 4 5 1 3 2 0]
%<0001090b0a08090d0f0b03070f0e0a02060e0c0800040c0d050706040501030200>
%          abcdef
%0123456789:;<=>?
(019;:89=?;37?>:26><804<=576451320)
{48 su get % 169 75 %V (>K)$ %sub %exch get

    al po %aload pop %2 117
    {W Z Y X}{(>3)$ %exch def
    }fora %forall %2 117  62 51 73
    X G
    Y G
    {li}(D)# %stopped
    {mov}
    if du%(T8)$ %if %84 du %dup 56
}
%<49a7a1>$ %forall stroke showpage %73 167-95=72 161-95=66
fora(HB)#

Ungolfed y ligeramente comentado:

300 400 translate   %roughly center of letter paper
currentlinewidth
100 dup dup scale
div setlinewidth    %scale x100, reduce line-width/100
(mat.ps)run         %load matrix library
ARGUMENTS aload pop{f e d c b a}{exch cvr def}forall  %define args as 
                                 % a,b,etc and convert to real numbers
/m{2 mod .5 sub}def
/P{aload pop{w z y x}{exch def}forall   %P: [x y z w]  project-and-draw  -
    x 2 mul z 2 add div 
    y 2 mul z 2 add div 
    {lineto}stopped{moveto}if %catch(&handle!) nocurrentpoint error in lineto
}bind def
/V[0 1 15{    % generate vectors with a for-loop
    [ exch
        dup m
        1 index 2 idiv m
        2 index 4 idiv m
        4 3 roll 8 idiv m
    ]
}for]
[[[1 0 0 0][0 a cos a sin neg 0][0 a sin a cos 0][0 0 0 1]] 
     [[b cos 0 b sin 0][0 1 0 0][b sin neg 0 b cos 0][0 0 0 1]] 
     [[c cos c sin neg 0 0][c sin c cos 0 0][0 0 1 0][0 0 0 1]] 
     [[d cos 0 0 d sin][0 1 0 0][0 0 1 0][d sin neg 0 0 d cos]]
     [[1 0 0 0][0 e cos 0 e sin neg][0 0 1 0][0 e sin 0 e cos]]
     [[1 0 0 0][0 1 0 0][0 0 f cos f sin neg][0 0 f sin f cos]]]
{transpose matmul} forall def   % apply array of rotations and define

%Eulerian circuit (borrowed and adjusted for 0-based indexing)
[0 1 9 11 10 8 9 13 15 11 3 7 15 14 10 2 6 14 12 8 0 4 12 13 5 7 6 4 5 1 3 2 0]

% the main program!
% on the stack is the Eulerian circuit array
{
    V exch get  %lookup index in (sextuply-transformed) vertex array
    P           %call project-and-draw
} forall
closepath stroke %draw it, don't just think about it

showpage % gs's cmd-line-args option automatically sets -dBATCH,
    % so without a showpage, gs will immediately exit before you
    % can look at the picture :(

Algunas de mis salidas son imágenes espejo de los ejemplos de la pregunta.

Para gs -- hc.ps 0 0 0 0 0 0, me sale:
ingrese la descripción de la imagen aquí

gs -- hc.ps 0 0 0 0 0 30
ingrese la descripción de la imagen aquí

gs -- hc.ps 30 0 0 0 0 30
ingrese la descripción de la imagen aquí

gs -- hc.ps 0 0 0 30 30 30
ingrese la descripción de la imagen aquí

gs -- hc.ps 45 45 45 0 0 0
ingrese la descripción de la imagen aquí

gs -- hc.ps 45 45 45 45 45 45
ingrese la descripción de la imagen aquí

Animación adicional que acabo de hacer con este programa. Esta imagen corresponde a la secuencia de rotación 0 30 60 0 i i , donde i varía de 0 a 360 por 2.
ingrese la descripción de la imagen aquí


2
Guau. Una respuesta PostScript para un problema matemático.
TuxCrafting

@ TùxCräftîñg En realidad no hay tanta matemática en esta pregunta, siempre y cuando puedas multiplicar fácilmente la matriz. Y he querido escribir este programa desde que leí The Armchair Universe de AK Dewdney .
luser droog

Se agregaron nuevas funciones a la biblioteca G. No se puede usar aquí, pero permite esta versión de 307 bytes .
luser droog

8

C # + Unidad, 1060 845 835 bytes

C # ≈ Java

Asume que esta función está en un script colocado MainCamera.

Editar:
Gracias a @TuukkaX por las sugerencias para guardar 19 bytes. Guardado ~ 200 bytes usando el ciclo Euleriano.

Golfizado:

void d(float[]r){transform.position=Vector3.back*2;GetComponent<Camera>().backgroundColor=Color.black;Vector4[]p=new Vector4[16];Matrix4x4[]m=new Matrix4x4[6];int i=0;for(;i<16;i++)p[i]=new Vector4(i%2,i/2%2,i/4%2,i/8%2)-new Vector4(.5f,.5f,.5f,.5f);int[,]X={{6,8,1,12,7,11},{5,0,0,0,5,10},{10,10,5,15,15,15}};for(i=0;i<6;i++){m[i]=Matrix4x4.identity;r[i]=Mathf.Deg2Rad*r[i];float c=Mathf.Cos(r[i]),s=Mathf.Sin(r[i]);m[i][X[1,i]]=c;m[i][X[2,i]]=c;m[i][X[0,i]]=s;m[i][X[0,i]%4*4+X[0,i]/4]=-s;}for(i=0;i<16;i++)foreach(Matrix4x4 x in m)p[i]=x*p[i];int[]F={0,1,9,11,10,8,9,13,15,11,3,7,15,14,10,2,6,14,12,8,0,4,12,13,5,7,6,4,5,1,3,2,0};LineRenderer l=new GameObject().AddComponent<LineRenderer>();l.SetVertexCount(33);l.material=new Material(Shader.Find("Sprites/Default"));l.SetWidth(.03f,.03f);for(i=0;i<33;i++)l.SetPosition(i,p[F[i]]);

Newlines + sangría + Shell completo:

using UnityEngine;
using System.Collections;

public class h : MonoBehaviour {

    void d(float[]r)
    {
        transform.position=Vector3.back*2.5f;
        GetComponent<Camera>().backgroundColor=Color.black;
        Vector4[]p=new Vector4[16];
        Matrix4x4[]m=new Matrix4x4[6];
        int i=0;
        for(;i<16;i++)p[i]=new Vector4(i%2,i/2%2,i/4%2,i/8%2)-new Vector4(.5f,.5f,.5f,.5f);
        int[,]X={{6,8,1,12,7,11},{5,0,0,0,5,10},{10,10,5,15,15,15}};
        for (i=0;i<6;i++){
            m[i]=Matrix4x4.identity;
            r[i]=Mathf.Deg2Rad*r[i];
            float c=Mathf.Cos(r[i]);
            float s=Mathf.Sin(r[i]);
            m[i][X[1,i]]=c;
            m[i][X[2,i]]=c;
            m[i][X[0,i]]=s;
            m[i][X[0,i]%4*4+X[0,i]/4]=-s;
        }
        for (i=0;i<16;i++)foreach(Matrix4x4 x in m)p[i]=x*p[i];
        int[]F={0,1,9,11,10,8,9,13,15,11,3,7,15,14,10,2,6,14,12,8,0,4,12,13,5,7,6,4,5,1,3,2,0};
        LineRenderer l=new GameObject().AddComponent<LineRenderer>();
        l.SetVertexCount(33);
        l.material=new Material(Shader.Find("Sprites/Default"));
        l.SetWidth(.03f,.03f);
        for (i=0;i<33;i++)
            l.SetPosition(i,p[F[i]]);
        l.gameObject.tag = "Player";
    }
    public float[] input;
    void Start()
    {
        d(input);
    }
}

No pude encontrar una fórmula simple para construir las matrices de rotación ni las "caras" que dibujar, por lo que costará muchos bytes codificar. Tomé prestado el ciclo euleriano de @beaker. Además, los elementos integrados de Unity son extremadamente detallados.

Puede verificar todos los casos de prueba en línea .


Esta es la primera vez que veo una respuesta de C # + Unity aquí. +1
DanTheMan

Creo que todo 0.5fse puede reducir a .5fy 0.01fpara .01f. También creo que las matrices de enteros se pueden separar con una coma en lugar de decir int[]varias veces.
Yytsi

@Blue ¡Oh, tienes razón! No he usado C # por un tiempo, así que no estaba seguro del último consejo.
Yytsi

@TuukkaX Ignora mi comentario anterior, puedo usarlo int[,]. Aún así, gracias.
Azul

Todavía tienes uno Vector4(0.5f,0.5f,0.5f,0.5f)que podría reducirse a Vector4(.5f,.5f,.5f,.5f).
Yytsi

6

Javascript ES6, 584 bytes

f=(...R)=>(P=s=>[...s].map(i=>parseInt(i,16)),C=document.createElement`canvas`,X=C.getContext`2d`,X.translate((C.width=300)/2,(C.height=300)/2),X.lineWidth=0.01,X.scale(100,100),X.beginPath(),P("0267fd9804c8ab915dcefb37546ea2310").map((e,i)=>{[x,y,z]=P("084c2a6e195d3b7f").map(i=>[...(1e3+i.toString(2)).slice(-4)].map(i=>i-0.5)).map(e=>(R.map((R,i,_,M=Math,C=M.cos(r=R*M.PI/180),S=M.sin(r))=>((a,b,s=1)=>[e[a],e[b]]=[C*e[a]-s*S*e[b],s*S*e[a]+C*e[b]])(...[[1,2],[0,2,-1],[0,1],[0,3,-1],[1,3],[2,3]][i])),e))[e];[x,y]=[2*x/(2+z),2*y/(2+z)];i?X.lineTo(x,y):X.moveTo(x,y)}),X.stroke(),C)

"Sin golf":

f=(...R)=>(                                                              // function that accepts rotations in the following form: f(a,b,c,d,e,f)
    P=s=>[...s].map(i=>parseInt(i,16)),                                  // function to convert strings to hex-arrays
    V=P("084c2a6e195d3b7f")                                              // vertices encoded as hex values ( [0,1,1,0] -> 6 )
        .map(i=>[...(1e3+i.toString(2)).slice(-4)].map(i=>i-0.5))        // convert hex values to vertices, center the hypercube
        .map(e=>(R.map((R,i,_,M=Math,C=M.cos(r=R*M.PI/180),S=M.sin(r))=> // convert angles to degrees, precalculate sin and cos values
        ((a,b,s=1)=>[e[a],e[b]]=[C*e[a]-s*S*e[b],s*S*e[a]+C*e[b]])       // apply matrix transforms to all vertices
        (...[[1,2],[0,2,-1],[0,1],[0,3,-1],[1,3],[2,3]][i])),e)),        // list of encoded matrix transforms
    C=document.createElement`canvas`,X=C.getContext`2d`,                 // create image to draw on
    X.translate((C.width=300)/2,(C.height=300)/2),                       // setup image dimensions, center transform
    X.lineWidth=0.01,X.scale(100,100),X.beginPath(),                     // setup line, scale the transform and begin drawing
    P("0267fd9804c8ab915dcefb37546ea2310").map((e,i)=>{                  // hypercube edge path indices encoded as hex values
        [x,y,z]=V[e];[x,y]=[2*x/(2+z),2*y/(2+z)];                        // project vertex
        i?X.lineTo(x,y):X.moveTo(x,y)}),X.stroke(),                      // draw vertex
    C)                                                                   // return image

Véalo en acción (modificado para rotar continuamente):

with(document)with(Math)with(document.getElementById`canvas`)with(getContext`2d`){render=()=>{requestAnimationFrame(render);clearRect(0,0,width,height);save();K=performance.now();R=[K*0.01,K*0.02,K*0.03,K*0.04,K*0.05,K*0.06];X=s=>[...s].map(i=>parseInt(i,16));V=X("084c2a6e195d3b7f").map(i=>[...(1e3+i.toString(2)).slice(-4)].map(i=>i-0.5)).map(e=>(R.map((R,i,_,C=cos(r=R*PI/180),S=sin(r))=>((a,b,s=1)=>[e[a],e[b]]=[C*e[a]-s*S*e[b],s*S*e[a]+C*e[b]])(...[[1,2],[0,2,-1],[0,1],[0,3,-1],[1,3],[2,3]][i])),e));translate((width=300)/2,(height=300)/2);lineWidth=0.01;scale(100,100);beginPath();X("0267fd9804c8ab915dcefb37546ea2310").map((e,i)=>{[x,y,z]=V[e];[x,y]=[2*x/(2+z),2*y/(2+z)];i?lineTo(x,y):moveTo(x,y)});stroke();restore();};render();}
<html><body><canvas id="canvas"></canvas></body></html>

La función devuelve un objeto de lienzo HTML5, debe agregarlo a la página haciendo, document.body.appendChild(f(0,0,0,0,0,0))por ejemplo.

Actualmente, las rotaciones se aplican fuera de orden, estoy trabajando en el reordenamiento, pero como es, rota un hipercubo correctamente.


Inteligente, me tomó un tiempo darme cuenta de lo que estabas haciendo con las transformaciones de la matriz. : D Además, no puedo hacer que el fragmento de código funcione ... me está dando un "error de script" inútil. en línea 0.
vaso

@beaker ¿Qué navegador estás usando? Lo probé en el último Firefox.
Dendrobium

Estoy en Safari 9.1.1. Déjame probar uno diferente.
vaso

1
Sí, Chrome funciona bien.
vaso

1
Safari es una mierda. No lo use para verificar si algo funciona.
Patrick Roberts

1

Mathematica, 453 415 bytes *

Se acorta usando el recorrido Euleriano y limpiándolo todo en una sola declaración sin definir funciones en variables. Esto hace que el código sea más lento por alguna razón. Supongo que Mathematica reevalúa las funciones varias veces ahora que no están almacenadas en una variable.

Graphics[Line[Table[{2#/(2+#3),2#2/(2+#3)}&@@Map[Dot@@Table[Table[If[n==m==#2||n==m==#,Cos[#3],If[n==#2&&m==#,If[#2==1&&(#==3||#==4),1,-1]Sin[#3],If[n==#&&m==#2,If[#2==1&&(#==3||#==4),-1,1]Sin[#3],If[n==m,1,0]]]],{n,4},{m,4}]&[k[[1]],k[[2]],a[[k[[3]]]]°],{k,{{4,3,6},{4,2,5},{4,1,4},{2,1,3},{3,1,2},{3,2,1}}}].#&,Tuples[{0,1},4]-.5,{1}][[i]],{i,{1,2,10,12,11,9,10,14,16,12,4,8,16,15,11,3,7,15,13,9,1,5,13,14,6,8,7,5,6,2,4,3,1}}]]]

* Estoy contando °y ==como bytes individuales cada uno ya que están representados como un solo carácter en Mathematica. Creo que esto es justo, ya que muchos idiomas usan codificaciones de caracteres extraños.

Ungolfed con comentarios. La entrada está codificada en la parte superior como a={30,0,0,0,0,30};. No conté eso para mi puntaje.


a = {45, 45, 45, 45, 45, 45};



(* #2,#-th rotation matrix as a funciton of #3 *)
(* Using the \
#-notation saved 6 bytes over the more common function definition \
notation*)
r = 
  Table[If[n == m == #2 || n == m == #, Cos[#3], 
     If[n == #2 && m == #, 
      If[#2 == 1 && (# == 3 || # == 4), 1, -1] Sin[#3], 
      If[n == # && m == #2, 
       If[#2 == 1 && (# == 3 || # == 4), -1, 1] Sin[#3], 
       If[n == m, 1, 0]]]], {n, 4}, {m, 4}] &;

(* Total rotation matrix. Need six of them. Function of the six \
angles to rotate.*)

u = Dot @@ 
     Table[r[k[[1]], 
       k[[2]], \[Degree]*
        a[[k[[3]]]]], {k, {{4, 3, 6}, {4, 2, 5}, {4, 1, 4}, {2, 1, 
         3}, {3, 1, 2}, {3, 2, 1}}}].# &;



(* List of all vertices of the hypercube *)
t = Tuples[{0, 1}, 4];
t -= .5;
v = Map[u, t, {1}];

(*projection*)
p = {2 #/(2 + #3), 2 #2/(2 + #3)} &;

(*Eulerian tour*)

l = Table[
   p @@ v[[i]], {i, {1, 2, 10, 12, 11, 9, 10, 14, 16, 12, 4, 8, 16, 
     15, 11, 3, 7, 15, 13, 9, 1, 5, 13, 14, 6, 8, 7, 5, 6, 2, 4, 3, 
     1}}];
Graphics[Line[l]]

0 0 0 0 0 30

0 0 0 30 30 30

ingrese la descripción de la imagen aquí

405 10 -14 -8 -9 205

ingrese la descripción de la imagen aquí

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.