Faire pivoter un hypercube

27

introduction

Un hypercube / tesseract est l'équivalent en 4 dimensions d'un cube normal. Il est fait en prenant un filet de cube, en l'étendant à la 3e dimension, puis - en utilisant la 4e dimension - en le pliant en un hypercube. C'est fondamentalement un cube, où chaque côté est un cube.

Pour créer un hypercube, vous avez besoin de 16 vecteurs 4d (un vecteur avec un x, un y, un zet un wcomposant). Ces vecteurs sont les suivants:

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'hypercube a 24 faces. La liste suivante les contient tous (chaque groupe marque 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

Avec toutes ces informations, vous avez techniquement un hypercube en code. Pour faire pivoter cela, vous avez besoin de 6 matrices différentes pour chaque plan de rotation, une pour les plans YZ, XZ, XY, XW, YW et ZW. Une fois que vous avez chaque matrice, vous devez multiplier les sommets du cube avec eux.

Les images suivantes montrent la structure de chaque matrice:

Pour la rotation sur le plan YZ:

Pour la rotation sur le plan XZ:

Pour la rotation sur le plan XY:

Pour la rotation sur le plan XW:

Pour la rotation sur le plan YW:

Pour la rotation sur le plan ZW:

Les rotations sont appliquées dans cet ordre.

Après tout cela, vous avez un hypercube tourné. Maintenant, vous devez le dessiner. Vous devez utiliser une projection orthogonale combinée à une projection en perspective d'envoyer (x, y, z, w)à (2x/(2+z), 2y/(2+z)).

Contribution

Votre entrée est de 6 entiers compris entre 0 (inclusivement) et 360 (exclusivement). Ceux-ci représentent les rotations en degrés sur les différents plans de rotation de l'hypercube.

Sortie

Votre sortie doit être une seule image contenant l'hypercube. L'affichage peut être une image tramée, une image vectorielle ou un art ASCII. L'image de sortie doit être d'au moins 100 * 100 pixels et le cube doit occuper au moins 50% de l'écran. Tout format de sortie d'image par défaut est autorisé.

Cas de 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

Ouvrez les images dans un nouvel onglet, pour les voir en taille réelle.

Règles

  • Les règles par défaut s'appliquent
  • Les failles standard sont interdites
  • Le code le plus court en octets gagne
Bálint
la source
Pourquoi avez-vous nuke l'autre poste?
Rɪᴋᴇʀ
@ EᴀsᴛᴇʀʟʏIʀᴋ Je l'ai posté dans le chat pour une dernière critique
Bálint
7
Comme je l'ai souligné à deux reprises dans le bac à sable, la description de la projection pour l'affichage est incomplète car elle suppose que l'objet à projeter est en 3 dimensions alors qu'il est en fait, évidemment, en 4 dimensions.
Peter Taylor
2
@luserdroog Je pense que le «U» doit être «N».
bécher
2
@ Bálint Merci pour le défi, je l'ai apprécié. J'espère que nous aurons plus de réponses et d'approches différentes. : D
bécher

Réponses:

9

Octave, 474 433 429 octets

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

Tourné:

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

Les matrices de rotation consomment encore beaucoup d'octets, mais le cycle eulérien a très bien fonctionné, réduisant le nombre de sommets visités de 96 120 à 33.

Les sommets sont générés en prenant la représentation binaire de 4 bits [0:15]et en considérant le msb comme la coordonnée x et le lsb la coordonnée w.

Edit: La pré-multiplication de toutes les matrices de rotation était un cauchemar, c'est pourquoi je ne l'ai pas utilisé initialement, mais les pré-multiplier par paires a économisé 41 octets. Maintenant, recherchons la combinaison optimale. :) Multiplier les matrices par trois était pire que pas de pré-multiplication du tout, donc je serai satisfait de l'approche par paire.


Sortie:

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

gobelet
la source
Edit: je suis stupide. dupé par la même variable partout ... [Êtes-vous sûr de ne pas vouloir la matrice pré-multipliée complète? :) i.imgur.com/nkM6y6g.png]
algmyr
@algmyr Oui, la matrice entièrement multipliée est sortie environ deux fois plus longtemps, si je me souviens bien.
bécher
Cela devrait être plus comme ça, profitez des stupides "simplifications" de Maxima
algmyr
Pour compenser l'échec misérable en mathématiques, voici une version plus golfée de votre code, 330 octets: paste.ee/p/2GRyJ
algmyr
14

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

