Xoay một hypercube


27

Giới thiệu

Một hypercube / tesseract là tương đương 4 chiều của một khối bình thường. Nó được tạo ra bằng cách lấy một mạng lưới hình khối, mở rộng nó sang chiều thứ 3, sau đó - sử dụng chiều thứ 4 - gấp nó thành một hypercube. Về cơ bản, nó là một khối lập phương, trong đó mỗi bên là một khối lập phương.

Để tạo một hypercube, bạn cần 16 vectơ 4d (một vectơ có thành phần xa y, a, a zvà một wthành phần). Các vectơ này như sau:

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

Hypercube có 24 khuôn mặt. Danh sách sau đây chứa tất cả chúng (mỗi nhóm đánh dấu một phần tư):

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

Với tất cả các thông tin này, về mặt kỹ thuật, bạn có một hypercube trong mã. Để xoay cái này, bạn cần 6 ma trận khác nhau cho mỗi mặt phẳng quay, một cho các mặt phẳng YZ, XZ, XY, XW, YW và ZW. Sau khi bạn có mọi ma trận, bạn cần nhân các đỉnh của khối lập phương với chúng.

Các hình ảnh sau đây cho thấy cấu trúc của từng ma trận:

Đối với vòng quay trên mặt phẳng YZ:

Đối với phép quay trên mặt phẳng XZ:

Đối với phép quay trên mặt phẳng XY:

Đối với phép quay trên mặt phẳng XW:

Đối với phép quay trên mặt phẳng YW:

Đối với phép quay trên mặt phẳng ZW:

Các phép quay được áp dụng theo thứ tự này.

Sau khi tất cả điều này, bạn có một hypercube xoay. Bây giờ bạn cần vẽ nó. Bạn nên sử dụng phép chiếu trực giao kết hợp với phép chiếu phối cảnh để gửi (x, y, z, w)tới (2x/(2+z), 2y/(2+z)).

Đầu vào

Đầu vào của bạn là 6 số nguyên từ 0 (bao gồm) và 360 (độc quyền). Chúng đại diện cho các phép quay theo độ trên các mặt phẳng quay khác nhau của hypercube.

Đầu ra

Đầu ra của bạn phải là một hình ảnh duy nhất chứa hypercube. Màn hình có thể là hình ảnh rasterized, hình ảnh vector hoặc nghệ thuật ASCII. Hình ảnh đầu ra phải có ít nhất 100 * 100 pixel và khối lập phương cần chiếm ít nhất 50% màn hình. Bất kỳ định dạng đầu ra hình ảnh mặc định được cho phép.

Các trường hợp thử nghiệm

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

Mở hình ảnh trong một tab mới, để xem chúng ở kích thước đầy đủ.

Quy tắc

  • Quy tắc mặc định được áp dụng
  • Sơ hở tiêu chuẩn bị cấm
  • Mã ngắn nhất tính bằng byte thắng

Tại sao bạn nuke bài khác?
Rɪᴋᴇʀ

@ EᴀsᴛᴇʀʟʏIʀᴋ Tôi đã đăng nó trong cuộc trò chuyện để xem xét lần cuối
Bálint

7
Như tôi đã chỉ ra trong hai lần riêng biệt trong hộp cát, mô tả trình chiếu để hiển thị là không đầy đủ vì nó giả định rằng đối tượng được chiếu là 3 chiều trong khi thực tế, rõ ràng là 4 chiều.
Peter Taylor

2
@luserdroog Tôi nghĩ 'U' phải là 'N'.
cốc

2
@ Bálint Cảm ơn vì thử thách, tôi rất thích nó. Hy vọng chúng tôi sẽ nhận được nhiều câu trả lời và các cách tiếp cận khác nhau. : D
cốc

Câu trả lời:


9

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

Xoay vòng:

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

Các ma trận xoay vòng vẫn tiêu thụ rất nhiều byte, nhưng chu trình Euler đã hoạt động khá tốt, giảm số lượng đỉnh được truy cập từ 96 120 xuống còn 33.

Các đỉnh được tạo bằng cách lấy biểu diễn nhị phân 4 bit [0:15]và coi msb là tọa độ x và lsb tọa độ w.

Chỉnh sửa: Nhân trước tất cả các ma trận xoay là một cơn ác mộng, đó là lý do tại sao tôi không sử dụng nó ban đầu, nhưng nhân trước chúng theo cặp đã lưu được 41 byte. Bây giờ để tìm kiếm sự kết hợp tối ưu. :) Nhân các ma trận với số ba còn tệ hơn là không nhân trước chút nào, vì vậy tôi sẽ hài lòng với cách tiếp cận theo cặp.


Đầu ra:

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)


Chỉnh sửa: Tôi ngu ngốc. bị đánh lừa bởi cùng một biến ở khắp mọi nơi ... [Bạn có chắc chắn bạn không muốn ma trận nhân trước đầy đủ? :) i.imgur.com/nkM6y6g.png]
algmyr

