Обертайте гіперкуб


27

Вступ

Гіперкуб / тессеракт - це 4 мірний еквівалент нормального куба. Це робиться, беручи кубикову сітку, розширюючи її до 3-го виміру, потім - використовуючи 4-й вимір - складаючи її в гіперкуб. Це в основному куб, де кожна сторона - куб.

Для створення гіперкуба потрібно 16 4d векторів (вектор з компонентами a x, a y, a zі w). Ці вектори такі:

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

Гіперкуб має 24 грані. У наступному списку містяться всі вони (кожна група позначає квадратик):

ABFE, CDHG, BCGF, DAEH, DCBA, FEHG
IJNM, KLPO, JKON, LIMP, LKJI, PMNO
ABJI, DCKL, BCKJ, DAIL, FEMN, GHPO, FGON, EHPM, EAIM, BFNJ, CGOK, HDLP

Маючи всю цю інформацію, ви технічно маєте гіперкуб у коді. Для обертання цього потрібно 6 різних матриць для кожної площини обертання, по одній для площин YZ, XZ, XY, XW, YW і ZW. Після того, як у вас є кожна матриця, вам потрібно помножити вершини куба з ними.

На наступних зображеннях показана структура кожної матриці:

Для обертання на площині YZ:

Для обертання на площині XZ:

Для обертання на площині XY:

Для обертання на площині XW:

Для обертання на площині YW:

Для обертання на площині ZW:

Обертання застосовуються в цьому порядку.

Після всього цього у вас обертається гіперкуб. Тепер вам потрібно намалювати його. Ви повинні використовувати ортогональну проекцію в поєднанні з перспективною проекцією , щоб відправити (x, y, z, w)в (2x/(2+z), 2y/(2+z)).

Вхідні дані

Ваш вхід становить 6 цілих чисел між 0 (включно) і 360 (виключно). Вони представляють обертання в градусах на різних площинах обертання гіперкуба.

Вихідні дані

На виході має бути одне зображення, що містить гіперкуб. Дисплей може бути растризованим зображенням, векторним зображенням або мистецтвом ASCII. Вихідне зображення має бути не менше 100 * 100 пікселів, а куб повинен займати не менше 50% екрана. Дозволений будь-який формат виводу зображення за замовчуванням.

Тестові справи

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

Відкрийте зображення на новій вкладці, щоб побачити їх у повному розмірі.

Правила

  • Діють правила за замовчуванням
  • Стандартні лазівки заборонені
  • Найкоротший код у байтах виграє

Чому ти занурив іншу посаду?
Rɪᴋᴇʀ

@ EᴀsᴛᴇʀʟʏIʀᴋ Я опублікував це в чаті для останнього огляду
Bálint

7
Як я вже два рази зазначав у пісочниці, опис проекції для відображення є неповним, оскільки передбачає, що об'єкт, що проектується, є тривимірним, тоді як він, очевидно, 4-мірний.
Пітер Тейлор

2
@luserdroog Я думаю, що "U" має бути "N".
стакан

2
@ Bálint Дякую за виклик, мені сподобалось. Сподіваємось, ми отримаємо більше відповідей та різні підходи. : D
стакан

Відповіді:


9

Октава, 474 433 429 байт

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

Поворот:

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

Матриці обертання все ще споживають багато байтів, але ейлеровий цикл спрацював досить добре, скоротивши кількість відвідуваних вершин з 96 120 до 33.

Вершини генеруються, беручи 4-бітове бінарне подання [0:15]та вважаючи msb x-координатою, а lsb координатою w.

Редагувати: попереднє множення всіх матриць обертання було кошмаром, тому я не використовував її спочатку, але попередньо помноживши їх на пари, врятував 41 байт. Тепер шукати оптимальне поєднання. :) Помноження матриць на трійки було гірше, ніж взагалі без попереднього множення, тому я буду задоволений парним підходом.


Вихід:

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)

