Narysuj prostą kostkę


10

Nie mamy ani jednego wyzwania dotyczącego narysowania prawdziwej trójwymiarowej kostki, więc oto:

Wyzwanie

Twoim zadaniem jest narysowanie obróconego sześcianu z perspektywą. Może znajdować się w osobnym oknie lub jako obraz.

Wejście

Wprowadzono 3 oddzielne liczby od 0 do 359,99 ... Przedstawiają obrót wokół osi x, y i z w stopniach.

0 0 0
30 0 40
95 320 12

Wynik

Możesz wyświetlić go w osobnym oknie lub zapisać obraz. Możesz użyć dowolnego rodzaju wyświetlacza (oparty na wektorach, zrasteryzowany itp.).

Edycja: ASCII jest również dozwolony, aby zezwolić na języki gry w golfa z tylko tekstem.

Dane wyjściowe dla grafiki rasteryzowanej lub ASCII muszą wynosić co najmniej 50 * 50 (piksele dla rasteryzacji, znaki dla ASCII)

Dodatkowe informacje

Dodatnia oś Z wskazuje okno, oś X jest pozioma, a oś Y jest pionowa. Zasadniczo standard OpenGL.

Obracanie odbywa się w kierunku przeciwnym do ruchu wskazówek zegara, jeśli spojrzysz na sześcian w kierunku ujemnym określonej osi, np. Patrząc w dół w kierunku osi y.

Kamera powinna znajdować się na osi Z w rozsądnej odległości od sześcianu w ujemnym kierunku Z, sześcian powinien znajdować się w (0; 0; 0). The. sześcian musi być również w pełni widoczny i zajmować co najmniej 50% ramki rysunkowej. Kamera powinna patrzeć w sześcian w kierunku dodatnim.

Obroty sześcianu są stosowane w kolejności x-> y-> z.

Sześcian jest obracany wokół środka, nie porusza się.

Aby rzutować sześcian na przestrzeń 2d, musisz podzielić współrzędne xiy sześcianu z odległością równoległą do osi Z między punktem a kamerą.

Zasady

Biblioteki renderowania są dozwolone, ale wierzchołki muszą być zdefiniowane w kodzie. Brak klasy modelu kostki 3d.

Przypadki testowe

wprowadź opis zdjęcia tutaj


1
Czy to musi być szkielet?
— Rɪᴋᴇʀ

Chcesz załączyć algorytm dla punktów?
— Leaky Nun

3
W jakiej kolejności / kierunkach wykonywane są obroty? Skąd patrzy aparat? Jakiego rodzaju projekcji musimy użyć?
— flawr

6
Ale jak powiedziałem, obroty się nie sprawdzą. Jak już zdefiniowałeś, sześcian zostanie przesunięty poza pole widzenia, jeśli np. Zostanie obrócony wokół osi x. Proszę użyć piaskownicy .
— flawr

6
@ EᴀsᴛᴇʀʟʏIʀᴋ google will tell you the formula. Nie , wyzwania powinny zawierać jak najwięcej materiałów i informacji potrzebnych do ich rozwiązania, zawartych w treści postu . Nie powinienem iść na googling lub na Wikipedię, żeby zacząć rozumieć.
— kot

Odpowiedzi:


2

Buty (rubinowe) 235 231

Wszystko obliczone od zera.

Shoes.app{p,a,b,c=ARGV.map{|j|j.to_f/90}
k=1+i="i".to_c
p=(0..3).map{|j|y,z=(k*i**(j+a)).rect
x,z=(((-1)**j+z*i)*i**b).rect
q=(x+y*i)*i**c
[90*(k+q/(z-4)),90*(k+q/(4+z))]}
4.upto(15){|j|line *(p[j%4][0].rect+p[(j+j/4)%4][1].rect)}}

Zadzwoń z wiersza poleceń np shoes cube3d.rb 0 30 0

Chodzi o to, aby jednocześnie generować / obracać cztery wierzchołki czworościanu w 3D. Następnie, gdy zostaną one zredukowane do 2d, generujemy cztery wierzchołki odwrotnego czworościanu (łącznie 8 wierzchołków to te sześcianu). Daje to 4 pary wierzchołków odpowiadające 4 przekątnym ciała. Wreszcie 2d wierzchołki są połączone liniami: każdy wierzchołek pierwotnego czworościanu musi być połączony z każdym wierzchołkiem odwrotnego czworościanu, tworząc 12 krawędzi i 4 przekątne bryły sześcianu. Kolejność zapewnia, że ​​przekątne korpusu nie zostaną narysowane.

Dane wyjściowe przypadków testowych

