Ruota un ipercubo


27

introduzione

Un ipercubo / tesseratto è l'equivalente a 4 dimensioni di un cubo normale. È realizzato prendendo una rete cubica, estendendola alla terza dimensione, quindi - usando la quarta dimensione - piegandola in un ipercubo. È fondamentalmente un cubo, dove ogni lato è un cubo.

Per creare un ipercubo, sono necessari 16 vettori 4d (un vettore con un x, un y, un ze un wcomponente). Questi vettori sono i seguenti:

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

L'ipercubo ha 24 facce. Il seguente elenco contiene tutti loro (ogni gruppo segna un quadrante):

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 tutte queste informazioni, tecnicamente hai un ipercubo nel codice. Per ruotare questo, sono necessarie 6 matrici diverse per ogni piano di rotazione, una per i piani YZ, XZ, XY, XW, YW e ZW. Dopo aver ottenuto ogni matrice, è necessario moltiplicare i vertici del cubo con essi.

Le seguenti immagini mostrano la struttura di ciascuna matrice:

Per la rotazione sul piano YZ:

Per la rotazione sul piano XZ:

Per la rotazione sul piano XY:

Per la rotazione sul piano XW:

Per la rotazione sul piano YW:

Per la rotazione sul piano ZW:

Le rotazioni vengono applicate in questo ordine.

Dopo tutto questo, hai un ipercubo ruotato. Ora devi disegnarlo. Si consiglia di utilizzare una proiezione ortogonale combinato con una proiezione prospettica per inviare (x, y, z, w)a (2x/(2+z), 2y/(2+z)).

Ingresso

Il tuo input è di 6 numeri interi compresi tra 0 (inclusivamente) e 360 ​​(esclusivamente). Questi rappresentano le rotazioni in gradi sui diversi piani di rotazione dell'ipercubo.

Produzione

L'output dovrebbe essere una singola immagine contenente l'ipercubo. Il display può essere un'immagine rasterizzata, un'immagine vettoriale o un'arte ASCII. L'immagine di output dovrebbe essere almeno 100 * 100 pixel e il cubo deve occupare almeno il 50% dello schermo. È consentito qualsiasi formato di output dell'immagine predefinito.

Casi test

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

Apri le immagini in una nuova scheda per vederle a schermo intero.

Regole

  • Si applicano le regole predefinite
  • Sono vietate le scappatoie standard
  • Vince il codice più breve in byte

Perché hai rovinato l'altro post?
Rɪᴋᴇʀ

@ EᴀsᴛᴇʀʟʏIʀᴋ L'ho pubblicato nella chat per un'ultima recensione
Bálint,

7
Come ho sottolineato in due diverse occasioni nella sandbox, la descrizione della proiezione per la visualizzazione è incompleta perché presuppone che l'oggetto da proiettare sia tridimensionale mentre, di fatto, è, ovviamente, tridimensionale.
Peter Taylor,

2
@luserdroog Penso che la 'U' debba essere 'N'.
becher

2
@Bálint Grazie per la sfida, mi sono divertito. Speriamo di avere più risposte e approcci diversi. : D
becher

Risposte:


9

Ottava, 474 433 429 byte

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

ruotato:

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

Le matrici di rotazione consumano ancora molti byte, ma il ciclo di Eulerian ha funzionato abbastanza bene, riducendo il numero di vertici visitati da 96 120 a 33.

I vertici vengono generati prendendo la rappresentazione binaria a 4 bit [0:15]e considerando msb come coordinata x e lsb come coordinata w.

Modifica: pre-moltiplicare tutte le matrici di rotazione è stato un incubo, motivo per cui non l'ho usato inizialmente, ma pre-moltiplicarle in coppie ha salvato 41 byte. Ora cerca la combinazione ottimale. :) Moltiplicare le matrici per tre era peggio di nessuna pre-moltiplicazione, quindi sarò felice con l'approccio a coppie.


Produzione:

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)


Modifica: sono stupido. ingannati dalla stessa variabile ovunque ... [Sei sicuro di non voler la matrice pre-moltiplicata completa? :) i.imgur.com/nkM6y6g.png]
algmyr