Н (45,45,45,0,0,0)

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

Н (45,45,45,45,45,45)


Редагувати: Я дурний. обдурений однією і тією ж змінною скрізь ... [Ви впевнені, що не хочете повної розмноженої матриці? :) i.imgur.com/nkM6y6g.png]
algmyr

@algmyr Так, повністю помножена матриця вийшла приблизно вдвічі довшою, якщо я правильно пам'ятаю.
стакан

Це повинно більше подобатися, насолоджуйтесь дурними "спрощеннями" Maxima: i.imgur.com/klkXLPf.png
algmyr

Щоб компенсувати невдачу в математиці, ось більш гольф-версія вашого коду, 330 байт: paste.ee/p/2GRyJ
algmyr

14

Постскрипт 1075 рік 732 683 640 631 601 590 545 542 526 514 478 470

Використовує mat.ps і G .

Редагувати: -343 Застосовується покоління векторів та ейлерових ланцюгіввикраденозапозичені з інших відповідей. І застосовано бінарні-маркери-рядки з бібліотеки G.
Редагувати: -49 Перевизначено sin cosта negскоротити назви.
Редагувати: -43 Визначені короткі імена для послідовностей 0 0 0 1 1 0.
Правка: -9 al (тобто aload) коротше, ніж (")@. Факторовані 3 дзвінки idi(тобто idiv) ціною нічого не робити 1 idiv.
Редагувати: -30 Застосований неявний блок визначення від G.
Редагувати: -10 Ще кілька потрійно використаних послідовностей.
Редагувати: -45 Видаліть змінні i j k l m nкути та завжди визначайте поточний кут як, tа функції кутів використовують значення (глобальне)tзмінна. Відкладіть виконання коду-опису матриці обертання, поки його tзначення не буде готове.
Редагувати: -3 Видалити, <16>$тобто. closepath. І простір.
Редагувати: -16 Дужки масиву з факторним виведенням з одиничних векторів у матрицях обертання ( J K Lі M). Повторне подання заявки випало moза modі suза sub.
Редагувати: -12 Увімкніть функцію проекту та малювання та видаліть (тепер порожній) словник, що додається.
Редагувати: -36 Зашифровано схему (тобто грані ) в рядку.
Редагувати: -8 Видалити визначення масиву вершин V. Замість цього залиште на стеці таdupробочі копії за потребою (раз, спочатку та знову в кінці циклу). Крім того, переведено кілька операторів з рядків бінарних токенів назад до скорочених імен, де BTS не дав заощаджень, так (I)$це зараз fora(тобто forall). if duможе бути (T8)$, але if du, безумовно, кращий вибір (це гольф , а не обдумка як така). Також виконайте scale раніше translate , тому перекладені координати можуть бути 3і 4замість, 300і 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)#

3 4І 100в першому рядку другого блоку є параметрами , що представляє центр-х, центрально-у і масштаб, відповідно, на креслення на сторінці (координати центру масштабується scale). (300 400) - це приблизно центр американського паперового формату (612,792) в одиницях PS.

Якщо ви можете приблизно дотримуватися постскрипту, важливими химерними речами є неявна процедура процедури та закодовані рядки оператора. Як показано в коментарях до робочого файлу, кожен рядок першого блоку неявно називається A, B, C тощо. Так, наприклад. F E Dбуде виробляти 1 0 0 1 0 0. Для кодованих рядків оператора все, що є аргументом $ #або @послідовністю викликів оператора, використовуючи байти для вибору операторів з таблиці імен системи, PLRM 3ed Додаток F. Ці функції та інше доступні для PostScript з бібліотекою G ( тепер також входить функції mat.ps).

Файл роботи:

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

Негольфірованний і злегка прокоментував:

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

Деякі з моїх результатів є дзеркальними зображеннями на прикладах запитання.

Бо gs -- hc.ps 0 0 0 0 0 0я отримую:
введіть тут опис зображення

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
введіть тут опис зображення