@ achmyr Vâng, ma trận nhân hoàn toàn xuất hiện dài gấp đôi, nếu tôi nhớ chính xác.
cốc

Điều này sẽ giống như vậy, hãy tận hưởng "sự đơn giản hóa" ngu ngốc của Maxima: i.imgur.com/klkXLPf.png
algmyr

Để bù đắp cho sự thất bại thảm hại trong toán học, đây là một phiên bản được mã hóa nhiều hơn của mã của bạn, 330 byte: paste.ee/p/2GRyJ
algmyr

14

Bản thảo 1075 732 683 640 631 601 590 545 542 526 514 478 470

Sử dụng mat.psG .

Chỉnh sửa: -343 Tạo mã hóa nhị phân của vectơ và mạch Eulerăn cắpmượn từ các câu trả lời khác. Và áp dụng chuỗi nhị phân-mã thông báo từ thư viện G.
Chỉnh sửa: -49 Xác định lại sin cosnegđể tên ngắn hơn.
Chỉnh sửa: -43 Xác định tên ngắn cho chuỗi 0 0 0 1 1 0.
Chỉnh sửa: -9 al (tức là. aload) Ngắn hơn (")@. Bao gồm 3 cuộc gọi đến idi(ví dụ. idiv) Với chi phí không làm gì cả 1 idiv.
Chỉnh sửa: -30 Khối định nghĩa ngầm định được áp dụng từ G.
Chỉnh sửa: -10 Một vài chuỗi được sử dụng nhiều hơn ba lần.
Chỉnh sửa: -45 Xóa các biến i j k l m ncho các góc và luôn xác định góc hiện tại tvà các chức năng của các góc sử dụng giá trị của (toàn cầu)tbiến. Trì hoãn việc thực hiện mô tả mã của ma trận xoay vòng cho đến khi tgiá trị của nó sẵn sàng.
Chỉnh sửa: -3 Xóa <16>$tức là. closepath. Và một không gian.
Chỉnh sửa: -16 Dấu ngoặc mảng nhân tố từ các vectơ đơn vị trong ma trận xoay ( J K LM). Áp dụng lại thả mocho modsucho sub.
Chỉnh sửa: -12 Nội tuyến chức năng dự án và vẽ và loại bỏ (bây giờ trống) từ điển kèm theo.
Chỉnh sửa: -36 Đã mã hóa mạch (tức là các mặt ) trong một chuỗi.
Chỉnh sửa: -8 Xóa định nghĩa của mảng đỉnh V. Thay vào đó, để lại trên stack vàdupbản sao làm việc khi cần thiết (một lần, lúc đầu và lần nữa ở cuối vòng lặp). Ngoài ra, đã dịch một vài toán tử từ các chuỗi nhị phân trở lại thành các tên viết tắt mà BTS không tiết kiệm, vì vậy (I)$bây giờ fora(tức là forall). if ducó thể (T8)$, nhưng if durõ ràng là một lựa chọn tốt hơn (đó là golf , không phải là obfuscation per se). Ngoài ra, thực hiện scale trước translate , để tọa độ dịch có thể 34thay vì 300400.

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

Các 3 4100trong dòng đầu tiên của khối thứ hai là các thông số đại diện cho trung tâm-x, trung tâm-y và quy mô, tương ứng, của bản vẽ trên trang (tọa độ trung tâm được thu nhỏ bằng scale). (300.400) gần như là trung tâm của giấy cỡ chữ Hoa Kỳ (612.792) tính theo đơn vị PS.

Nếu bạn có thể theo dõi phần lớn bài viết, thì những điều kỳ lạ quan trọng là khối thủ tục ngầm và chuỗi toán tử được mã hóa. Như được hiển thị bởi các bình luận trong tệp công việc, bên dưới, mỗi dòng của khối đầu tiên được đặt tên ngầm định bởi A, B, C, v.v. F E Dsẽ sản xuất 1 0 0 1 0 0. Đối với các chuỗi toán tử được mã hóa, bất kỳ đối số $ #nào @là hoặc là một chuỗi các lệnh gọi toán tử, sử dụng các byte để chọn các toán tử từ bảng tên hệ thống, PLRM 3ed Phụ lục F. Các tính năng này và nhiều tính năng khác có sẵn cho PostScript với thư viện G ( bây giờ bao gồm các hàm mat.ps quá).

Workfile:

(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 và bình luận nhẹ:

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

Một số kết quả đầu ra của tôi là hình ảnh phản chiếu của các ví dụ của câu hỏi.

gs -- hc.ps 0 0 0 0 0 0, tôi nhận được:
nhập mô tả hình ảnh ở đây

gs -- hc.ps 0 0 0 0 0 30
nhập mô tả hình ảnh ở đây

gs -- hc.ps 30 0 0 0 0 30
nhập mô tả hình ảnh ở đây

gs -- hc.ps 0 0 0 30 30 30
nhập mô tả hình ảnh ở đây

gs -- hc.ps 45 45 45 0 0 0
nhập mô tả hình ảnh ở đây

gs -- hc.ps 45 45 45 45 45 45
nhập mô tả hình ảnh ở đây

Phần thưởng hoạt hình tôi vừa thực hiện với chương trình này. Hình ảnh này tương ứng với chuỗi xoay 0 30 60 0 i i , trong đó i dao động từ 0 đến 360 x 2.
nhập mô tả hình ảnh ở đây


2
Ồ Một câu trả lời PostScript cho một vấn đề toán học.
Thiền vào

@ TùxCräftîñg Thực sự không có nhiều toán học trong câu hỏi này miễn là bạn có thể thực hiện phép nhân ma trận một cách dễ dàng. Và tôi đã muốn viết chương trình này kể từ khi đọc Vũ trụ Ghế bành của AK Dewdney .
kẻ lừa đảo người lái xe

Đã thêm chức năng mới vào thư viện G. Không thể sử dụng ở đây, nhưng nó cho phép phiên bản 307 byte này .
luser droog

8

C # + Thống nhất, 1060 845 835 byte

C # ≈ Java

Giả sử rằng chức năng này là trong một tập lệnh được đặt trên MainCamera.

Chỉnh sửa:
Cảm ơn @TuukkaX về các đề xuất để lưu 19 byte được lưu ~ 200 byte bằng chu trình Euler.

Chơi gôn

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

Dòng mới + thụt lề + Vỏ đầy đủ:

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

Tôi không thể tìm ra một công thức đơn giản để xây dựng các ma trận xoay cũng như "các mặt" cần vẽ, do đó sẽ tốn rất nhiều byte cho mã cứng. Tôi đã mượn chu trình Euler từ @beaker. Ngoài ra, Unity dựng sẵn rất dài dòng.

Bạn có thể xác minh tất cả các trường hợp thử nghiệm trực tuyến .


Đây là lần đầu tiên tôi thấy câu trả lời của C # + Unity trên đây. +1
DanTheMan

Tôi nghĩ rằng tất cả các 0.5fcó thể được giảm xuống .5f0.01fđể .01f. Tôi cũng nghĩ rằng các mảng số nguyên có thể được phân tách bằng dấu phẩy thay vì nói int[]nhiều lần.
Yytsi

@Blue ơi, bạn nói đúng! Không sử dụng C # trong một thời gian nên không chắc chắn về mẹo cuối cùng.
Yytsi

@TuukkaX Bỏ qua bình luận trước đây của tôi, tôi có thể sử dụng int[,]. Tuy nhiên, cảm ơn bạn.
Màu xanh

Bạn vẫn có một Vector4(0.5f,0.5f,0.5f,0.5f)cái có thể được giảm xuống 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

Xem nó trong hành động (sửa đổi để xoay liên tục):

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>

Hàm trả về một đối tượng canvas HTML5, bạn cần thêm nó vào trang bằng cách thực hiện document.body.appendChild(f(0,0,0,0,0,0))chẳng hạn.

Hiện tại, các phép quay được áp dụng không theo thứ tự, tôi đang làm việc sắp xếp lại, nhưng như vậy, nó xoay một hypercube chính xác.


Thông minh, tôi phải mất một thời gian để tìm ra những gì bạn đang làm với các phép biến đổi ma trận. : D Ngoài ra, tôi không thể làm cho đoạn mã của bạn hoạt động ... nó mang lại cho tôi một "lỗi Script" không hữu ích. trong dòng 0.
cốc

@beaker Bạn đang sử dụng trình duyệt nào? Tôi đã thử nó trên Firefox mới nhất.
Dendrobium

Tôi đang dùng Safari 9.1.1. Hãy để tôi thử một cái khác.
cốc

1
Đúng, Chrome hoạt động tốt.
cốc

1
Safari là tào lao. Đừng sử dụng nó để kiểm tra nếu một cái gì đó hoạt động.
Patrick Roberts

1

Toán học, 453 415 byte *

Rút ngắn bằng cách sử dụng chuyến tham quan Euler và làm sạch tất cả thành một câu lệnh duy nhất mà không xác định các hàm trong các biến. Điều này làm cho mã chậm hơn vì một số lý do. Tôi đoán Mathicala đánh giá lại các hàm nhiều lần mà chúng không được lưu trữ trong một biến.

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

* Tôi đang đếm °==từng byte một vì chúng được biểu diễn dưới dạng một ký tự đơn trong Mathicala. Tôi nghĩ điều này là công bằng vì rất nhiều ngôn ngữ sử dụng mã hóa ký tự kỳ lạ.

Ungolfed với ý kiến. Đầu vào được mã hóa cứng ở đầu như a={30,0,0,0,0,30};. Tôi đã không tính điều đó vào điểm số của tôi.


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

nhập mô tả hình ảnh ở đây

405 10 -14 -8 -9 205

nhập mô tả hình ảnh ở đây

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.