Utilise mat.ps et G .

Edit: -343 Génération de vecteurs et circuit eulérien à codage binaire appliquévoléemprunté à d'autres réponses. Et appliqué des chaînes de jetons binaires de la bibliothèque G.
Edit: -49 Redéfini sin coset negà des noms plus courts.
Edit: -43 Noms courts définis pour les séquences 0 0 0 1 1 0.
Edit: -9 al (ie. aload) Est plus court que (")@. Factorisé 3 appels à idi(c.- à -d. idiv) Au prix d'un ne rien faire 1 idiv.
Edit: -30 Bloc de définition implicite appliqué de G.
Edit: -10 Quelques séquences supplémentaires utilisées à trois reprises.
Edit: -45 Supprimez les variables i j k l m npour les angles et définissez toujours l'angle actuel car les tfonctions des angles utilisent la valeur de (global)tvariable. Différez l'exécution de la description de code de la matrice de rotation jusqu'à ce que sa tvaleur soit prête.
Modifier: -3 Supprimer <16>$ie. closepath. Et un espace.
Edit: -16 crochets de matrice de facteur de sortie à partir de vecteurs unitaires dans les matrices de rotation ( J K Let M). Réappliquer abandonné mopour modet supour sub.
Modifier: -12 En ligne la fonction de projet et de dessin et supprimer (maintenant vide) le dictionnaire englobant.
Edit: -36 Encodé le circuit (c'est-à-dire les visages ) dans une chaîne.
Modifier: -8 Supprimer la définition du tableau de sommets V. Au lieu de cela, laissez sur la pile etdupcopies de travail selon les besoins (une fois, au début, et de nouveau à la fin de la boucle). De plus, quelques opérateurs de chaînes de jetons binaires ont été traduits en noms abrégés où le BTS n'a donné aucune économie, tout (I)$comme maintenant fora(c.-à-d. forall). if dupourrait être (T8)$, mais if duest clairement un meilleur choix (c'est le golf , pas l' obscurcissement en soi). Effectuez également le scale précédent translate , afin que les coordonnées traduites puissent être 3et 4au lieu de 300et 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)#

Le 3 4et 100dans la première ligne du deuxième bloc sont des paramètres représentant respectivement centre-x, centre-y et échelle du dessin sur la page (les coordonnées centrales sont mises à l'échelle par scale). (300 400) est à peu près le centre du papier de format lettre américain (612 792) en unités PS.

Si vous pouvez à peu près suivre le post-scriptum, les choses bizarres importantes sont le bloc de procédure implicite et les chaînes d'opérateur codées. Comme le montrent les commentaires dans le fichier de travail ci-dessous, chaque ligne du premier bloc est implicitement nommée par A, B, C, etc. Ainsi, par exemple. F E Dproduirait 1 0 0 1 0 0. Pour les chaînes d'opérateur codées, tout ce qui est un argument $ #ou @une séquence d'appels d'opérateur, en utilisant les octets pour sélectionner des opérateurs dans la table des noms de système, PLRM 3ed Annexe F.Ces fonctionnalités et plus sont disponibles pour PostScript avec la bibliothèque G ( inclut désormais également les fonctions mat.ps).

Fichier de travail:

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

Non golfé et légèrement commenté:

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

Certaines de mes sorties sont des images miroir des exemples de la question.

Pour gs -- hc.ps 0 0 0 0 0 0, je reçois:
entrez la description de l'image ici

gs -- hc.ps 0 0 0 0 0 30
entrez la description de l'image ici

gs -- hc.ps 30 0 0 0 0 30
entrez la description de l'image ici

gs -- hc.ps 0 0 0 30 30 30
entrez la description de l'image ici

gs -- hc.ps 45 45 45 0 0 0
entrez la description de l'image ici

gs -- hc.ps 45 45 45 45 45 45
entrez la description de l'image ici

Animation bonus que je viens de faire avec ce programme. Cette image correspond à la séquence de rotation 0 30 60 0 i i , où i varie de 0 à 360 par 2.
entrez la description de l'image ici

luser droog
la source
2
Sensationnel. Une réponse PostScript pour un problème mathématique.
TuxCrafting
@ TùxCräftîñg Il n'y a pas vraiment beaucoup de mathématiques dans cette question tant que vous pouvez facilement multiplier la matrice. Et je veux écrire ce programme depuis que j'ai lu The Armchair Universe d' AK Dewdney .
luser droog
Ajout de nouvelles fonctions à la bibliothèque G. Ne peut pas être utilisé ici, mais il autorise cette version de 307 octets .
luser droog
8

C # + Unity, 1060 845 835 octets

C # ≈ Java

Suppose que cette fonction se trouve dans un script placé sur MainCamera.

Edit:
Merci à @TuukkaX pour les suggestions de sauvegarde de 19 octets enregistrés ~ 200 octets en utilisant le cycle eulérien.

Golfé:

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

Je ne pouvais pas trouver une formule simple pour construire les matrices de rotation ni les "faces" à dessiner, ce qui coûtait beaucoup d'octets pour coder en dur. J'ai emprunté le cycle eulérien à @beaker. De plus, les modules intégrés Unity sont extrêmement verbeux.

Vous pouvez vérifier tous les cas de test en ligne .

Bleu
la source
C'est la première fois que je vois une réponse C # + Unity ici. +1
DanTheMan
Je pense que tout 0.5fpeut être réduit à .5fet 0.01fà .01f. Je pense également que les tableaux entiers peuvent être séparés par une virgule au lieu de dire int[]plusieurs fois.
Yytsi
@Blue Oh, tu as raison! Je n'ai pas utilisé C # depuis un moment, donc je n'étais pas sûr du dernier conseil.
Yytsi
@TuukkaX Ignore mon commentaire précédent, je peux l'utiliser int[,]. Encore merci.
Blue
Vous en avez encore un Vector4(0.5f,0.5f,0.5f,0.5f)qui pourrait être réduit à Vector4(.5f,.5f,.5f,.5f).
Yytsi
6

Javascript ES6, 584 octets

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)

"Non 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

Voyez-le en action (modifié pour tourner en continu):

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 fonction renvoie un objet canvas HTML5, vous devez l'ajouter à la page en faisant document.body.appendChild(f(0,0,0,0,0,0))par exemple.

Actuellement, les rotations sont appliquées dans le désordre, je travaille sur la réorganisation, mais en l'état, cela fait tourner un hypercube correctement.

Dendrobium
la source
Intelligent, il m'a fallu un certain temps pour comprendre ce que vous faisiez avec les transformations matricielles. : D De plus, je ne peux pas faire fonctionner votre extrait de code ... cela me donne une "erreur de script" inutile. en ligne 0.
bécher
@beaker Quel navigateur utilisez-vous? Je l'ai testé sur le dernier Firefox.
Dendrobium
Je suis sur Safari 9.1.1. Permettez-moi d'en essayer un autre.
bécher
1
Oui, Chrome fonctionne très bien.
bécher
1
Safari est de la merde. Ne l'utilisez pas pour vérifier si quelque chose fonctionne.
Patrick Roberts
1

Mathematica, 453 415 octets *

Raccourci en utilisant la visite eulérienne et en nettoyant le tout en une seule instruction sans définir de fonctions dans les variables. Cela rend le code plus lent pour une raison quelconque. Je suppose que Mathematica réévalue les fonctions plusieurs fois maintenant qu'elles ne sont pas stockées dans une 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}}]]]

* Je compte °et ==comme octets simples chacun car ils sont représentés comme un seul caractère dans Mathematica. Je pense que c'est juste car de nombreuses langues utilisent des encodages de caractères étranges.

Non golfé avec des commentaires. L'entrée est codée en dur en haut comme a={30,0,0,0,0,30};. Je n'ai pas compté cela dans mon score.


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

entrez la description de l'image ici

405 10 -14 -8 -9 205

entrez la description de l'image ici

dylnan
la source