@algmyr Sì, la matrice completamente moltiplicata è uscita circa il doppio, se ricordo bene.
Becher

Dovrebbe essere più simile, goditi le stupide "semplificazioni" di Maxima
algmyr,

Per compensare il fallimento miserabile in matematica, ecco una versione più giocata del tuo codice, 330 byte: paste.ee/p/2GRyJ
algmyr

14

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

Utilizza mat.ps e G .

Modifica: -343 Generazione di codifica binaria applicata di vettori e circuito eulerianoStolenpreso in prestito da altre risposte. E ha applicato stringhe binarie token dalla libreria G.
Modifica: -49 Redefinito sin cose negcon nomi più brevi.
Modifica: -43 Nomi brevi definiti per le sequenze 0 0 0 1 1 0.
Modifica: -9 al (cioè. aload) È più corto di (")@. 3 chiamate fattorizzate a idi(es. idiv) Al costo di un non fare nulla 1 idiv.
Modifica: -30 Blocco di definizione implicita applicato da G.
Modifica: -10 Alcune sequenze più utilizzate triplicamente.
Modifica: -45 Rimuovi le variabili i j k l m nper gli angoli e definisce sempre l'angolo corrente poiché le tfunzioni degli angoli utilizzano il valore di (globale)tvariabile. Rinvia l'esecuzione della descrizione del codice della matrice di rotazione fino a quando il suo tvalore non è pronto.
Modifica: -3 Rimuovi <16>$ie. closepath. E uno spazio.
Modifica: -16 Parentesi di matrice fattorizzate dai vettori di unità nelle matrici di rotazione ( J K Le M). Nuova richiesta rilasciata moper mode super sub.
Modifica: -12 In linea la funzione progetto-e-disegna e rimuovi (ora vuoto) dizionario allegato.
Modifica: -36 Codificato il circuito (cioè le facce ) in una stringa.
Modifica: -8 Rimuove la definizione dell'array vertici V. Invece, lascia in pila edupcopie di lavoro secondo necessità (una volta, all'inizio e di nuovo alla fine del ciclo). Inoltre, tradotto alcuni operatori da stringhe binarie token in nomi abbreviati in cui il BTS non ha dato risparmi, così (I)$è ora fora(cioè. forall). if dupotrebbe essere (T8)$, ma if duè chiaramente una scelta migliore (è golf , non offuscamento in sé). Inoltre, esegui il scale precedente translate , in modo che le coordinate tradotte possano essere 3e 4invece di 300e 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)#

La 3 4e 100nella prima riga del secondo blocco sono parametri che rappresentano rispettivamente centro-x, centro-y e scala del disegno sulla pagina (le coordinate centrali sono ridimensionate da scale). (300.400) è approssimativamente il centro della carta americana in formato lettera (612.792) nelle unità PS.

Se puoi seguire approssimativamente Postscript, le cose bizzarre importanti sono il blocco di procedura implicito e le stringhe dell'operatore codificate. Come mostrato dai commenti nel file di lavoro, di seguito, ogni riga del primo blocco è implicitamente denominata da A, B, C, ecc. Quindi, ad es. F E Dprodurrebbe 1 0 0 1 0 0. Per le stringhe dell'operatore codificate, tutto ciò che è un argomento $ #o @è una sequenza di chiamate dell'operatore, utilizzando i byte per selezionare gli operatori dalla tabella dei nomi di sistema, PLRM 3ed Appendice F. Queste funzionalità e altro sono disponibili per PostScript con la libreria G ( ora include anche le funzioni mat.ps).

file di lavoro:

(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 e leggermente commentato:

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 :(

Alcuni dei miei risultati sono immagini speculari degli esempi della domanda.

Per gs -- hc.ps 0 0 0 0 0 0, ottengo:
inserisci qui la descrizione dell'immagine

gs -- hc.ps 0 0 0 0 0 30
inserisci qui la descrizione dell'immagine

gs -- hc.ps 30 0 0 0 0 30
inserisci qui la descrizione dell'immagine

gs -- hc.ps 0 0 0 30 30 30
inserisci qui la descrizione dell'immagine

gs -- hc.ps 45 45 45 0 0 0
inserisci qui la descrizione dell'immagine

gs -- hc.ps 45 45 45 45 45 45
inserisci qui la descrizione dell'immagine

Animazione bonus che ho appena realizzato con questo programma. Questa immagine corrisponde alla sequenza di rotazione 0 30 60 0 i i , dove i varia da 0 a 360 x 2.
inserisci qui la descrizione dell'immagine


2
Wow. Una risposta PostScript per un problema matematico.
TuxCrafting

@ TùxCräftîñg In realtà non c'è molta matematica in questa domanda finché puoi fare facilmente la moltiplicazione di matrici. E ho voluto scrivere questo programma da quando ho letto The Armchair Universe di AK Dewdney .
Luser droog

Aggiunte nuove funzioni alla libreria G. Non può essere utilizzato qui, ma consente questa versione da 307 byte .
Luser droog,

8

C # + Unità, 1060 845 835 byte

C # ≈ Java

Presuppone che questa funzione sia inserita in uno script MainCamera.

Modifica:
grazie a @TuukkaX per i suggerimenti per salvare 19 byte Salvati ~ 200 byte usando il ciclo euleriano.

golfed:

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

Newline + indentazione + Full shell:

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

Non riuscivo a capire una semplice formula per costruire le matrici di rotazione né le "facce" che disegnare, cosicché il codice hard costava molti byte. Ho preso in prestito il ciclo euleriano da @beaker. Inoltre, i built-in di Unity sono estremamente dettagliati.

Puoi verificare tutti i casi di test online .


Questa è la prima volta che vedo una risposta Unity C # + qui. +1
DanTheMan,

Penso che ogni 0.5fpuò essere ridotto a .5fe 0.01fa .01f. Penso anche che le matrici di numeri interi possano essere separate con una virgola invece di dirlo int[]più volte.
Yytsi,

@Blue Oh, hai ragione! Non ho usato C # per un po ', quindi non ero sicuro dell'ultimo suggerimento.
Yytsi,

@TuukkaX Ignora il mio commento precedente, che posso usare int[,]. Grazie ancora.
Blu

Hai ancora un Vector4(0.5f,0.5f,0.5f,0.5f)che potrebbe essere ridotto a Vector4(.5f,.5f,.5f,.5f).
Yytsi,

6

Javascript ES6, 584 byte

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)

"Ungolfed":

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

Guardalo in azione (modificato per ruotare 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 funzione restituisce un oggetto canvas HTML5, ad esempio è necessario aggiungerlo alla pagina document.body.appendChild(f(0,0,0,0,0,0)).

Attualmente, le rotazioni vengono applicate fuori servizio, sto lavorando sul riordino, ma così com'è, ruota correttamente un ipercubo.


Intelligente, mi ci è voluto un po 'per capire cosa stavi facendo con le trasformazioni di matrice. : D Inoltre, non riesco a far funzionare il tuo frammento di codice ... mi sta dando un inutile "Errore di script". in linea 0.
Becher

@beaker Quale browser stai usando? L'ho provato sull'ultimo Firefox.
Dendrobium,

Sono su Safari 9.1.1. Lasciami provare un altro.
becher

1
Sì, Chrome funziona bene.
becher

1
Safari è una schifezza. Non usarlo per verificare se qualcosa funziona.
Patrick Roberts,

1

Mathematica, 453 415 byte *

Abbreviato usando il tour di Eulerian e ripulendo tutto in una singola istruzione senza definire le funzioni nelle variabili. Questo rende il codice più lento per qualche motivo. Immagino che Mathematica rivaluti le funzioni più volte ora che non sono memorizzate in una variabile.

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

* Sto contando °e ==come byte singoli ciascuno poiché sono rappresentati come un singolo carattere in Mathematica. Penso che sia giusto poiché molte lingue usano strane codifiche di caratteri.

Non rigato di commenti. L'ingresso è fortemente codificato in alto come a={30,0,0,0,0,30};. Non ho contato questo per il mio punteggio.


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

inserisci qui la descrizione dell'immagine

405 10 -14 -8 -9 205

inserisci qui la descrizione dell'immagine

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.