Zauważ, że aby zachować spójność z dwoma ostatnimi przypadkami testowymi, obrót wokół osi Z odbywa się zgodnie z ruchem wskazówek zegara od POV przeglądarki. Wydaje się to jednak być sprzeczne ze specyfikacją. Kierunek obrotu można odwrócić, modyfikując *i**c->/i**c

wprowadź opis zdjęcia tutaj

bez golfa

Shoes.app{
  p,a,b,c=ARGV.map{|j|j.to_f/90}   #Throw away first argument (script name) and translate next three to fractions of a right angle.
  k=1+i="i".to_c                   #set up constants i=sqrt(-1) and k=1+i

  p=(0..3).map{|j|                 #build an array p of 4 elements (each element wil be a 2-element array containing the ends of a body diagonal in complex number format)
    y,z=(k*i**(j+a)).rect          #generate 4 sides of square: 1+i,i-1,-1-i,-i+1, rotate about x axis by a, and store in y and z as reals 
    x,z=(((-1)**j+z*i)*i**b).rect  #generate x axis displacements 1,-1,1,-1, rotate x and z about y axis by b, store in x and z as reals
    q=(x+y*i)*i**c                 #rotate x and y about z axis, store result in q as complex number
  [90*(k+q/(z-4)),90*(k+q/(4+z))]} #generate "far" vertex q/(4+z) and "near" vertex q/-(4-z) opposite ends of body diagonal in 2d format.

  4.upto(15){|j|                   #iterate through 12 edges, use rect and + to convert the two complex numbers into a 4 element array for line method
    line *(p[j%4][0].rect+         #cycle through 4 vertices of the "normal" tetrahedron
     p[(j+j/4)%4][1].rect)         #draw to three vertices of the "inverted" tetrahedron. j/4=1,2,3, never 0
  }                                #so the three edges are drawn but the body diagonal is not.
}

Należy pamiętać, że ze względów historycznych w linii 9 stosuje się współczynnik skali 90 (wybrano, aby był taki sam jak 90 stopni w linii 2 dla gry w golfa), ale ostatecznie nie było żadnej przewagi golfowej w korzystaniu z tej konkretnej wartości, więc stała się dowolny wybór.


3

HTML / CSS / JS, 739 bajtów, prawdopodobnie niekonkurencyjny

Ale chciałem tylko pochwalić się transformacjami CSS 3D.


To właściwie wygląda całkiem schludnie. Doświadczyłem wcześniej transformacji CSS3, ale miałem z tym problemy.
— Bálint

Wygląda na to, że obroty są w niewłaściwej kolejności. Powinno to być x, a następnie y. Masz z, a następnie y, a następnie x. @ Bálint może potwierdzić.
— Level River St

@LevelRiverSt Kiedy to napisałem, nie wiedziałem, jaka powinna być kolejność, i nie mogłem tego wypracować na podstawie przypadków testowych, więc dziękuję za aktualizację. Zmieniłem również kierunek obrotu X, więc teraz dopasowuję wszystkie przypadki testowe.
— Neil

Czy nadal możesz podać liczbę bajtów? Nawet jeśli odpowiedzi nie są konkurencyjne, zawsze powinny mieć liczbę bajtów
— Downgoat

@Downgoat Gra w golfa lub bez golfa?
— Neil

0

Klon, 130 + 14 (w trakcie)

with(plots):f:=(X,Y,Z)->plot3d(0,x=0..1,y=0..1,style=contour,tickmarks=[0,0,0],labels=["","",""],axes=boxed,orientation=[Z,-X,Y]);

wprowadź opis zdjęcia tutaj

Wypisuje stałą funkcję w ramce, a następnie używa opcji drukowania do ukrycia znaczników, etykiet i samej funkcji. Dodanie projection=.5do opcji przybliża kamerę, umożliwiając widok perspektywiczny.
Napisałem to, zanim specyfikacje zostały sfinalizowane, a kolejność rotacji jest x, y', z''zamiast x, y, z. Dopóki nie poprawię kątów, oto inne rozwiązanie

POV-Ray, 182

#include"a.txt"
#include"shapes.inc"
camera{location 9*z look_at 0}
light_source{9*z color 1}
object{Wire_Box(<-2,-2,-2>,<2,2,2>,.01,0)texture{pigment{color rgb 1}}rotate<R.x,-R.y,-R.z>}

czyta wejście za pośrednictwem a.txtpliku, który powinien zawierać
#declare R=<xx,yy,zz>;
z xx,yy,zzczym kąty obrotu

wprowadź opis zdjęcia tutaj


1
Tak, za używanie POV-ray, to świetny program. Niestety, reguły mówią teraz, że nie można użyć żadnej klasy kostki 3d.
— mil
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.