Бонусна анімація, яку я щойно робив за допомогою цієї програми. Це зображення відповідає послідовності обертання 0 30 60 0 i i , де i становить від 0 до 360 на 2.
введіть тут опис зображення


2
Ого. Відповідь PostScript для математичної задачі.
TuxCrafting

@ TùxCräftîñg Насправді в цьому питанні не так багато математики, якщо ви можете легко розмножувати матрицю. І я хотів написати цю програму з тих пір читання АК Dewdney в кріслі Всесвіту .
luser droog

Додано нові функції до бібліотеки G. Тут не можна використовувати, але це дозволяє ця версія 307 байт .
luser droog

8

C # + Unity, 1060 845 835 байт

C # ≈ Java

Припускає, що ця функція знаходиться в сценарії, розміщеному на MainCamera.

Редагувати:
Завдяки @TuukkaX за пропозиції зберегти 19 байт Збережено ~ 200 байт за допомогою циклу Ейлерова.

Гольф:

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

Нові рядки + відступ + Повна оболонка:

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

Я не міг розібрати просту формулу для побудови матриць обертання, ані "граней", які можна намалювати, так що це коштувало багато байтів для жорсткого коду. Я запозичив ейлеровий цикл у @beaker. Також вбудовані модулі Unity надзвичайно багатослівні.

Ви можете перевірити всі тестові випадки в Інтернеті .


Це перший раз, коли я бачив тут відповідь C # + Unity. +1
DanTheMan

Я думаю, що все 0.5fможна звести до .5fі 0.01fдо .01f. Я також думаю, що цілі масиви можна розділити комою, а не вимовляти int[]кілька разів.
Yytsi

@Blue О, ти маєш рацію! Не використовував C # деякий час, тому не був впевнений в останній підказці.
Yytsi

@TuukkaX Ігноруй мій попередній коментар, я можу використовувати int[,]. Все-таки дякую.
Блакитний

У вас ще є показник, до Vector4(0.5f,0.5f,0.5f,0.5f)якого можна було б звести Vector4(.5f,.5f,.5f,.5f).
Yytsi

6

Javascript ES6, 584 байти

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)

"Безголів":

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

Дивіться це в дії (модифіковане для постійного обертання):

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>

Функція повертає об’єкт полотна HTML5, вам потрібно додати його на сторінку, зробивши, document.body.appendChild(f(0,0,0,0,0,0))наприклад.

Наразі обертання застосовуються поза порядком, я працюю над переупорядкуванням, але як є, він обертає гіперкуб правильно.


Розумний, мені знадобилося певний час, щоб зрозуміти, що ти робиш з перетвореннями матриці. : D Крім того, я не можу змусити ваш фрагмент коду працювати ... це дає мені непомітну "Помилку сценарію". у рядку 0.
стакан

@beaker Який браузер ви використовуєте? Я перевірив це на останньому Firefox.
Дендробіум

Я на Safari 9.1.1. Дозвольте спробувати інший.
стакан

1
Так, Chrome працює чудово.
стакан

1
Сафарі - лайно. Не використовуйте його, щоб перевірити, чи щось працює.
Патрік Робертс

1

Mathematica, 453 415 байт *

Скорочується за допомогою Eulerian tour і очищення все це в єдиний оператор, не визначаючи функції змінних. Це робить код повільнішим з певних причин. Я здогадуюсь, що Mathematica повторно оцінює функції тепер, коли вони не зберігаються у змінній.

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

* Я рахую °і ==по одному байтам кожен, оскільки вони представлені як Mathematica як один символ. Я думаю, що це справедливо, оскільки багато мов використовують дивні кодування символів.

Безголовка з коментарями. Вхід жорстко кодується вгорі як a={30,0,0,0,0,30};. Я не вважав це своїм рахунком.


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

введіть тут опис зображення

405 10 -14 -8 -9 205

введіть тут опис зображення

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.