Initial data commit
This commit is contained in:
parent
72d218235f
commit
f23f22d71c
199087 changed files with 3378941 additions and 0 deletions
2
Task/Draw-a-rotating-cube/00-META.yaml
Normal file
2
Task/Draw-a-rotating-cube/00-META.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
from: http://rosettacode.org/wiki/Draw_a_rotating_cube
|
||||
11
Task/Draw-a-rotating-cube/00-TASK.txt
Normal file
11
Task/Draw-a-rotating-cube/00-TASK.txt
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
;Task
|
||||
Draw a rotating cube.
|
||||
|
||||
It should be oriented with one vertex pointing straight up, and its opposite vertex on the main diagonal (the one farthest away) straight down. It can be solid or wire-frame, and you can use ASCII art if your language doesn't have graphical capabilities. Perspective is optional.
|
||||
<br><br>
|
||||
|
||||
;Related tasks
|
||||
* [[Draw_a_cuboid|Draw a cuboid]]
|
||||
* [[Write_language_name_in_3D_ASCII|write language name in 3D ASCII]]
|
||||
<br><br>
|
||||
|
||||
105
Task/Draw-a-rotating-cube/Ada/draw-a-rotating-cube.ada
Normal file
105
Task/Draw-a-rotating-cube/Ada/draw-a-rotating-cube.ada
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
with Ada.Numerics.Elementary_Functions;
|
||||
|
||||
with SDL.Video.Windows.Makers;
|
||||
with SDL.Video.Renderers.Makers;
|
||||
with SDL.Events.Events;
|
||||
|
||||
procedure Rotating_Cube is
|
||||
|
||||
Width : constant := 500;
|
||||
Height : constant := 500;
|
||||
Offset : constant := 500.0 / 2.0;
|
||||
|
||||
Window : SDL.Video.Windows.Window;
|
||||
Renderer : SDL.Video.Renderers.Renderer;
|
||||
Event : SDL.Events.Events.Events;
|
||||
Quit : Boolean := False;
|
||||
|
||||
type Node_Id is new Natural;
|
||||
type Point_3D is record X, Y, Z : Float; end record;
|
||||
type Edge_Type is record A, B : Node_Id; end record;
|
||||
|
||||
Nodes : array (Node_Id range <>) of Point_3D :=
|
||||
((-100.0, -100.0, -100.0), (-100.0, -100.0, 100.0), (-100.0, 100.0, -100.0),
|
||||
(-100.0, 100.0, 100.0), (100.0, -100.0, -100.0), (100.0, -100.0, 100.0),
|
||||
(100.0, 100.0, -100.0), (100.0, 100.0, 100.0));
|
||||
Edges : constant array (Positive range <>) of Edge_Type :=
|
||||
((0, 1), (1, 3), (3, 2), (2, 0), (4, 5), (5, 7),
|
||||
(7, 6), (6, 4), (0, 4), (1, 5), (2, 6), (3, 7));
|
||||
|
||||
use Ada.Numerics.Elementary_Functions;
|
||||
|
||||
procedure Rotate_Cube (AngleX, AngleY : in Float) is
|
||||
SinX : constant Float := Sin (AngleX);
|
||||
CosX : constant Float := Cos (AngleX);
|
||||
SinY : constant Float := Sin (AngleY);
|
||||
CosY : constant Float := Cos (AngleY);
|
||||
X, Y, Z : Float;
|
||||
begin
|
||||
for Node of Nodes loop
|
||||
X := Node.X;
|
||||
Y := Node.Y;
|
||||
Z := Node.Z;
|
||||
Node.X := X * CosX - Z * SinX;
|
||||
Node.Z := Z * CosX + X * SinX;
|
||||
Z := Node.Z;
|
||||
Node.Y := Y * CosY - Z * SinY;
|
||||
Node.Z := Z * CosY + Y * SinY;
|
||||
end loop;
|
||||
end Rotate_Cube;
|
||||
|
||||
function Poll_Quit return Boolean is
|
||||
use type SDL.Events.Event_Types;
|
||||
begin
|
||||
while SDL.Events.Events.Poll (Event) loop
|
||||
if Event.Common.Event_Type = SDL.Events.Quit then
|
||||
return True;
|
||||
end if;
|
||||
end loop;
|
||||
return False;
|
||||
end Poll_Quit;
|
||||
|
||||
procedure Draw_Cube (Quit : out Boolean) is
|
||||
use SDL.C;
|
||||
Pi : constant := Ada.Numerics.Pi;
|
||||
Xy1, Xy2 : Point_3D;
|
||||
begin
|
||||
Rotate_Cube (Pi / 4.0, Arctan (Sqrt (2.0)));
|
||||
for Frame in 0 .. 359 loop
|
||||
Renderer.Set_Draw_Colour ((0, 0, 0, 255));
|
||||
Renderer.Fill (Rectangle => (0, 0, Width, Height));
|
||||
|
||||
Renderer.Set_Draw_Colour ((0, 220, 0, 255));
|
||||
for Edge of Edges loop
|
||||
Xy1 := Nodes (Edge.A);
|
||||
Xy2 := Nodes (Edge.B);
|
||||
Renderer.Draw (Line => ((int (Xy1.X + Offset), int (Xy1.Y + Offset)),
|
||||
(int (Xy2.X + Offset), int (Xy2.Y + Offset))));
|
||||
end loop;
|
||||
Rotate_Cube (Pi / 180.0, 0.0);
|
||||
Window.Update_Surface;
|
||||
Quit := Poll_Quit;
|
||||
exit when Quit;
|
||||
delay 0.020;
|
||||
end loop;
|
||||
end Draw_Cube;
|
||||
|
||||
begin
|
||||
if not SDL.Initialise (Flags => SDL.Enable_Screen) then
|
||||
return;
|
||||
end if;
|
||||
|
||||
SDL.Video.Windows.Makers.Create (Win => Window,
|
||||
Title => "Rotating cube",
|
||||
Position => SDL.Natural_Coordinates'(X => 10, Y => 10),
|
||||
Size => SDL.Positive_Sizes'(Width, Height),
|
||||
Flags => 0);
|
||||
SDL.Video.Renderers.Makers.Create (Renderer, Window.Get_Surface);
|
||||
|
||||
while not Quit loop
|
||||
Draw_Cube (Quit);
|
||||
end loop;
|
||||
|
||||
Window.Finalize;
|
||||
SDL.Finalise;
|
||||
end Rotating_Cube;
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
#context-free Draw a cube
|
||||
Loop for (i=1, #(i<=3), ++i)
|
||||
Draw a line (size_2, {size_2} Minus(scale_zoff), [i] Get 'x',\
|
||||
{size_2} Minus(scale x zoff) )
|
||||
Draw a line (size_2, {size_2} Plus(scale_zoff), [{7}Minus(i)] Get 'x' ,\
|
||||
{size_2} Plus(scale x zoff) )
|
||||
Draw a line ([i] Get 'x', {size_2} Minus(scale x zoff),\
|
||||
[Minusone(i) Module(3) Plus(4)] Get 'x', {size_2} Plus(scale x zoff) )
|
||||
Draw a line ([i] Get 'x', {size_2} Minus(scale x zoff), \
|
||||
[{i} Module(3) Plus(4)] Get 'x', {size_2} Plus(scale x zoff) )
|
||||
Next
|
||||
Return\\
|
||||
|
||||
#context-free Delete old cube
|
||||
Color back '0', Draw a cube
|
||||
Return\\
|
||||
|
||||
#context-free Setting values of program
|
||||
Set( Div(M_PI,6), Mul(5,Div(M_PI,6)), Mul(3,M_PI_2), Mul(11,Div(M_PI,6)),\
|
||||
M_PI_2, Mul(7,Div(M_PI,6)) )
|
||||
Append to list 'cylphi'
|
||||
|
||||
/* pre-cálculos */
|
||||
Let ( dt := Div(1,30 ))
|
||||
Let (size_2 := Div( SIZE, 2))
|
||||
Let (scale_zoff := Div( SCALE,zoff))
|
||||
Let (scale x zoff := Mul (SCALE, zoff))
|
||||
Return \\
|
||||
|
||||
#include <jambo.h>
|
||||
|
||||
/*
|
||||
Execute with:
|
||||
$ rxvt -g 250x250 -fn "xft:FantasqueSansMono-Regular:pixelsize=1" -e hopper jm/cubo.jambo
|
||||
*/
|
||||
|
||||
#define SCALE 50
|
||||
#define SIZE 200
|
||||
#define zoff 0.5773502691896257645091487805019574556
|
||||
#define cylr 1.6329931618554520654648560498039275946
|
||||
|
||||
Main
|
||||
Set break
|
||||
theta=0, dtheta=1.5, lasttime=0, dt=0 , timer=0
|
||||
size_2=0, scale_zoff=0, scale x zoff=0, cylphi = {}
|
||||
|
||||
Dim (6) as zeros (x)
|
||||
|
||||
Setting values of program
|
||||
|
||||
Cls
|
||||
/* Draw a cube */
|
||||
Loop while ( Not (Keypressed))
|
||||
Tic(lasttime)
|
||||
Loop for( i=1, #(i<=6), ++i )
|
||||
Add( size_2, Mul( Mul(SCALE,cylr), Cos( [i] Get 'cylphi' Plus 'theta')) )
|
||||
Put 'x'
|
||||
Next
|
||||
Color back '15', Draw a cube
|
||||
|
||||
Loop
|
||||
Timecpu(timer)
|
||||
While ( This 'timer' Compared to 'Add(lasttime, dt)' Is less )
|
||||
|
||||
Let ( theta := Add( theta, Mul( dtheta, Sub(timer, lasttime))))
|
||||
Sleep (0.01)
|
||||
Delete old cube
|
||||
Back
|
||||
End
|
||||
|
||||
Subrutines
|
||||
314
Task/Draw-a-rotating-cube/AutoHotkey/draw-a-rotating-cube.ahk
Normal file
314
Task/Draw-a-rotating-cube/AutoHotkey/draw-a-rotating-cube.ahk
Normal file
|
|
@ -0,0 +1,314 @@
|
|||
; ---------------------------------------------------------------
|
||||
cubeSize := 200
|
||||
deltaX := A_ScreenWidth/2
|
||||
deltaY := A_ScreenHeight/2
|
||||
keyStep := 1
|
||||
mouseStep := 0.2
|
||||
zoomStep := 1.1
|
||||
playSpeed := 1
|
||||
playTimer := 10
|
||||
penSize := 5
|
||||
|
||||
/*
|
||||
HotKeys:
|
||||
!p:: Play/Stop
|
||||
!x:: change play to x-axis
|
||||
!y:: change play to y-axis
|
||||
!z:: change play to z-axis
|
||||
!NumpadAdd:: Zoom in
|
||||
!WheelUp:: Zoom in
|
||||
!NumpadSub:: Zoom out
|
||||
!WheelDown:: Zoom out
|
||||
!LButton:: Rotate X-axis, follow mouse
|
||||
!Up:: Rotate X-axis, CCW
|
||||
!Down:: Rotate X-axis, CW
|
||||
!LButton:: Rotate Y-axis, follow mouse
|
||||
!Right:: Rotate Y-axis, CCW
|
||||
!Left:: Rotate Y-axis, CW
|
||||
!RButton:: Rotate Z-axis, follow mouse
|
||||
!PGUP:: Rotate Z-axis, CW
|
||||
!PGDN:: Rotate Z-axis, CCW
|
||||
+LButton:: Move, follow mouse
|
||||
^esc:: Exitapp
|
||||
*/
|
||||
visualCube =
|
||||
(
|
||||
1+--------+5
|
||||
|\ \
|
||||
| 2+--------+6
|
||||
| | |
|
||||
3+ | 7+ |
|
||||
\ | |
|
||||
4+--------+8
|
||||
)
|
||||
|
||||
SetBatchLines, -1
|
||||
coord := cubeSize/2
|
||||
nodes :=[[-coord, -coord, -coord]
|
||||
, [-coord, -coord, coord]
|
||||
, [-coord, coord, -coord]
|
||||
, [-coord, coord, coord]
|
||||
, [ coord, -coord, -coord]
|
||||
, [ coord, -coord, coord]
|
||||
, [ coord, coord, -coord]
|
||||
, [ coord, coord, coord]]
|
||||
|
||||
edges := [[1, 2], [2, 4], [4, 3], [3, 1]
|
||||
, [5, 6], [6, 8], [8, 7], [7, 5]
|
||||
, [1, 5], [2, 6], [3, 7], [4, 8]]
|
||||
|
||||
faces := [[1,2,4,3], [2,4,8,6], [1,2,6,5], [1,3,7,5], [5,7,8,6], [3,4,8,7]]
|
||||
|
||||
CP := [(nodes[8,1]+nodes[1,1])/2 , (nodes[8,2]+nodes[1,2])/2]
|
||||
|
||||
rotateX3D(-30)
|
||||
rotateY3D(30)
|
||||
Gdip1()
|
||||
draw()
|
||||
return
|
||||
|
||||
; --------------------------------------------------------------
|
||||
draw() {
|
||||
global
|
||||
D := ""
|
||||
for i, n in nodes
|
||||
D .= Sqrt((n.1-CP.1)**2 + (n.2-CP.2)**2) "`t:" i ":`t" n.3 "`n"
|
||||
Sort, D, N
|
||||
p1 := StrSplit(StrSplit(D, "`n", "`r").1, ":").2
|
||||
p2 := StrSplit(StrSplit(D, "`n", "`r").2, ":").2
|
||||
hiddenNode := nodes[p1,3] < nodes[p2,3] ? p1 : p2
|
||||
|
||||
; Draw Faces
|
||||
loop % faces.count() {
|
||||
n1 := faces[A_Index, 1]
|
||||
n2 := faces[A_Index, 2]
|
||||
n3 := faces[A_Index, 3]
|
||||
n4 := faces[A_Index, 4]
|
||||
if (n1 = hiddenNode) || (n2 = hiddenNode) || (n3 = hiddenNode) || (n4 = hiddenNode)
|
||||
continue
|
||||
points := nodes[n1,1]+deltaX "," nodes[n1,2]+deltaY
|
||||
. "|" nodes[n2,1]+deltaX "," nodes[n2,2]+deltaY
|
||||
. "|" nodes[n3,1]+deltaX "," nodes[n3,2]+deltaY
|
||||
. "|" nodes[n4,1]+deltaX "," nodes[n4,2]+deltaY
|
||||
Gdip_FillPolygon(G, FaceBrush%A_Index%, Points)
|
||||
}
|
||||
|
||||
; Draw Node-Numbers
|
||||
;~ loop % nodes.count() {
|
||||
;~ Gdip_FillEllipse(G, pBrush, nodes[A_Index, 1]+deltaX, nodes[A_Index, 2]+deltaY, 4, 4)
|
||||
;~ Options := "x" nodes[A_Index, 1]+deltaX " y" nodes[A_Index, 2]+deltaY "c" TextColor " Bold s" size
|
||||
;~ Gdip_TextToGraphics(G, A_Index, Options, Font)
|
||||
;~ }
|
||||
|
||||
; Draw Edges
|
||||
loop % edges.count() {
|
||||
n1 := edges[A_Index, 1]
|
||||
n2 := edges[A_Index, 2]
|
||||
if (n1 = hiddenNode) || (n2 = hiddenNode)
|
||||
continue
|
||||
Gdip_DrawLine(G, pPen, nodes[n1,1]+deltaX, nodes[n1,2]+deltaY, nodes[n2,1]+deltaX, nodes[n2,2]+deltaY)
|
||||
}
|
||||
UpdateLayeredWindow(hwnd1, hdc, 0, 0, Width, Height)
|
||||
}
|
||||
|
||||
; ---------------------------------------------------------------
|
||||
rotateZ3D(theta) { ; Rotate shape around the z-axis
|
||||
global
|
||||
theta *= 3.141592653589793/180
|
||||
sinTheta := sin(theta)
|
||||
cosTheta := cos(theta)
|
||||
loop % nodes.count() {
|
||||
x := nodes[A_Index,1]
|
||||
y := nodes[A_Index,2]
|
||||
nodes[A_Index,1] := x*cosTheta - y*sinTheta
|
||||
nodes[A_Index,2] := y*cosTheta + x*sinTheta
|
||||
}
|
||||
Redraw()
|
||||
}
|
||||
|
||||
; ---------------------------------------------------------------
|
||||
rotateX3D(theta) { ; Rotate shape around the x-axis
|
||||
global
|
||||
theta *= 3.141592653589793/180
|
||||
sinTheta := sin(theta)
|
||||
cosTheta := cos(theta)
|
||||
loop % nodes.count() {
|
||||
y := nodes[A_Index, 2]
|
||||
z := nodes[A_Index, 3]
|
||||
nodes[A_Index, 2] := y*cosTheta - z*sinTheta
|
||||
nodes[A_Index, 3] := z*cosTheta + y*sinTheta
|
||||
}
|
||||
Redraw()
|
||||
}
|
||||
|
||||
; ---------------------------------------------------------------
|
||||
rotateY3D(theta) { ; Rotate shape around the y-axis
|
||||
global
|
||||
theta *= 3.141592653589793/180
|
||||
sinTheta := sin(theta)
|
||||
cosTheta := cos(theta)
|
||||
loop % nodes.count() {
|
||||
x := nodes[A_Index, 1]
|
||||
z := nodes[A_Index, 3]
|
||||
nodes[A_Index, 1] := x*cosTheta + z*sinTheta
|
||||
nodes[A_Index, 3] := z*cosTheta - x*sinTheta
|
||||
}
|
||||
Redraw()
|
||||
}
|
||||
|
||||
; ---------------------------------------------------------------
|
||||
Redraw(){
|
||||
global
|
||||
gdip2()
|
||||
gdip1()
|
||||
draw()
|
||||
}
|
||||
|
||||
; ---------------------------------------------------------------
|
||||
gdip1(){
|
||||
global
|
||||
If !pToken := Gdip_Startup()
|
||||
{
|
||||
MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
|
||||
ExitApp
|
||||
}
|
||||
OnExit, Exit
|
||||
Width := A_ScreenWidth, Height := A_ScreenHeight
|
||||
Gui, 1: -Caption +E0x80000 +LastFound +OwnDialogs +Owner +AlwaysOnTop
|
||||
Gui, 1: Show, NA
|
||||
hwnd1 := WinExist()
|
||||
hbm := CreateDIBSection(Width, Height)
|
||||
hdc := CreateCompatibleDC()
|
||||
obm := SelectObject(hdc, hbm)
|
||||
G := Gdip_GraphicsFromHDC(hdc)
|
||||
Gdip_SetSmoothingMode(G, 4)
|
||||
TextColor:="FFFFFF00", size := 18
|
||||
Font := "Arial"
|
||||
Gdip_FontFamilyCreate(Font)
|
||||
pBrush := Gdip_BrushCreateSolid(0xFFFF00FF)
|
||||
FaceBrush1 := Gdip_BrushCreateSolid(0xFF0000FF) ; blue
|
||||
FaceBrush2 := Gdip_BrushCreateSolid(0xFFFF0000) ; red
|
||||
FaceBrush3 := Gdip_BrushCreateSolid(0xFFFFFF00) ; yellow
|
||||
FaceBrush4 := Gdip_BrushCreateSolid(0xFFFF7518) ; orange
|
||||
FaceBrush5 := Gdip_BrushCreateSolid(0xFF00FF00) ; lime
|
||||
FaceBrush6 := Gdip_BrushCreateSolid(0xFFFFFFFF) ; white
|
||||
pPen := Gdip_CreatePen(0xFF000000, penSize)
|
||||
}
|
||||
|
||||
; ---------------------------------------------------------------
|
||||
gdip2(){
|
||||
global
|
||||
Gdip_DeleteBrush(pBrush)
|
||||
Gdip_DeletePen(pPen)
|
||||
SelectObject(hdc, obm)
|
||||
DeleteObject(hbm)
|
||||
DeleteDC(hdc)
|
||||
Gdip_DeleteGraphics(G)
|
||||
}
|
||||
; Viewing Hotkeys ----------------------------------------------
|
||||
; HotKey Play/Stop ---------------------------------------------
|
||||
!p::
|
||||
SetTimer, rotateTimer, % (toggle:=!toggle)?playTimer:"off"
|
||||
return
|
||||
|
||||
rotateTimer:
|
||||
axis := !axis ? "Y" : axis
|
||||
rotate%axis%3D(playSpeed)
|
||||
return
|
||||
|
||||
!x::
|
||||
!y::
|
||||
!z::
|
||||
axis := SubStr(A_ThisHotkey, 2, 1)
|
||||
return
|
||||
|
||||
; HotKey Zoom in/out -------------------------------------------
|
||||
!NumpadAdd::
|
||||
!NumpadSub::
|
||||
!WheelUp::
|
||||
!WheelDown::
|
||||
loop % nodes.count()
|
||||
{
|
||||
nodes[A_Index, 1] := nodes[A_Index, 1] * (InStr(A_ThisHotkey, "Add") || InStr(A_ThisHotkey, "Up") ? zoomStep : 1/zoomStep)
|
||||
nodes[A_Index, 2] := nodes[A_Index, 2] * (InStr(A_ThisHotkey, "Add") || InStr(A_ThisHotkey, "Up") ? zoomStep : 1/zoomStep)
|
||||
nodes[A_Index, 3] := nodes[A_Index, 3] * (InStr(A_ThisHotkey, "Add") || InStr(A_ThisHotkey, "Up") ? zoomStep : 1/zoomStep)
|
||||
}
|
||||
Redraw()
|
||||
return
|
||||
|
||||
; HotKey Rotate around Y-Axis ----------------------------------
|
||||
!Right::
|
||||
!Left::
|
||||
rotateY3D(keyStep * (InStr(A_ThisHotkey,"right") ? 1 : -1))
|
||||
return
|
||||
|
||||
; HotKey Rotate around X-Axis ----------------------------------
|
||||
!Up::
|
||||
!Down::
|
||||
rotateX3D(keyStep * (InStr(A_ThisHotkey, "Up") ? 1 : -1))
|
||||
return
|
||||
|
||||
; HotKey Rotate around Z-Axis ----------------------------------
|
||||
!PGUP::
|
||||
!PGDN::
|
||||
rotateZ3D(keyStep * (InStr(A_ThisHotkey, "UP") ? 1 : -1))
|
||||
return
|
||||
|
||||
; HotKey, Rotate around X/Y-Axis -------------------------------
|
||||
!LButton::
|
||||
MouseGetPos, pmouseX, pmouseY
|
||||
while GetKeyState("Lbutton", "P")
|
||||
{
|
||||
MouseGetPos, mouseX, mouseY
|
||||
DeltaMX := mouseX - pmouseX
|
||||
DeltaMY := pmouseY - mouseY
|
||||
if (DeltaMX || DeltaMY)
|
||||
{
|
||||
MouseGetPos, pmouseX, pmouseY
|
||||
rotateY3D(DeltaMX)
|
||||
rotateX3D(DeltaMY)
|
||||
}
|
||||
}
|
||||
return
|
||||
|
||||
; HotKey Rotate around Z-Axis ----------------------------------
|
||||
!RButton::
|
||||
MouseGetPos, pmouseX, pmouseY
|
||||
while GetKeyState("Rbutton", "P")
|
||||
{
|
||||
MouseGetPos, mouseX, mouseY
|
||||
DeltaMX := mouseX - pmouseX
|
||||
DeltaMY := mouseY - pmouseY
|
||||
DeltaMX *= mouseY < deltaY ? mouseStep : -mouseStep
|
||||
DeltaMY *= mouseX > deltaX ? mouseStep : -mouseStep
|
||||
if (DeltaMX || DeltaMY)
|
||||
{
|
||||
MouseGetPos, pmouseX, pmouseY
|
||||
rotateZ3D(DeltaMX)
|
||||
rotateZ3D(DeltaMY)
|
||||
}
|
||||
}
|
||||
return
|
||||
|
||||
; HotKey, Move -------------------------------------------------
|
||||
+LButton::
|
||||
MouseGetPos, pmouseX, pmouseY
|
||||
while GetKeyState("Lbutton", "P")
|
||||
{
|
||||
MouseGetPos, mouseX, mouseY
|
||||
deltaX += mouseX - pmouseX
|
||||
deltaY += mouseY - pmouseY
|
||||
pmouseX := mouseX
|
||||
pmouseY := mouseY
|
||||
Redraw()
|
||||
}
|
||||
return
|
||||
|
||||
; ---------------------------------------------------------------
|
||||
^esc::
|
||||
Exit:
|
||||
gdip2()
|
||||
Gdip_Shutdown(pToken)
|
||||
ExitApp
|
||||
Return
|
||||
; ---------------------------------------------------------------
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
global escala
|
||||
global tam
|
||||
global zoff
|
||||
global cylr
|
||||
|
||||
escala = 50
|
||||
tam = 320
|
||||
zoff = 0.5773502691896257645091487805019574556
|
||||
cylr = 1.6329931618554520654648560498039275946
|
||||
|
||||
clg
|
||||
graphsize tam, tam
|
||||
|
||||
dim x(6)
|
||||
theta = 0.0
|
||||
dtheta = 1.5
|
||||
dt = 1.0 / 30
|
||||
dim cylphi = {PI/6, 5*PI/6, 3*PI/2, 11*PI/6, PI/2, 7*PI/6}
|
||||
|
||||
while key = ""
|
||||
lasttime = msec
|
||||
for i = 0 to 5
|
||||
x[i] = tam/2 + escala *cylr * cos(cylphi[i] + theta)
|
||||
next i
|
||||
clg
|
||||
call drawcube(x)
|
||||
|
||||
while msec < lasttime + dt
|
||||
end while
|
||||
theta += dtheta*(msec-lasttime)
|
||||
pause .4
|
||||
call drawcube(x)
|
||||
end while
|
||||
|
||||
subroutine drawcube(x)
|
||||
for i = 0 to 2
|
||||
color rgb(0,0,0) #black
|
||||
line tam/2, tam/2 - escala / zoff, x[i], tam/2 - escala * zoff
|
||||
line tam/2, tam/2 + escala / zoff, x[5-i], tam/2 + escala * zoff
|
||||
line x[i], tam/2 - escala * zoff, x[(i % 3) + 3], tam/2 + escala * zoff
|
||||
line x[i], tam/2 - escala * zoff, x[((i+1)%3) + 3], tam/2 + escala * zoff
|
||||
next i
|
||||
end subroutine
|
||||
97
Task/Draw-a-rotating-cube/C-sharp/draw-a-rotating-cube.cs
Normal file
97
Task/Draw-a-rotating-cube/C-sharp/draw-a-rotating-cube.cs
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Threading;
|
||||
|
||||
namespace RotatingCube
|
||||
{
|
||||
public partial class Form1 : Form
|
||||
{
|
||||
double[][] nodes = {
|
||||
new double[] {-1, -1, -1}, new double[] {-1, -1, 1}, new double[] {-1, 1, -1},
|
||||
new double[] {-1, 1, 1}, new double[] {1, -1, -1}, new double[] {1, -1, 1},
|
||||
new double[] {1, 1, -1}, new double[] {1, 1, 1} };
|
||||
|
||||
int[][] edges = {
|
||||
new int[] {0, 1}, new int[] {1, 3}, new int[] {3, 2}, new int[] {2, 0}, new int[] {4, 5},
|
||||
new int[] {5, 7}, new int[] {7, 6}, new int[] {6, 4}, new int[] {0, 4}, new int[] {1, 5},
|
||||
new int[] {2, 6}, new int[] {3, 7}};
|
||||
|
||||
public Form1()
|
||||
{
|
||||
Width = Height = 640;
|
||||
StartPosition = FormStartPosition.CenterScreen;
|
||||
SetStyle(
|
||||
ControlStyles.AllPaintingInWmPaint |
|
||||
ControlStyles.UserPaint |
|
||||
ControlStyles.DoubleBuffer,
|
||||
true);
|
||||
|
||||
Scale(100, 100, 100);
|
||||
RotateCuboid(Math.PI / 4, Math.Atan(Math.Sqrt(2)));
|
||||
|
||||
var timer = new DispatcherTimer();
|
||||
timer.Tick += (s, e) => { RotateCuboid(Math.PI / 180, 0); Refresh(); };
|
||||
timer.Interval = new TimeSpan(0, 0, 0, 0, 17);
|
||||
timer.Start();
|
||||
}
|
||||
|
||||
private void RotateCuboid(double angleX, double angleY)
|
||||
{
|
||||
double sinX = Math.Sin(angleX);
|
||||
double cosX = Math.Cos(angleX);
|
||||
|
||||
double sinY = Math.Sin(angleY);
|
||||
double cosY = Math.Cos(angleY);
|
||||
|
||||
foreach (var node in nodes)
|
||||
{
|
||||
double x = node[0];
|
||||
double y = node[1];
|
||||
double z = node[2];
|
||||
|
||||
node[0] = x * cosX - z * sinX;
|
||||
node[2] = z * cosX + x * sinX;
|
||||
|
||||
z = node[2];
|
||||
|
||||
node[1] = y * cosY - z * sinY;
|
||||
node[2] = z * cosY + y * sinY;
|
||||
}
|
||||
}
|
||||
|
||||
private void Scale(int v1, int v2, int v3)
|
||||
{
|
||||
foreach (var item in nodes)
|
||||
{
|
||||
item[0] *= v1;
|
||||
item[1] *= v2;
|
||||
item[2] *= v3;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPaint(PaintEventArgs args)
|
||||
{
|
||||
var g = args.Graphics;
|
||||
g.SmoothingMode = SmoothingMode.HighQuality;
|
||||
g.Clear(Color.White);
|
||||
|
||||
g.TranslateTransform(Width / 2, Height / 2);
|
||||
|
||||
foreach (var edge in edges)
|
||||
{
|
||||
double[] xy1 = nodes[edge[0]];
|
||||
double[] xy2 = nodes[edge[1]];
|
||||
g.DrawLine(Pens.Black, (int)Math.Round(xy1[0]), (int)Math.Round(xy1[1]),
|
||||
(int)Math.Round(xy2[0]), (int)Math.Round(xy2[1]));
|
||||
}
|
||||
|
||||
foreach (var node in nodes)
|
||||
{
|
||||
g.FillEllipse(Brushes.Black, (int)Math.Round(node[0]) - 4,
|
||||
(int)Math.Round(node[1]) - 4, 8, 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
63
Task/Draw-a-rotating-cube/C/draw-a-rotating-cube.c
Normal file
63
Task/Draw-a-rotating-cube/C/draw-a-rotating-cube.c
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#include<gl/freeglut.h>
|
||||
|
||||
double rot = 0;
|
||||
float matCol[] = {1,0,0,0};
|
||||
|
||||
void display(){
|
||||
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||
glPushMatrix();
|
||||
glRotatef(30,1,1,0);
|
||||
glRotatef(rot,0,1,1);
|
||||
glMaterialfv(GL_FRONT,GL_DIFFUSE,matCol);
|
||||
glutWireCube(1);
|
||||
glPopMatrix();
|
||||
glFlush();
|
||||
}
|
||||
|
||||
|
||||
void onIdle(){
|
||||
rot += 0.1;
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
void reshape(int w,int h){
|
||||
float ar = (float) w / (float) h ;
|
||||
|
||||
glViewport(0,0,(GLsizei)w,(GLsizei)h);
|
||||
glTranslatef(0,0,-10);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
gluPerspective(70,(GLfloat)w/(GLfloat)h,1,12);
|
||||
glLoadIdentity();
|
||||
glFrustum ( -1.0, 1.0, -1.0, 1.0, 10.0, 100.0 ) ;
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
}
|
||||
|
||||
void init(){
|
||||
float pos[] = {1,1,1,0};
|
||||
float white[] = {1,1,1,0};
|
||||
float shini[] = {70};
|
||||
|
||||
glClearColor(.5,.5,.5,0);
|
||||
glShadeModel(GL_SMOOTH);
|
||||
glLightfv(GL_LIGHT0,GL_AMBIENT,white);
|
||||
glLightfv(GL_LIGHT0,GL_DIFFUSE,white);
|
||||
glMaterialfv(GL_FRONT,GL_SHININESS,shini);
|
||||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_LIGHT0);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
int main(int argC, char* argV[])
|
||||
{
|
||||
glutInit(&argC,argV);
|
||||
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);
|
||||
glutInitWindowSize(600,500);
|
||||
glutCreateWindow("Rossetta's Rotating Cube");
|
||||
init();
|
||||
glutDisplayFunc(display);
|
||||
glutReshapeFunc(reshape);
|
||||
glutIdleFunc(onIdle);
|
||||
glutMainLoop();
|
||||
return 0;
|
||||
}
|
||||
108
Task/Draw-a-rotating-cube/Delphi/draw-a-rotating-cube-1.delphi
Normal file
108
Task/Draw-a-rotating-cube/Delphi/draw-a-rotating-cube-1.delphi
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
unit main;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Winapi.Windows, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.ExtCtrls,
|
||||
System.Math, System.Classes;
|
||||
|
||||
type
|
||||
TForm1 = class(TForm)
|
||||
tmr1: TTimer;
|
||||
procedure FormCreate(Sender: TObject);
|
||||
procedure tmr1Timer(Sender: TObject);
|
||||
private
|
||||
{ Private declarations }
|
||||
public
|
||||
{ Public declarations }
|
||||
end;
|
||||
|
||||
var
|
||||
Form1: TForm1;
|
||||
nodes: TArray<TArray<double>> = [[-1, -1, -1], [-1, -1, 1], [-1, 1, -1], [-1,
|
||||
1, 1], [1, -1, -1], [1, -1, 1], [1, 1, -1], [1, 1, 1]];
|
||||
edges: TArray<TArray<Integer>> = [[0, 1], [1, 3], [3, 2], [2, 0], [4, 5], [5,
|
||||
7], [7, 6], [6, 4], [0, 4], [1, 5], [2, 6], [3, 7]];
|
||||
|
||||
implementation
|
||||
|
||||
{$R *.dfm}
|
||||
|
||||
procedure Scale(factor: TArray<double>);
|
||||
begin
|
||||
if Length(factor) <> 3 then
|
||||
exit;
|
||||
for var i := 0 to High(nodes) do
|
||||
for var f := 0 to High(factor) do
|
||||
nodes[i][f] := nodes[i][f] * factor[f];
|
||||
end;
|
||||
|
||||
procedure RotateCuboid(angleX, angleY: double);
|
||||
begin
|
||||
var sinX := sin(angleX);
|
||||
var cosX := cos(angleX);
|
||||
var sinY := sin(angleY);
|
||||
var cosY := cos(angleY);
|
||||
|
||||
for var i := 0 to High(nodes) do
|
||||
begin
|
||||
var x := nodes[i][0];
|
||||
var y := nodes[i][1];
|
||||
var z := nodes[i][2];
|
||||
|
||||
nodes[i][0] := x * cosX - z * sinX;
|
||||
nodes[i][2] := z * cosX + x * sinX;
|
||||
|
||||
z := nodes[i][2];
|
||||
|
||||
nodes[i][1] := y * cosY - z * sinY;
|
||||
nodes[i][2] := z * cosY + y * sinY;
|
||||
end;
|
||||
end;
|
||||
|
||||
function DrawCuboid(x, y, w, h: Integer): TBitmap;
|
||||
var
|
||||
offset: TPoint;
|
||||
begin
|
||||
Result := TBitmap.Create;
|
||||
Result.SetSize(w, h);
|
||||
rotateCuboid(PI / 180, 0);
|
||||
offset := TPoint.Create(x, y);
|
||||
with Result.canvas do
|
||||
begin
|
||||
Brush.Color := clBlack;
|
||||
Pen.Color := clWhite;
|
||||
|
||||
Lock;
|
||||
FillRect(ClipRect);
|
||||
|
||||
for var edge in edges do
|
||||
begin
|
||||
var p1 := (nodes[edge[0]]);
|
||||
var p2 := (nodes[edge[1]]);
|
||||
moveTo(trunc(p1[0]) + offset.x, trunc(p1[1]) + offset.y);
|
||||
lineTo(trunc(p2[0]) + offset.x, trunc(p2[1]) + offset.y);
|
||||
end;
|
||||
Unlock;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TForm1.FormCreate(Sender: TObject);
|
||||
begin
|
||||
ClientHeight := 360;
|
||||
ClientWidth := 640;
|
||||
DoubleBuffered := true;
|
||||
scale([100, 100, 100]);
|
||||
rotateCuboid(PI / 4, ArcTan(sqrt(2)));
|
||||
end;
|
||||
|
||||
procedure TForm1.tmr1Timer(Sender: TObject);
|
||||
var
|
||||
buffer: TBitmap;
|
||||
begin
|
||||
buffer := DrawCuboid(ClientWidth div 2, ClientHeight div 2, ClientWidth, ClientHeight);
|
||||
Canvas.Draw(0, 0, buffer);
|
||||
buffer.Free;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
object Form1: TForm1
|
||||
OnCreate = FormCreate
|
||||
object tmr1: TTimer
|
||||
Interval = 17
|
||||
OnTimer = tmr1Timer
|
||||
end
|
||||
end
|
||||
66
Task/Draw-a-rotating-cube/EasyLang/draw-a-rotating-cube.easy
Normal file
66
Task/Draw-a-rotating-cube/EasyLang/draw-a-rotating-cube.easy
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
node[][] = [ [ -1 -1 -1 ] [ -1 -1 1 ] [ -1 1 -1 ] [ -1 1 1 ] [ 1 -1 -1 ] [ 1 -1 1 ] [ 1 1 -1 ] [ 1 1 1 ] ]
|
||||
edge[][] = [ [ 1 2 ] [ 2 4 ] [ 4 3 ] [ 3 1 ] [ 5 6 ] [ 6 8 ] [ 8 7 ] [ 7 5 ] [ 1 5 ] [ 2 6 ] [ 3 7 ] [ 4 8 ] ]
|
||||
#
|
||||
proc scale f . .
|
||||
for i = 1 to len node[][]
|
||||
for d = 1 to 3
|
||||
node[i][d] *= f
|
||||
.
|
||||
.
|
||||
.
|
||||
proc rotate angx angy . .
|
||||
sinx = sin angx
|
||||
cosx = cos angx
|
||||
siny = sin angy
|
||||
cosy = cos angy
|
||||
for i = 1 to len node[][]
|
||||
x = node[i][1]
|
||||
z = node[i][3]
|
||||
node[i][1] = x * cosx - z * sinx
|
||||
y = node[i][2]
|
||||
z = z * cosx + x * sinx
|
||||
node[i][2] = y * cosy - z * siny
|
||||
node[i][3] = z * cosy + y * siny
|
||||
.
|
||||
.
|
||||
len nd[] 3
|
||||
proc draw . .
|
||||
clear
|
||||
m = 999
|
||||
mi = -1
|
||||
for i = 1 to len node[][]
|
||||
if node[i][3] < m
|
||||
m = node[i][3]
|
||||
mi = i
|
||||
.
|
||||
.
|
||||
ix = 1
|
||||
for i = 1 to len edge[][]
|
||||
if edge[i][1] = mi
|
||||
nd[ix] = edge[i][2]
|
||||
ix += 1
|
||||
elif edge[i][2] = mi
|
||||
nd[ix] = edge[i][1]
|
||||
ix += 1
|
||||
.
|
||||
.
|
||||
for ni = 1 to len nd[]
|
||||
for i = 1 to len edge[][]
|
||||
if edge[i][1] = nd[ni] or edge[i][2] = nd[ni]
|
||||
x1 = node[edge[i][1]][1]
|
||||
y1 = node[edge[i][1]][2]
|
||||
x2 = node[edge[i][2]][1]
|
||||
y2 = node[edge[i][2]][2]
|
||||
move x1 + 50 y1 + 50
|
||||
line x2 + 50 y2 + 50
|
||||
.
|
||||
.
|
||||
.
|
||||
.
|
||||
call scale 25
|
||||
call rotate 45 atan sqrt 2
|
||||
call draw
|
||||
on animate
|
||||
call rotate 1 0
|
||||
call draw
|
||||
.
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
#define PI 3.14159265358979323
|
||||
#define SCALE 50
|
||||
#define SIZE 320
|
||||
#define zoff 0.5773502691896257645091487805019574556
|
||||
#define cylr 1.6329931618554520654648560498039275946
|
||||
screenres SIZE, SIZE, 4
|
||||
|
||||
dim as double theta = 0.0, dtheta = 1.5, x(0 to 5), lasttime, dt = 1./30
|
||||
|
||||
dim as double cylphi(0 to 5) = {PI/6, 5*PI/6, 3*PI/2, 11*PI/6, PI/2, 7*PI/6}
|
||||
|
||||
sub drawcube( x() as double, colour as uinteger )
|
||||
for i as uinteger = 0 to 2
|
||||
line (SIZE/2, SIZE/2-SCALE/zoff) - (x(i), SIZE/2-SCALE*zoff), colour
|
||||
line (SIZE/2, SIZE/2+SCALE/zoff) - (x(5-i), SIZE/2+SCALE*zoff), colour
|
||||
line ( x(i), SIZE/2-SCALE*zoff ) - ( x(i mod 3 + 3), SIZE/2+SCALE*zoff ), colour
|
||||
line ( x(i), SIZE/2-SCALE*zoff ) - ( x((i+1) mod 3 + 3), SIZE/2+SCALE*zoff ), colour
|
||||
next i
|
||||
end sub
|
||||
|
||||
while inkey=""
|
||||
lasttime = timer
|
||||
for i as uinteger = 0 to 5
|
||||
x(i) = SIZE/2 + SCALE*cylr*cos(cylphi(i)+theta)
|
||||
next i
|
||||
drawcube x(), 15
|
||||
|
||||
while timer < lasttime + dt
|
||||
wend
|
||||
theta += dtheta*(timer-lasttime)
|
||||
drawcube x(),0
|
||||
wend
|
||||
end
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
include "Tlbx SceneKit.incl"
|
||||
|
||||
_window = 1
|
||||
begin enum output 1
|
||||
_sceneView
|
||||
end enum
|
||||
|
||||
local fn RotatingCubeScene as SCNSceneRef
|
||||
SCNSceneRef scene = fn SCNSceneInit
|
||||
SCNNodeRef rootNode = fn SCNSceneRootNode( scene )
|
||||
|
||||
SCNCameraRef camera = fn SCNCameraInit
|
||||
SCNNodeRef cameraNode = fn SCNNodeInit
|
||||
SCNNodeSetCamera( cameraNode, camera )
|
||||
SCNNodeAddChildNode( rootNode, cameraNode )
|
||||
|
||||
SCNVector3 cameraPos = {0.0, 0.0, 10.0}
|
||||
SCNNodeSetPosition( cameraNode, cameraPos )
|
||||
|
||||
SCNNodeRef lightNode = fn SCNNodeInit
|
||||
SCNLightRef light = fn SCNLightInit
|
||||
SCNLightSetType( light, SCNLightTypeOmni )
|
||||
SCNNodeSetPosition( lightNode, fn SCNVector3Make( 0.0, 10.0, 10.0 ) )
|
||||
SCNNodeAddChildNode( rootNode, lightNode )
|
||||
|
||||
SCNNodeRef ambientLightNode = fn SCNNodeInit
|
||||
SCNLightRef ambientLight = fn SCNLightInit
|
||||
SCNLightSetType( ambientLight, SCNLightTypeAmbient )
|
||||
SCNLightSetColor( ambientLight, fn ColorGray )
|
||||
SCNNodeSetLight( ambientLightNode, ambientLight )
|
||||
SCNNodeAddChildNode( rootNode, ambientLightNode )
|
||||
|
||||
SCNBoxRef boxGeometry = fn SCNBoxInit( 4.0, 4.0, 4.0, 0.0 )
|
||||
SCNNodeRef boxNode = fn SCNNodeWithGeometry( boxGeometry )
|
||||
|
||||
SCNMaterialRef side1 = fn SCNMaterialInit
|
||||
SCNMaterialRef side2 = fn SCNMaterialInit
|
||||
SCNMaterialRef side3 = fn SCNMaterialInit
|
||||
SCNMaterialRef side4 = fn SCNMaterialInit
|
||||
SCNMaterialRef side5 = fn SCNMaterialInit
|
||||
SCNMaterialRef side6 = fn SCNMaterialInit
|
||||
|
||||
SCNMaterialPropertySetContents( fn SCNMaterialMultiply( side1 ), fn ColorBlue )
|
||||
SCNMaterialPropertySetContents( fn SCNMaterialMultiply( side2 ), fn ColorOrange )
|
||||
SCNMaterialPropertySetContents( fn SCNMaterialMultiply( side3 ), fn ColorRed )
|
||||
SCNMaterialPropertySetContents( fn SCNMaterialMultiply( side4 ), fn ColorGreen )
|
||||
SCNMaterialPropertySetContents( fn SCNMaterialMultiply( side5 ), fn ColorYellow )
|
||||
SCNMaterialPropertySetContents( fn SCNMaterialMultiply( side6 ), fn ColorCyan )
|
||||
|
||||
SCNGeometrySetMaterials( boxGeometry, @[side1,side2,side3,side4,side5,side6] )
|
||||
SCNNodeAddChildNode( rootNode, boxNode )
|
||||
SCNActionableRunAction( boxNode, fn SCNActionRepeatActionForever( fn SCNActionRotateByAngle( M_PI, fn SCNVector3Make( 0.0, 25.0, 5.0 ), 5.0 ) ) )
|
||||
end fn = scene
|
||||
|
||||
void local fn BuildWindow
|
||||
window _window, @"Rosetta Code Rotating Cube", ( 0, 0, 600, 600 )
|
||||
scnview _sceneView, fn RotatingCubeScene, ( 0, 0, 600, 600 )
|
||||
SCNViewSetBackgroundColor( _sceneView, fn ColorBlack )
|
||||
SCNViewSetAllowsCameraControl( _sceneView, YES )
|
||||
end fn
|
||||
|
||||
void local fn DoDialog( ev as long, tag as long, wnd as long )
|
||||
select (ev)
|
||||
case _windowWillClose : end
|
||||
end select
|
||||
end fn
|
||||
|
||||
on dialog fn DoDialog
|
||||
|
||||
fn BuildWindow
|
||||
|
||||
HandleEvents
|
||||
105
Task/Draw-a-rotating-cube/Go/draw-a-rotating-cube.go
Normal file
105
Task/Draw-a-rotating-cube/Go/draw-a-rotating-cube.go
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"image"
|
||||
"image/color"
|
||||
"image/gif"
|
||||
"log"
|
||||
"math"
|
||||
"os"
|
||||
)
|
||||
|
||||
const (
|
||||
width, height = 640, 640
|
||||
offset = height / 2
|
||||
fileName = "rotatingCube.gif"
|
||||
)
|
||||
|
||||
var nodes = [][]float64{{-100, -100, -100}, {-100, -100, 100}, {-100, 100, -100}, {-100, 100, 100},
|
||||
{100, -100, -100}, {100, -100, 100}, {100, 100, -100}, {100, 100, 100}}
|
||||
var edges = [][]int{{0, 1}, {1, 3}, {3, 2}, {2, 0}, {4, 5}, {5, 7}, {7, 6},
|
||||
{6, 4}, {0, 4}, {1, 5}, {2, 6}, {3, 7}}
|
||||
|
||||
func main() {
|
||||
var images []*image.Paletted
|
||||
fgCol := color.RGBA{0xff, 0x00, 0xff, 0xff}
|
||||
var palette = []color.Color{color.RGBA{0x00, 0x00, 0x00, 0xff}, fgCol}
|
||||
var delays []int
|
||||
|
||||
imgFile, err := os.Create(fileName)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer imgFile.Close()
|
||||
|
||||
rotateCube(math.Pi/4, math.Atan(math.Sqrt(2)))
|
||||
var frame float64
|
||||
for frame = 0; frame < 360; frame++ {
|
||||
img := image.NewPaletted(image.Rect(0, 0, width, height), palette)
|
||||
images = append(images, img)
|
||||
delays = append(delays, 5)
|
||||
for _, edge := range edges {
|
||||
xy1 := nodes[edge[0]]
|
||||
xy2 := nodes[edge[1]]
|
||||
drawLine(int(xy1[0])+offset, int(xy1[1])+offset, int(xy2[0])+offset, int(xy2[1])+offset, img, fgCol)
|
||||
}
|
||||
rotateCube(math.Pi/180, 0)
|
||||
}
|
||||
if err := gif.EncodeAll(imgFile, &gif.GIF{Image: images, Delay: delays}); err != nil {
|
||||
imgFile.Close()
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func rotateCube(angleX, angleY float64) {
|
||||
sinX := math.Sin(angleX)
|
||||
cosX := math.Cos(angleX)
|
||||
sinY := math.Sin(angleY)
|
||||
cosY := math.Cos(angleY)
|
||||
for _, node := range nodes {
|
||||
x := node[0]
|
||||
y := node[1]
|
||||
z := node[2]
|
||||
node[0] = x*cosX - z*sinX
|
||||
node[2] = z*cosX + x*sinX
|
||||
z = node[2]
|
||||
node[1] = y*cosY - z*sinY
|
||||
node[2] = z*cosY + y*sinY
|
||||
}
|
||||
}
|
||||
|
||||
func drawLine(x0, y0, x1, y1 int, img *image.Paletted, col color.RGBA) {
|
||||
dx := abs(x1 - x0)
|
||||
dy := abs(y1 - y0)
|
||||
var sx, sy int = -1, -1
|
||||
if x0 < x1 {
|
||||
sx = 1
|
||||
}
|
||||
if y0 < y1 {
|
||||
sy = 1
|
||||
}
|
||||
err := dx - dy
|
||||
for {
|
||||
img.Set(x0, y0, col)
|
||||
if x0 == x1 && y0 == y1 {
|
||||
break
|
||||
}
|
||||
e2 := 2 * err
|
||||
if e2 > -dy {
|
||||
err -= dy
|
||||
x0 += sx
|
||||
}
|
||||
if e2 < dx {
|
||||
err += dx
|
||||
y0 += sy
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func abs(x int) int {
|
||||
if x < 0 {
|
||||
return -x
|
||||
}
|
||||
return x
|
||||
}
|
||||
180
Task/Draw-a-rotating-cube/Haskell/draw-a-rotating-cube.hs
Normal file
180
Task/Draw-a-rotating-cube/Haskell/draw-a-rotating-cube.hs
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
{-# LANGUAGE RecursiveDo #-}
|
||||
import Reflex.Dom
|
||||
import Data.Map as DM (Map, lookup, insert, empty, fromList)
|
||||
import Data.Matrix
|
||||
import Data.Time.Clock
|
||||
import Control.Monad.Trans
|
||||
|
||||
size = 500
|
||||
updateFrequency = 0.2
|
||||
rotationStep = pi/10
|
||||
|
||||
data Color = Red | Green | Blue | Yellow | Orange | Purple | Black deriving (Show,Eq,Ord,Enum)
|
||||
|
||||
zRot :: Float -> Matrix Float
|
||||
zRot rotation =
|
||||
let c = cos rotation
|
||||
s = sin rotation
|
||||
in fromLists [[ c, s, 0, 0 ]
|
||||
,[-s, c, 0, 0 ]
|
||||
,[ 0, 0, 1, 0 ]
|
||||
,[ 0, 0, 0, 1 ]
|
||||
]
|
||||
|
||||
xRot :: Float -> Matrix Float
|
||||
xRot rotation =
|
||||
let c = cos rotation
|
||||
s = sin rotation
|
||||
in fromLists [[ 1, 0, 0, 0 ]
|
||||
,[ 0, c, s, 0 ]
|
||||
,[ 0, -s, c, 0 ]
|
||||
,[ 0, 0, 0, 1 ]
|
||||
]
|
||||
|
||||
yRot :: Float -> Matrix Float
|
||||
yRot rotation =
|
||||
let c = cos rotation
|
||||
s = sin rotation
|
||||
in fromLists [[ c, 0, -s, 0 ]
|
||||
,[ 0, 1, 0, 0 ]
|
||||
,[ s, 0, c, 0 ]
|
||||
,[ 0, 0, 0, 1 ]
|
||||
]
|
||||
|
||||
translation :: (Float,Float,Float) -> Matrix Float
|
||||
translation (x,y,z) =
|
||||
fromLists [[ 1, 0, 0, 0 ]
|
||||
,[ 0, 1, 0, 0 ]
|
||||
,[ 0, 0, 1, 0 ]
|
||||
,[ x, y, z, 1 ]
|
||||
]
|
||||
|
||||
scale :: Float -> Matrix Float
|
||||
scale s =
|
||||
fromLists [[ s, 0, 0, 0 ]
|
||||
,[ 0, s, 0, 0 ]
|
||||
,[ 0, 0, s, 0 ]
|
||||
,[ 0, 0, 0, 1 ]
|
||||
]
|
||||
|
||||
-- perspective transformation;
|
||||
perspective :: Matrix Float
|
||||
perspective =
|
||||
fromLists [[ 1, 0, 0, 0 ]
|
||||
,[ 0, 1, 0, 0 ]
|
||||
,[ 0, 0, 1, 1 ]
|
||||
,[ 0, 0, 1, 1 ] ]
|
||||
|
||||
transformPoints :: Matrix Float -> Matrix Float -> [(Float,Float)]
|
||||
transformPoints transform points =
|
||||
let result4d = points `multStd2` transform
|
||||
result2d = (\[x,y,z,w] -> (x/w,y/w)) <$> toLists result4d
|
||||
in result2d
|
||||
|
||||
showRectangle :: MonadWidget t m => Float -> Float -> Float -> Float -> Color -> Dynamic t (Matrix Float) -> m ()
|
||||
showRectangle x0 y0 x1 y1 faceColor dFaceView = do
|
||||
let points = fromLists [[x0,y0,0,1],[x0,y1,0,1],[x1,y1,0,1],[x1,y0,0,1]]
|
||||
pointsToString = concatMap (\(x,y) -> show x ++ ", " ++ show y ++ " ")
|
||||
dAttrs <- mapDyn (\fvk -> DM.fromList [ ("fill", show faceColor)
|
||||
, ("points", pointsToString (transformPoints fvk points))
|
||||
] ) dFaceView
|
||||
elDynAttrSVG "polygon" dAttrs $ return ()
|
||||
|
||||
showUnitSquare :: MonadWidget t m => Color -> Float -> Dynamic t (Matrix Float) -> m ()
|
||||
showUnitSquare faceColor margin dFaceView =
|
||||
showRectangle margin margin (1.0 - margin) (1.0 - margin) faceColor dFaceView
|
||||
|
||||
-- show colored square on top of black square for outline effect
|
||||
showFace :: MonadWidget t m => Color -> Dynamic t (Matrix Float) -> m ()
|
||||
showFace faceColor dFaceView = do
|
||||
showUnitSquare Black 0 dFaceView
|
||||
showUnitSquare faceColor 0.03 dFaceView
|
||||
|
||||
facingCamera :: [Float] -> Matrix Float -> Bool
|
||||
facingCamera viewPoint modelTransform =
|
||||
let cross [x0,y0,z0] [x1,y1,z1] = [y0*z1-z0*y1, z0*x1-x0*z1, x0*y1-y0*x1 ]
|
||||
dot v0 v1 = sum $ zipWith (*) v0 v1
|
||||
vMinus = zipWith (-)
|
||||
|
||||
untransformedPoints = fromLists [ [0,0,0,1] -- lower left
|
||||
, [1,0,0,1] -- lower right
|
||||
, [0,1,0,1] ] -- upper left
|
||||
|
||||
transformedPoints = toLists $ untransformedPoints `multStd2` modelTransform
|
||||
pt00 = take 3 $ head transformedPoints -- transformed lower left
|
||||
pt10 = take 3 $ transformedPoints !! 1 -- transformed upper right
|
||||
pt01 = take 3 $ transformedPoints !! 2 -- transformed upper left
|
||||
|
||||
tVec_10_00 = pt10 `vMinus` pt00 -- lower right to lower left
|
||||
tVec_01_00 = pt01 `vMinus` pt00 -- upper left to lower left
|
||||
perpendicular = tVec_10_00 `cross` tVec_01_00 -- perpendicular to face
|
||||
cameraToPlane = pt00 `vMinus` viewPoint -- line of sight to face
|
||||
|
||||
-- Perpendicular points away from surface;
|
||||
-- Camera vector points towards surface
|
||||
-- Opposed vectors means that face will be visible.
|
||||
in cameraToPlane `dot` perpendicular < 0
|
||||
|
||||
faceView :: Matrix Float -> Matrix Float -> (Bool, Matrix Float)
|
||||
faceView modelOrientation faceOrientation =
|
||||
let modelTransform = translation (-1/2,-1/2,1/2) -- unit square to origin + z offset
|
||||
`multStd2` faceOrientation -- orientation specific to each face
|
||||
`multStd2` scale (1/2) -- shrink cube to fit in view.
|
||||
`multStd2` modelOrientation -- position the entire cube
|
||||
|
||||
|
||||
isFacingCamera = facingCamera [0,0,-1] modelTransform -- backface elimination
|
||||
|
||||
-- combine to get single transform from 2d face to 2d display
|
||||
viewTransform = modelTransform
|
||||
`multStd2` perspective
|
||||
`multStd2` scale size -- scale up to svg box scale
|
||||
`multStd2` translation (size/2, size/2, 0) -- move to center of svg box
|
||||
|
||||
in (isFacingCamera, viewTransform)
|
||||
|
||||
updateFaceViews :: Matrix Float -> Map Color (Matrix Float) -> (Color, Matrix Float) -> Map Color (Matrix Float)
|
||||
updateFaceViews modelOrientation prevCollection (faceColor, faceOrientation) =
|
||||
let (isVisible, newFaceView) = faceView modelOrientation faceOrientation
|
||||
in if isVisible
|
||||
then insert faceColor newFaceView prevCollection
|
||||
else prevCollection
|
||||
|
||||
faceViews :: Matrix Float -> Map Color (Matrix Float)
|
||||
faceViews modelOrientation =
|
||||
foldl (updateFaceViews modelOrientation) empty
|
||||
[ (Purple , xRot (0.0) )
|
||||
, (Yellow , xRot (pi/2) )
|
||||
, (Red , yRot (pi/2) )
|
||||
, (Green , xRot (-pi/2) )
|
||||
, (Blue , yRot (-pi/2) )
|
||||
, (Orange , xRot (pi) )
|
||||
]
|
||||
|
||||
viewModel :: MonadWidget t m => Dynamic t (Matrix Float) -> m ()
|
||||
viewModel modelOrientation = do
|
||||
faceMap <- mapDyn faceViews modelOrientation
|
||||
listWithKey faceMap showFace
|
||||
return ()
|
||||
|
||||
view :: MonadWidget t m => Dynamic t (Matrix Float) -> m ()
|
||||
view modelOrientation = do
|
||||
el "h1" $ text "Rotating Cube"
|
||||
elDynAttrSVG "svg"
|
||||
(constDyn $ DM.fromList [ ("width", show size), ("height", show size) ])
|
||||
$ viewModel modelOrientation
|
||||
|
||||
main = mainWidget $ do
|
||||
let initialOrientation = xRot (pi/4) `multStd2` zRot (atan(1/sqrt(2)))
|
||||
update _ modelOrientation = modelOrientation `multStd2` (yRot (rotationStep) )
|
||||
|
||||
tick <- tickLossy updateFrequency =<< liftIO getCurrentTime
|
||||
rec
|
||||
view modelOrientation
|
||||
modelOrientation <- foldDyn update initialOrientation tick
|
||||
return ()
|
||||
|
||||
-- At end because of Rosetta Code handling of unmatched quotes.
|
||||
elDynAttrSVG a2 a3 a4 = do
|
||||
elDynAttrNS' (Just "http://www.w3.org/2000/svg") a2 a3 a4
|
||||
return ()
|
||||
138
Task/Draw-a-rotating-cube/J/draw-a-rotating-cube.j
Normal file
138
Task/Draw-a-rotating-cube/J/draw-a-rotating-cube.j
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
require'gl2 gles ide/qt/opengl'
|
||||
coinsert'jgl2 jgles qtopengl'
|
||||
|
||||
rotcube=: {{
|
||||
if.0=nc<'sprog'do.return.end.
|
||||
fixosx=. 'opengl';'opengl',('DARWIN'-:UNAME)#' version 4.1'
|
||||
wd 'pc rot; minwh 300 300; cc cube opengl flush' rplc fixosx
|
||||
HD=: ".wd 'qhwndc cube'
|
||||
wd 'ptimer 17; pshow'
|
||||
}}
|
||||
|
||||
rot_close=: {{
|
||||
wd 'ptimer 0'
|
||||
glDeleteBuffers ::0: 2; vbo
|
||||
glDeleteProgram ::0: sprog
|
||||
erase 'sprog'
|
||||
wd 'pclose'
|
||||
}}
|
||||
|
||||
cstr=: {{if.y do.memr y,0 _1 2 else.EMPTY end.}}
|
||||
gstr=: {{cstr>{.glGetString y}}
|
||||
diag=: {{p[echo y,': ',p=.gstr".y}}
|
||||
|
||||
blitf=: {{
|
||||
dat=. 1 fc,y NB. short floats
|
||||
glBindBuffer GL_ARRAY_BUFFER; x{vbo
|
||||
glBufferData GL_ARRAY_BUFFER; (#dat); (symdat<'dat'); GL_STATIC_DRAW
|
||||
}}
|
||||
|
||||
rot_cube_initialize=: {{
|
||||
erase'sprog'
|
||||
if.0=#diag 'GL_VERSION' do.echo 'cannot retrieve GL_VERSION' return.end.
|
||||
diag each;:'GL_VENDOR GL_RENDERER GL_SHADING_LANGUAGE_VERSION'
|
||||
GLSL=:wglGLSL''
|
||||
wglPROC''
|
||||
'err program'=. gl_makeprogram VSRC ;&fixversion FSRC
|
||||
if.#err do. echo 'err: ', err return.end.
|
||||
if. GLSL>120 do.vao=: >{:glGenVertexArrays 1;,_1 end.
|
||||
assert _1~:vertexAttr=: >{.glGetAttribLocation program;'vertex'
|
||||
assert _1~:colorAttr=: >{.glGetAttribLocation program;'color'
|
||||
assert _1~:mvpUni=: >{.glGetUniformLocation program;'mvp'
|
||||
vbo=: >{:glGenBuffers 2;2#_1
|
||||
0 blitf vertexData
|
||||
1 blitf colorData
|
||||
sprog=: program
|
||||
}}
|
||||
|
||||
VSRC=: {{)n
|
||||
#version $version
|
||||
$v_in $highp vec3 vertex;
|
||||
$v_in $lowp vec3 color;
|
||||
$v_out $lowp vec4 v_color;
|
||||
uniform mat4 mvp;
|
||||
void main(void) {
|
||||
gl_Position= mvp * vec4(vertex,1.0);
|
||||
v_color= vec4(color,1.0);
|
||||
}
|
||||
}}
|
||||
|
||||
FSRC=: {{)n
|
||||
#version $version
|
||||
$f_in $lowp vec4 v_color;
|
||||
$fragColor
|
||||
void main(void) {
|
||||
$gl_fragColor= v_color;
|
||||
}
|
||||
}}
|
||||
|
||||
fixversion=: {{
|
||||
NB. cope with host shader language version
|
||||
r=. '$version';GLSL,&":;(GLSL>:300)#(*GLES_VERSION){' core';' es'
|
||||
f1=. GLSL<:120
|
||||
r=.r, '$v_in';f1{'in';'attribute'
|
||||
r=.r, '$v_out';f1{'out';'varying'
|
||||
r=.r, '$f_in';f1{'in';'varying'
|
||||
r=.r, '$highp ';f1#(*GLES_VERSION)#'highp'
|
||||
r=.r, '$lowp ';f1#(*GLES_VERSION)#'lowp'
|
||||
f2=.(330<:GLSL)+.(300<:GLSL)**GLES_VERSION
|
||||
r=.r, '$gl_fragColor';f2{'gl_FragColor';'fragColor'
|
||||
r=.r, '$fragColor';f2#'out vec4 fragColor;'
|
||||
y rplc r
|
||||
}}
|
||||
|
||||
rot_timer=: {{
|
||||
try.
|
||||
gl_sel HD
|
||||
gl_paint''
|
||||
catch.
|
||||
echo 'error in rot_timer',LF,13!:12''
|
||||
wd'ptimer 0'
|
||||
end.
|
||||
}}
|
||||
|
||||
zeroVAttr=: {{
|
||||
glEnableVertexAttribArray y
|
||||
glBindBuffer GL_ARRAY_BUFFER; x{vbo
|
||||
glVertexAttribPointer y; 3; GL_FLOAT; 0; 0; 0
|
||||
}}
|
||||
|
||||
mp=: +/ .*
|
||||
ref=: (gl_Translate 0 0 _10) mp glu_LookAt 0 0 1,0 0 0,1 0 0
|
||||
rot_cube_paint=: {{
|
||||
try.
|
||||
if.nc<'sprog' do.return.end.
|
||||
wh=. gl_qwh''
|
||||
glClear GL_COLOR_BUFFER_BIT+GL_DEPTH_BUFFER_BIT [glClearColor 0 0 0 0+%3
|
||||
glUseProgram sprog
|
||||
glEnable each GL_DEPTH_TEST, GL_CULL_FACE, GL_BLEND
|
||||
glBlendFunc GL_SRC_ALPHA; GL_ONE_MINUS_SRC_ALPHA
|
||||
mvp=. (gl_Rotate (360|60*6!:1''),1 0 0)mp ref mp gl_Perspective 30, (%/wh),1 20
|
||||
glUniformMatrix4fv mvpUni; 1; GL_FALSE; mvp
|
||||
if. GLSL>120 do. glBindVertexArray {.vao end.
|
||||
0 zeroVAttr vertexAttr
|
||||
1 zeroVAttr colorAttr
|
||||
glDrawArrays GL_TRIANGLES; 0; 36
|
||||
glUseProgram 0
|
||||
catch.
|
||||
echo 'error in rot_cube_paint',LF,13!:12''
|
||||
wd'ptimer 0'
|
||||
end.
|
||||
}}
|
||||
|
||||
NB. oriented triangle representation of unit cube
|
||||
unitCube=: #:(0 1 2, 2 1 3)&{@".;._2 {{)n
|
||||
2 3 0 1 NB. unit cube corner indices
|
||||
3 7 1 5 NB. 0: origin
|
||||
4 0 5 1 NB. 1, 2, 4: unit distance along each axis
|
||||
6 2 4 0 NB. 3, 5, 6, 7: combinations of axes
|
||||
7 6 5 4
|
||||
7 3 6 2
|
||||
}}
|
||||
|
||||
NB. orient cube so diagonal is along first axis
|
||||
daxis=: (_1^5 6 e.~i.3 3)*%:6%~2 0 4,2 3 1,:2 3 1
|
||||
vertexData=:(_1^unitCube)mp daxis NB. cube with center at origin
|
||||
colorData=: unitCube NB. corresponding colors
|
||||
|
||||
rotcube''
|
||||
92
Task/Draw-a-rotating-cube/Java/draw-a-rotating-cube.java
Normal file
92
Task/Draw-a-rotating-cube/Java/draw-a-rotating-cube.java
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import static java.lang.Math.*;
|
||||
import javax.swing.*;
|
||||
|
||||
public class RotatingCube extends JPanel {
|
||||
double[][] nodes = {{-1, -1, -1}, {-1, -1, 1}, {-1, 1, -1}, {-1, 1, 1},
|
||||
{1, -1, -1}, {1, -1, 1}, {1, 1, -1}, {1, 1, 1}};
|
||||
|
||||
int[][] edges = {{0, 1}, {1, 3}, {3, 2}, {2, 0}, {4, 5}, {5, 7}, {7, 6},
|
||||
{6, 4}, {0, 4}, {1, 5}, {2, 6}, {3, 7}};
|
||||
|
||||
public RotatingCube() {
|
||||
setPreferredSize(new Dimension(640, 640));
|
||||
setBackground(Color.white);
|
||||
|
||||
scale(100);
|
||||
rotateCube(PI / 4, atan(sqrt(2)));
|
||||
|
||||
new Timer(17, (ActionEvent e) -> {
|
||||
rotateCube(PI / 180, 0);
|
||||
repaint();
|
||||
}).start();
|
||||
}
|
||||
|
||||
final void scale(double s) {
|
||||
for (double[] node : nodes) {
|
||||
node[0] *= s;
|
||||
node[1] *= s;
|
||||
node[2] *= s;
|
||||
}
|
||||
}
|
||||
|
||||
final void rotateCube(double angleX, double angleY) {
|
||||
double sinX = sin(angleX);
|
||||
double cosX = cos(angleX);
|
||||
|
||||
double sinY = sin(angleY);
|
||||
double cosY = cos(angleY);
|
||||
|
||||
for (double[] node : nodes) {
|
||||
double x = node[0];
|
||||
double y = node[1];
|
||||
double z = node[2];
|
||||
|
||||
node[0] = x * cosX - z * sinX;
|
||||
node[2] = z * cosX + x * sinX;
|
||||
|
||||
z = node[2];
|
||||
|
||||
node[1] = y * cosY - z * sinY;
|
||||
node[2] = z * cosY + y * sinY;
|
||||
}
|
||||
}
|
||||
|
||||
void drawCube(Graphics2D g) {
|
||||
g.translate(getWidth() / 2, getHeight() / 2);
|
||||
|
||||
for (int[] edge : edges) {
|
||||
double[] xy1 = nodes[edge[0]];
|
||||
double[] xy2 = nodes[edge[1]];
|
||||
g.drawLine((int) round(xy1[0]), (int) round(xy1[1]),
|
||||
(int) round(xy2[0]), (int) round(xy2[1]));
|
||||
}
|
||||
|
||||
for (double[] node : nodes)
|
||||
g.fillOval((int) round(node[0]) - 4, (int) round(node[1]) - 4, 8, 8);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintComponent(Graphics gg) {
|
||||
super.paintComponent(gg);
|
||||
Graphics2D g = (Graphics2D) gg;
|
||||
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
|
||||
RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
|
||||
drawCube(g);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
JFrame f = new JFrame();
|
||||
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
f.setTitle("Rotating Cube");
|
||||
f.setResizable(false);
|
||||
f.add(new RotatingCube(), BorderLayout.CENTER);
|
||||
f.pack();
|
||||
f.setLocationRelativeTo(null);
|
||||
f.setVisible(true);
|
||||
});
|
||||
}
|
||||
}
|
||||
89
Task/Draw-a-rotating-cube/JavaScript/draw-a-rotating-cube.js
Normal file
89
Task/Draw-a-rotating-cube/JavaScript/draw-a-rotating-cube.js
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<style>
|
||||
canvas {
|
||||
background-color: black;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<canvas></canvas>
|
||||
<script>
|
||||
var canvas = document.querySelector("canvas");
|
||||
canvas.width = window.innerWidth;
|
||||
canvas.height = window.innerHeight;
|
||||
|
||||
var g = canvas.getContext("2d");
|
||||
|
||||
var nodes = [[-1, -1, -1], [-1, -1, 1], [-1, 1, -1], [-1, 1, 1],
|
||||
[1, -1, -1], [1, -1, 1], [1, 1, -1], [1, 1, 1]];
|
||||
|
||||
var edges = [[0, 1], [1, 3], [3, 2], [2, 0], [4, 5], [5, 7], [7, 6],
|
||||
[6, 4], [0, 4], [1, 5], [2, 6], [3, 7]];
|
||||
|
||||
function scale(factor0, factor1, factor2) {
|
||||
nodes.forEach(function (node) {
|
||||
node[0] *= factor0;
|
||||
node[1] *= factor1;
|
||||
node[2] *= factor2;
|
||||
});
|
||||
}
|
||||
|
||||
function rotateCuboid(angleX, angleY) {
|
||||
|
||||
var sinX = Math.sin(angleX);
|
||||
var cosX = Math.cos(angleX);
|
||||
|
||||
var sinY = Math.sin(angleY);
|
||||
var cosY = Math.cos(angleY);
|
||||
|
||||
nodes.forEach(function (node) {
|
||||
var x = node[0];
|
||||
var y = node[1];
|
||||
var z = node[2];
|
||||
|
||||
node[0] = x * cosX - z * sinX;
|
||||
node[2] = z * cosX + x * sinX;
|
||||
|
||||
z = node[2];
|
||||
|
||||
node[1] = y * cosY - z * sinY;
|
||||
node[2] = z * cosY + y * sinY;
|
||||
});
|
||||
}
|
||||
|
||||
function drawCuboid() {
|
||||
g.save();
|
||||
|
||||
g.clearRect(0, 0, canvas.width, canvas.height);
|
||||
g.translate(canvas.width / 2, canvas.height / 2);
|
||||
g.strokeStyle = "#FFFFFF";
|
||||
g.beginPath();
|
||||
|
||||
edges.forEach(function (edge) {
|
||||
var p1 = nodes[edge[0]];
|
||||
var p2 = nodes[edge[1]];
|
||||
g.moveTo(p1[0], p1[1]);
|
||||
g.lineTo(p2[0], p2[1]);
|
||||
});
|
||||
|
||||
g.closePath();
|
||||
g.stroke();
|
||||
|
||||
g.restore();
|
||||
}
|
||||
|
||||
scale(200, 200, 200);
|
||||
rotateCuboid(Math.PI / 4, Math.atan(Math.sqrt(2)));
|
||||
|
||||
setInterval(function() {
|
||||
rotateCuboid(Math.PI / 180, 0);
|
||||
drawCuboid();
|
||||
}, 17);
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
13
Task/Draw-a-rotating-cube/Julia/draw-a-rotating-cube.julia
Normal file
13
Task/Draw-a-rotating-cube/Julia/draw-a-rotating-cube.julia
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
using Makie, LinearAlgebra
|
||||
|
||||
N = 40
|
||||
interval = 0.10
|
||||
|
||||
scene = mesh(FRect3D(Vec3f0(-0.5), Vec3f0(1)), color = :skyblue2)
|
||||
rect = scene[end]
|
||||
|
||||
for rad in 0.5:1/N:8.5
|
||||
arr = normalize([cospi(rad/2), 0, sinpi(rad/2), -sinpi(rad/2)])
|
||||
Makie.rotate!(rect, Quaternionf0(arr[1], arr[2], arr[3], arr[4]))
|
||||
sleep(interval)
|
||||
end
|
||||
101
Task/Draw-a-rotating-cube/Kotlin/draw-a-rotating-cube.kotlin
Normal file
101
Task/Draw-a-rotating-cube/Kotlin/draw-a-rotating-cube.kotlin
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
// version 1.1
|
||||
|
||||
import java.awt.*
|
||||
import javax.swing.*
|
||||
|
||||
class RotatingCube : JPanel() {
|
||||
private val nodes = arrayOf(
|
||||
doubleArrayOf(-1.0, -1.0, -1.0),
|
||||
doubleArrayOf(-1.0, -1.0, 1.0),
|
||||
doubleArrayOf(-1.0, 1.0, -1.0),
|
||||
doubleArrayOf(-1.0, 1.0, 1.0),
|
||||
doubleArrayOf( 1.0, -1.0, -1.0),
|
||||
doubleArrayOf( 1.0, -1.0, 1.0),
|
||||
doubleArrayOf( 1.0, 1.0, -1.0),
|
||||
doubleArrayOf( 1.0, 1.0, 1.0)
|
||||
)
|
||||
private val edges = arrayOf(
|
||||
intArrayOf(0, 1),
|
||||
intArrayOf(1, 3),
|
||||
intArrayOf(3, 2),
|
||||
intArrayOf(2, 0),
|
||||
intArrayOf(4, 5),
|
||||
intArrayOf(5, 7),
|
||||
intArrayOf(7, 6),
|
||||
intArrayOf(6, 4),
|
||||
intArrayOf(0, 4),
|
||||
intArrayOf(1, 5),
|
||||
intArrayOf(2, 6),
|
||||
intArrayOf(3, 7)
|
||||
)
|
||||
|
||||
init {
|
||||
preferredSize = Dimension(640, 640)
|
||||
background = Color.white
|
||||
scale(100.0)
|
||||
rotateCube(Math.PI / 4.0, Math.atan(Math.sqrt(2.0)))
|
||||
Timer(17) {
|
||||
rotateCube(Math.PI / 180.0, 0.0)
|
||||
repaint()
|
||||
}.start()
|
||||
}
|
||||
|
||||
private fun scale(s: Double) {
|
||||
for (node in nodes) {
|
||||
node[0] *= s
|
||||
node[1] *= s
|
||||
node[2] *= s
|
||||
}
|
||||
}
|
||||
|
||||
private fun rotateCube(angleX: Double, angleY: Double) {
|
||||
val sinX = Math.sin(angleX)
|
||||
val cosX = Math.cos(angleX)
|
||||
val sinY = Math.sin(angleY)
|
||||
val cosY = Math.cos(angleY)
|
||||
for (node in nodes) {
|
||||
val x = node[0]
|
||||
val y = node[1]
|
||||
var z = node[2]
|
||||
node[0] = x * cosX - z * sinX
|
||||
node[2] = z * cosX + x * sinX
|
||||
z = node[2]
|
||||
node[1] = y * cosY - z * sinY
|
||||
node[2] = z * cosY + y * sinY
|
||||
}
|
||||
}
|
||||
|
||||
private fun drawCube(g: Graphics2D) {
|
||||
g.translate(width / 2, height / 2)
|
||||
for (edge in edges) {
|
||||
val xy1 = nodes[edge[0]]
|
||||
val xy2 = nodes[edge[1]]
|
||||
g.drawLine(Math.round(xy1[0]).toInt(), Math.round(xy1[1]).toInt(),
|
||||
Math.round(xy2[0]).toInt(), Math.round(xy2[1]).toInt())
|
||||
}
|
||||
for (node in nodes) {
|
||||
g.fillOval(Math.round(node[0]).toInt() - 4, Math.round(node[1]).toInt() - 4, 8, 8)
|
||||
}
|
||||
}
|
||||
|
||||
override public fun paintComponent(gg: Graphics) {
|
||||
super.paintComponent(gg)
|
||||
val g = gg as Graphics2D
|
||||
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
|
||||
g.color = Color.blue
|
||||
drawCube(g)
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
SwingUtilities.invokeLater {
|
||||
val f = JFrame()
|
||||
f.defaultCloseOperation = JFrame.EXIT_ON_CLOSE
|
||||
f.title = "Rotating cube"
|
||||
f.isResizable = false
|
||||
f.add(RotatingCube(), BorderLayout.CENTER)
|
||||
f.pack()
|
||||
f.setLocationRelativeTo(null)
|
||||
f.isVisible = true
|
||||
}
|
||||
}
|
||||
93
Task/Draw-a-rotating-cube/Lua/draw-a-rotating-cube.lua
Normal file
93
Task/Draw-a-rotating-cube/Lua/draw-a-rotating-cube.lua
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
local abs,atan,cos,floor,pi,sin,sqrt = math.abs,math.atan,math.cos,math.floor,math.pi,math.sin,math.sqrt
|
||||
local bitmap = {
|
||||
init = function(self, w, h, value)
|
||||
self.w, self.h, self.pixels = w, h, {}
|
||||
for y=1,h do self.pixels[y]={} end
|
||||
self:clear(value)
|
||||
end,
|
||||
clear = function(self, value)
|
||||
for y=1,self.h do
|
||||
for x=1,self.w do
|
||||
self.pixels[y][x] = value or " "
|
||||
end
|
||||
end
|
||||
end,
|
||||
set = function(self, x, y, value)
|
||||
x,y = floor(x),floor(y)
|
||||
if x>0 and y>0 and x<=self.w and y<=self.h then
|
||||
self.pixels[y][x] = value or "#"
|
||||
end
|
||||
end,
|
||||
line = function(self, x1, y1, x2, y2, c)
|
||||
x1,y1,x2,y2 = floor(x1),floor(y1),floor(x2),floor(y2)
|
||||
local dx, sx = abs(x2-x1), x1<x2 and 1 or -1
|
||||
local dy, sy = abs(y2-y1), y1<y2 and 1 or -1
|
||||
local err = floor((dx>dy and dx or -dy)/2)
|
||||
while(true) do
|
||||
self:set(x1, y1, c)
|
||||
if (x1==x2 and y1==y2) then break end
|
||||
if (err > -dx) then
|
||||
err, x1 = err-dy, x1+sx
|
||||
if (x1==x2 and y1==y2) then
|
||||
self:set(x1, y1, c)
|
||||
break
|
||||
end
|
||||
end
|
||||
if (err < dy) then
|
||||
err, y1 = err+dx, y1+sy
|
||||
end
|
||||
end
|
||||
end,
|
||||
render = function(self)
|
||||
for y=1,self.h do
|
||||
print(table.concat(self.pixels[y]))
|
||||
end
|
||||
end,
|
||||
}
|
||||
screen = {
|
||||
clear = function()
|
||||
os.execute("cls") -- or? os.execute("clear"), or? io.write("\027[2J\027[H"), or etc?
|
||||
end,
|
||||
}
|
||||
local camera = { fl = 2.5 }
|
||||
local L = 0.5
|
||||
local cube = {
|
||||
verts = { {L,L,L}, {L,-L,L}, {-L,-L,L}, {-L,L,L}, {L,L,-L}, {L,-L,-L}, {-L,-L,-L}, {-L,L,-L} },
|
||||
edges = { {1,2}, {2,3}, {3,4}, {4,1}, {5,6}, {6,7}, {7,8}, {8,5}, {1,5}, {2,6}, {3,7}, {4,8} },
|
||||
rotate = function(self, rx, ry)
|
||||
local cx,sx = cos(rx),sin(rx)
|
||||
local cy,sy = cos(ry),sin(ry)
|
||||
for i,v in ipairs(self.verts) do
|
||||
local x,y,z = v[1],v[2],v[3]
|
||||
v[1], v[2], v[3] = x*cx-z*sx, y*cy-x*sx*sy-z*cx*sy, x*sx*cy+y*sy+z*cx*cy
|
||||
end
|
||||
end,
|
||||
}
|
||||
local renderer = {
|
||||
render = function(self, shape, camera, bitmap)
|
||||
local fl = camera.fl
|
||||
local ox, oy = bitmap.w/2, bitmap.h/2
|
||||
local mx, my = bitmap.w/2, bitmap.h/2
|
||||
local rpverts = {}
|
||||
for i,v in ipairs(shape.verts) do
|
||||
local x,y,z = v[1],v[2],v[3]
|
||||
local px = ox + mx * (fl*x)/(fl-z)
|
||||
local py = oy + my * (fl*y)/(fl-z)
|
||||
rpverts[i] = { px,py }
|
||||
end
|
||||
for i,e in ipairs(shape.edges) do
|
||||
local v1, v2 = rpverts[e[1]], rpverts[e[2]]
|
||||
bitmap:line( v1[1], v1[2], v2[1], v2[2], "██" )
|
||||
end
|
||||
end
|
||||
}
|
||||
--
|
||||
bitmap:init(40,40)
|
||||
cube:rotate(pi/4, atan(sqrt(2)))
|
||||
for i=1,60 do
|
||||
cube:rotate(pi/60,0)
|
||||
bitmap:clear("··")
|
||||
renderer:render(cube, camera, bitmap)
|
||||
screen:clear()
|
||||
bitmap:render()
|
||||
end
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
Module Cube3D {
|
||||
form 80, 32
|
||||
smooth on // enable GDI+ smooth lines
|
||||
zoff=0.5773502691896257645091487805019574556@
|
||||
cylr=1.6329931618554520654648560498039275946@
|
||||
oX=scale.x div 2 : oY=scale.y div 2
|
||||
SCALE=min.data(oX, oY)/2*.6
|
||||
gradient 0
|
||||
theta = 0.0 : dtheta = 1.5 : dt = 1000/60
|
||||
ScZof=SCALE/zoff
|
||||
ScZofM=SCALE*zoff
|
||||
dim cylphi(), x()
|
||||
c =(PI/6, 5*PI/6, 3*PI/2, 11*PI/6, PI/2, 7*PI/6) : c*=180/Pi : cylphi()=c // cos() take Degree
|
||||
every DT {
|
||||
if mouse then (oX, oY)=(mouse.x,mouse.y) : dtheta*=1.05 else dtheta = 1.5
|
||||
dim x(6)=oX : for i=0 to 5: x(i) += SCALE*cylr*cos(cylphi(i)+theta):next
|
||||
drawcube() : refresh 100 : IF keypress(32) then exit
|
||||
theta += dtheta : gradient 0, 5: cursor 0,0
|
||||
Print "Press space to exit",,"Press any mouse button to move cube",,Time$(Now)
|
||||
}
|
||||
sub drawcube()
|
||||
for i= 0 to 2
|
||||
move x(i), oY-ScZofM:draw to oX,oY-ScZof, 11
|
||||
move oX,ScZof+oY:draw to x(i),oY-ScZofM, 9
|
||||
move oX,oY+ ScZof:draw to x(5-i),ScZofM+oY
|
||||
move x(i),oY-ScZofM:draw to x(i mod 3 + 3),oY+ScZofM, 15
|
||||
move oX,oY-ScZof:draw to x(i mod 3 + 3), oY+ScZofM, 7
|
||||
move x(i),oY-ScZofM:draw to x((i+1) mod 3 + 3),oY+ScZofM, 13
|
||||
next
|
||||
end sub
|
||||
}
|
||||
Cube3D
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
plots:-display(
|
||||
seq(
|
||||
plots:-display(
|
||||
plottools[cuboid]( [0,0,0], [1,1,1] ),
|
||||
axes=none, scaling=constrained, orientation=[0,45,i] ),
|
||||
i = 0..360, 20 ),
|
||||
insequence=true );
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
Dynamic[
|
||||
Graphics3D[
|
||||
GeometricTransformation[
|
||||
GeometricTransformation[Cuboid[], RotationTransform[Pi/4, {1, 1, 0}]],
|
||||
RotationTransform[Clock[2 Pi], {0, 0, 1}]
|
||||
],
|
||||
Boxed -> False]]
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
import "mathUtil"
|
||||
scale = 250
|
||||
radius = sqrt(scale^2)
|
||||
|
||||
Face = new Sprite
|
||||
Face.image = file.loadImage("/sys/pics/shapes/SquareThin.png")
|
||||
|
||||
clear; gfx.clear color.gray
|
||||
sprites = display(4).sprites
|
||||
|
||||
// build a sprite for each side
|
||||
for i in range(0, 3)
|
||||
sp = new Face
|
||||
sp.x = 480; sp.y = 320
|
||||
yBot = -sin(pi/4)
|
||||
yTop = sin(pi/4)
|
||||
cosAngL = cos(i*pi/2); sinAngL = sin(i*pi/2)
|
||||
cosAngR = cos((i+1)*pi/2); sinAngR = sin((i+1)*pi/2)
|
||||
sp.corners3d = [
|
||||
[cosAngL, yBot, sinAngL], [cosAngR, yBot, sinAngR],
|
||||
[cosAngR, yTop, sinAngR], [cosAngL, yTop, sinAngL] ]
|
||||
sp.color = [color.yellow, color.aqua, color.pink, color.lime][i]
|
||||
sprites.push sp
|
||||
end for
|
||||
// ...and one for the top
|
||||
top = new Face
|
||||
top.x = 480; top.y = 320
|
||||
top.corners3d = []
|
||||
for i in range(0, 3)
|
||||
top.corners3d.push [cos(i*pi/2), sin(pi/4), sin(i*pi/2)]
|
||||
end for
|
||||
sprites.push top
|
||||
|
||||
// Rotate the given [x,y,z] point by some number of degrees
|
||||
// around the Y axis, then project to the screen.
|
||||
rotateAndProject = function(point3d, rotDegrees)
|
||||
radians = rotDegrees * pi/180
|
||||
cosAng = cos(radians); sinAng = sin(radians)
|
||||
// First, rotate around the Y axis in 3D space
|
||||
x = point3d[0] * cosAng - point3d[2] * sinAng
|
||||
y = point3d[1]
|
||||
z = point3d[0] * sinAng + point3d[2] * cosAng
|
||||
// Then, project this to the screen
|
||||
result = [480 + x * scale, 320 + y * scale + z*0]
|
||||
p = (8 - z) / 8 // (perspective factor)
|
||||
return mathUtil.lerp2d(result, [480,800], 1-p)
|
||||
end function
|
||||
|
||||
// Position all the sprites where they should be on screen for the given rotation.
|
||||
positionSprites = function(rotDegrees)
|
||||
for sp in sprites
|
||||
corners = []
|
||||
for i in range(0,3)
|
||||
corners.push rotateAndProject(sp.corners3d[i], rotDegrees)
|
||||
end for
|
||||
sp.setCorners corners
|
||||
if sp == top then continue
|
||||
if corners[1][0] > corners[0][0] then
|
||||
sp.tint = sp.color
|
||||
else
|
||||
sp.tint = color.clear
|
||||
end if
|
||||
end for
|
||||
end function
|
||||
|
||||
// Main program
|
||||
rot = 0
|
||||
while not key.pressed("escape") and not key.pressed("q")
|
||||
yield
|
||||
positionSprites rot
|
||||
rot = rot + 1
|
||||
end while
|
||||
key.clear
|
||||
81
Task/Draw-a-rotating-cube/Nim/draw-a-rotating-cube.nim
Normal file
81
Task/Draw-a-rotating-cube/Nim/draw-a-rotating-cube.nim
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
import math
|
||||
import sdl2
|
||||
|
||||
const
|
||||
Width = 500
|
||||
Height = 500
|
||||
Offset = 500 / 2
|
||||
|
||||
var nodes = [(x: -100.0, y: -100.0, z: -100.0),
|
||||
(x: -100.0, y: -100.0, z: 100.0),
|
||||
(x: -100.0, y: 100.0, z: -100.0),
|
||||
(x: -100.0, y: 100.0, z: 100.0),
|
||||
(x: 100.0, y: -100.0, z: -100.0),
|
||||
(x: 100.0, y: -100.0, z: 100.0),
|
||||
(x: 100.0, y: 100.0, z: -100.0),
|
||||
(x: 100.0, y: 100.0, z: 100.0)]
|
||||
|
||||
const Edges = [(a: 0, b: 1), (a: 1, b: 3), (a: 3, b: 2), (a: 2, b: 0),
|
||||
(a: 4, b: 5), (a: 5, b: 7), (a: 7, b: 6), (a: 6, b: 4),
|
||||
(a: 0, b: 4), (a: 1, b: 5), (a: 2, b: 6), (a: 3, b: 7)]
|
||||
|
||||
var
|
||||
window: WindowPtr
|
||||
renderer: RendererPtr
|
||||
event: Event
|
||||
endSimulation = false
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
|
||||
proc rotateCube(angleX, angleY: float) =
|
||||
let
|
||||
sinX = sin(angleX)
|
||||
cosX = cos(angleX)
|
||||
sinY = sin(angleY)
|
||||
cosY = cos(angleY)
|
||||
|
||||
for node in nodes.mitems:
|
||||
var (x, y, z) = node
|
||||
node.x = x * cosX - z * sinX
|
||||
node.z = z * cosX + x * sinX
|
||||
z = node.z
|
||||
node.y = y * cosY - z * sinY
|
||||
node.z = z * cosY + y * sinY
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
|
||||
proc pollQuit(): bool =
|
||||
while pollEvent(event):
|
||||
if event.kind == QuitEvent:
|
||||
return true
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
|
||||
proc drawCube(): bool =
|
||||
var rect: Rect = (cint(0), cint(0), cint(Width), cint(Height))
|
||||
rotateCube(PI / 4, arctan(sqrt(2.0)))
|
||||
for frame in 0..359:
|
||||
renderer.setDrawColor((0u8, 0u8, 0u8, 255u8))
|
||||
renderer.fillRect(addr(rect))
|
||||
renderer.setDrawColor((0u8, 220u8, 0u8, 255u8))
|
||||
for edge in Edges:
|
||||
let xy1 = nodes[edge.a]
|
||||
let xy2 = nodes[edge.b]
|
||||
renderer.drawLine(cint(xy1.x + Offset), cint(xy1.y + Offset),
|
||||
cint(xy2.x + Offset), cint(xy2.y + Offset))
|
||||
rotateCube(PI / 180, 0)
|
||||
renderer.present()
|
||||
if pollQuit(): return true
|
||||
delay 10
|
||||
|
||||
#———————————————————————————————————————————————————————————————————————————————————————————————————
|
||||
|
||||
if sdl2.init(INIT_EVERYTHING) == SdlError:
|
||||
quit(QuitFailure)
|
||||
|
||||
window = createWindow("Rotating cube", 10, 10, 500, 500, 0)
|
||||
renderer = createRenderer(window, -1, Renderer_Accelerated)
|
||||
|
||||
while not endSimulation:
|
||||
endSimulation = drawCube()
|
||||
window.destroy()
|
||||
122
Task/Draw-a-rotating-cube/Objeck/draw-a-rotating-cube.objeck
Normal file
122
Task/Draw-a-rotating-cube/Objeck/draw-a-rotating-cube.objeck
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
#~
|
||||
Rotating Cube
|
||||
~#
|
||||
|
||||
use Collection.Generic;
|
||||
use Game.SDL2;
|
||||
use Game.Framework;
|
||||
|
||||
class RotatingCube {
|
||||
# game framework
|
||||
@framework : GameFramework;
|
||||
@initialized : Bool;
|
||||
|
||||
@nodes : Float[,];
|
||||
@edges : Int[,];
|
||||
|
||||
New() {
|
||||
@initialized := true;
|
||||
@framework := GameFramework->New(GameConsts->SCREEN_WIDTH, GameConsts->SCREEN_HEIGHT, "Rotating Cube");
|
||||
|
||||
@nodes := [[-100.0, -100.0, -100.0], [-100.0, -100.0, 100.0], [-100.0, 100.0, -100.0],
|
||||
[-100.0, 100.0, 100.0], [100.0, -100.0, -100.0], [100.0, -100.0, 100.0],
|
||||
[100.0, 100.0, -100.0], [100.0, 100.0, 100.0]];
|
||||
|
||||
@edges := [[0, 1], [1, 3], [3, 2], [2, 0], [4, 5], [5, 7],
|
||||
[7, 6], [6, 4], [0, 4], [1, 5], [2, 6], [3, 7]];
|
||||
|
||||
}
|
||||
|
||||
function : Main(args : String[]) ~ Nil {
|
||||
RotatingCube->New()->Play();
|
||||
}
|
||||
|
||||
method : Play() ~ Nil {
|
||||
if(@initialized) {
|
||||
# initialization
|
||||
@framework->SetClearColor(Color->New(0, 0, 0));
|
||||
RotateCube(Float->Pi(), 2.0->SquareRoot()->ArcTan());
|
||||
|
||||
quit := false;
|
||||
e := @framework->GetEvent();
|
||||
while(<>quit) {
|
||||
@framework->FrameStart();
|
||||
@framework->Clear();
|
||||
|
||||
# process input
|
||||
while(e->Poll() <> 0) {
|
||||
if(e->GetType() = EventType->SDL_QUIT) {
|
||||
quit := true;
|
||||
};
|
||||
};
|
||||
|
||||
#draw
|
||||
DrawCube();
|
||||
|
||||
@framework->FrameEnd();
|
||||
|
||||
# render
|
||||
@framework->Show();
|
||||
|
||||
Timer->Delay(200);
|
||||
|
||||
RotateCube (Float->Pi() / 180.0, 0.0);
|
||||
};
|
||||
}
|
||||
else {
|
||||
"--- Error Initializing Environment ---"->ErrorLine();
|
||||
return;
|
||||
};
|
||||
|
||||
leaving {
|
||||
@framework->FreeShapes();
|
||||
};
|
||||
}
|
||||
|
||||
method : RotateCube(angleX : Float, angleY : Float) ~ Nil {
|
||||
sinX := angleX->Sin();
|
||||
cosX := angleX->Cos();
|
||||
|
||||
sinY := angleY->Sin();
|
||||
cosY := angleY->Cos();
|
||||
|
||||
node_sizes := @nodes->Size();
|
||||
size := node_sizes[0];
|
||||
|
||||
for(i := 0; i < size; i += 1;) {
|
||||
x := @nodes[i, 0];
|
||||
y := @nodes[i, 1];
|
||||
z := @nodes[i, 2];
|
||||
|
||||
@nodes[i, 0] := x * cosX - z * sinX;
|
||||
@nodes[i, 2] := z * cosX + x * sinX;
|
||||
|
||||
z := @nodes[i, 2];
|
||||
|
||||
@nodes[i, 1] := y * cosY - z * sinY;
|
||||
@nodes[i, 2] := z * cosY + y * sinY;
|
||||
};
|
||||
}
|
||||
|
||||
method : DrawCube() ~ Nil {
|
||||
edge_sizes := @edges->Size();
|
||||
size := edge_sizes[0];
|
||||
|
||||
@framework->GetRenderer()->SetDrawColor(0, 220, 0, 0);
|
||||
for(i := 0; i < size; i += 1;) {
|
||||
x0y0 := @nodes[@edges[i, 0], 0];
|
||||
x0y1 := @nodes[@edges[i, 0], 1];
|
||||
|
||||
x1y0 := @nodes[@edges[i, 1], 0];
|
||||
x1y1 := @nodes[@edges[i, 1], 1];
|
||||
|
||||
@framework->GetRenderer()->DrawLine(x0y0 + GameConsts->DRAW_OFFSET, x0y1 + GameConsts->DRAW_OFFSET, x1y0 + GameConsts->DRAW_OFFSET, x1y1 + GameConsts->DRAW_OFFSET);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
consts GameConsts {
|
||||
SCREEN_WIDTH := 600,
|
||||
SCREEN_HEIGHT := 600,
|
||||
DRAW_OFFSET := 300
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
% Title "Rotating Cube"
|
||||
% Animated
|
||||
% PlaceCentral
|
||||
uses ConsoleG
|
||||
|
||||
sub main
|
||||
========
|
||||
cls 0.0, 0.5, 0.7
|
||||
shading
|
||||
scale 7
|
||||
pushstate
|
||||
GoldMaterial.act
|
||||
static float ang
|
||||
rotateX ang
|
||||
rotateY ang
|
||||
go cube
|
||||
popstate
|
||||
ang+=.5 : if ang>=360 then ang-=360
|
||||
end sub
|
||||
|
||||
EndScript
|
||||
31
Task/Draw-a-rotating-cube/Perl/draw-a-rotating-cube.pl
Normal file
31
Task/Draw-a-rotating-cube/Perl/draw-a-rotating-cube.pl
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
use strict; # http://www.rosettacode.org/wiki/Draw_a_rotating_cube
|
||||
use warnings;
|
||||
use Tk;
|
||||
use Time::HiRes qw( time );
|
||||
|
||||
my $size = 600;
|
||||
my $wait = int 1000 / 30;
|
||||
my ($height, $width) = ($size, $size * sqrt 8/9);
|
||||
my $mid = $width / 2;
|
||||
my $rot = atan2(0, -1) / 3; # middle corners every 60 degrees
|
||||
|
||||
my $mw = MainWindow->new;
|
||||
my $c = $mw->Canvas(-width => $width, -height => $height)->pack;
|
||||
$c->Tk::bind('<ButtonRelease>' => sub {$mw->destroy}); # click to exit
|
||||
draw();
|
||||
MainLoop;
|
||||
|
||||
sub draw
|
||||
{
|
||||
my $angle = time - $^T; # full rotation every 2*PI seconds
|
||||
my @points = map { $mid + $mid * cos $angle + $_ * $rot,
|
||||
$height * ($_ % 2 + 1) / 3 } 0 .. 5;
|
||||
$c->delete('all');
|
||||
$c->createLine( @points[-12 .. 1], $mid, 0, -width => 5,);
|
||||
$c->createLine( @points[4, 5], $mid, 0, @points[8, 9], -width => 5,);
|
||||
$c->createLine( @points[2, 3], $mid, $height, @points[6, 7], -width => 5,);
|
||||
$c->createLine( $mid, $height, @points[10, 11], -width => 5,);
|
||||
$mw->after($wait, \&draw);
|
||||
}
|
||||
205
Task/Draw-a-rotating-cube/Phix/draw-a-rotating-cube.phix
Normal file
205
Task/Draw-a-rotating-cube/Phix/draw-a-rotating-cube.phix
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #000080;font-style:italic;">--
|
||||
-- demo\rosetta\DrawRotatingCube.exw
|
||||
-- =================================
|
||||
--
|
||||
-- credits: http://petercollingridge.appspot.com/3D-tutorial/rotating-objects
|
||||
-- https://github.com/ssloy/tinyrenderer/wiki/Lesson-4:-Perspective-projection
|
||||
--
|
||||
-- Aside: low CPU usage, at least when using a 30ms timer (33 FPS, which is plenty).
|
||||
--</span>
|
||||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
|
||||
<span style="color: #008080;">include</span> <span style="color: #000000;">pGUI</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
|
||||
|
||||
<span style="color: #008080;">constant</span> <span style="color: #000000;">title</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"Draw a Rotating Cube"</span>
|
||||
<span style="color: #004080;">Ihandle</span> <span style="color: #000000;">dlg</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">canvas</span>
|
||||
<span style="color: #004080;">cdCanvas</span> <span style="color: #000000;">cd_canvas</span>
|
||||
|
||||
<span style="color: #000080;font-style:italic;">--
|
||||
-- First, define 8 corners equidistant from {0,0,0}:
|
||||
--
|
||||
-- 6-----2
|
||||
-- 5-----1 3
|
||||
-- 8-----4
|
||||
--
|
||||
-- ie the right face is 1-2-3-4 clockwise, and the left face
|
||||
-- is 5-6-7-8 counter-clockwise (unless using x-ray vision).
|
||||
-- (since this is not drawing textures, clockwise-ness does
|
||||
-- not matter, as shown by the corrected orange face, but
|
||||
-- it will if you (figure out how to) apply any textures.)
|
||||
-- (a quick (online) study of opengl texture documentation
|
||||
-- should convince you that stuff is best left to opengl.)
|
||||
--</span>
|
||||
<span style="color: #008080;">enum</span> <span style="color: #000000;">X</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">Y</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">Z</span>
|
||||
<span style="color: #008080;">constant</span> <span style="color: #000000;">l</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">100</span>
|
||||
<span style="color: #008080;">constant</span> <span style="color: #000000;">corners</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{+</span><span style="color: #000000;">l</span><span style="color: #0000FF;">,+</span><span style="color: #000000;">l</span><span style="color: #0000FF;">,+</span><span style="color: #000000;">l</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- 1 (front top right)</span>
|
||||
<span style="color: #0000FF;">{+</span><span style="color: #000000;">l</span><span style="color: #0000FF;">,+</span><span style="color: #000000;">l</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">l</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- 2 (back top "right")</span>
|
||||
<span style="color: #0000FF;">{+</span><span style="color: #000000;">l</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">l</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">l</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- 3 (back btm "right")</span>
|
||||
<span style="color: #0000FF;">{+</span><span style="color: #000000;">l</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">l</span><span style="color: #0000FF;">,+</span><span style="color: #000000;">l</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- 4 (front btm right)</span>
|
||||
<span style="color: #0000FF;">{-</span><span style="color: #000000;">l</span><span style="color: #0000FF;">,+</span><span style="color: #000000;">l</span><span style="color: #0000FF;">,+</span><span style="color: #000000;">l</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- 5 (front top left)</span>
|
||||
<span style="color: #0000FF;">{-</span><span style="color: #000000;">l</span><span style="color: #0000FF;">,+</span><span style="color: #000000;">l</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">l</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- 6 (back top "left")</span>
|
||||
<span style="color: #0000FF;">{-</span><span style="color: #000000;">l</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">l</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">l</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- 7 (back btm "left")</span>
|
||||
<span style="color: #0000FF;">{-</span><span style="color: #000000;">l</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">l</span><span style="color: #0000FF;">,+</span><span style="color: #000000;">l</span><span style="color: #0000FF;">}}</span> <span style="color: #000080;font-style:italic;">-- 8 (front btm left)
|
||||
-- I put left/right in quotes for the back face as a reminder
|
||||
-- those match the above diagram, but of course they would be
|
||||
-- swapped were you looking "at" the face/rotated it by 180.</span>
|
||||
|
||||
<span style="color: #008080;">constant</span> <span style="color: #000000;">faces</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #004600;">CD_RED</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- right</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #004600;">CD_YELLOW</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">6</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- top</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #004600;">CD_DARK_GREEN</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">8</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- front</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #004600;">CD_BLUE</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span><span style="color: #000000;">6</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- back</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #004600;">CD_WHITE</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">8</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- bottom
|
||||
-- {CD_ORANGE, 5,6,7,8}} -- left</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #004600;">CD_ORANGE</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span><span style="color: #000000;">6</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">}}</span> <span style="color: #000080;font-style:italic;">-- left
|
||||
|
||||
-- rotation angles, 0..359, on a timer</span>
|
||||
<span style="color: #004080;">atom</span> <span style="color: #000000;">rx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">45</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- initially makes cube like a H</span>
|
||||
<span style="color: #000000;">ry</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">35</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- " " " italic H</span>
|
||||
<span style="color: #000000;">rz</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
|
||||
|
||||
<span style="color: #008080;">constant</span> <span style="color: #000000;">naxes</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">Y</span><span style="color: #0000FF;">,</span><span style="color: #000000;">Z</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- (rotate about the X-axis)</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">X</span><span style="color: #0000FF;">,</span><span style="color: #000000;">Z</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- (rotate about the Y-axis)</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">X</span><span style="color: #0000FF;">,</span><span style="color: #000000;">Y</span><span style="color: #0000FF;">}}</span> <span style="color: #000080;font-style:italic;">-- (rotate about the Z-axis)</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">rotate</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">points</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">angle</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">axis</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000080;font-style:italic;">--
|
||||
-- rotate points by the specified angle about the given axis
|
||||
--</span>
|
||||
<span style="color: #004080;">atom</span> <span style="color: #000000;">radians</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">angle</span><span style="color: #0000FF;">*</span><span style="color: #004600;">CD_DEG2RAD</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">sin_t</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sin</span><span style="color: #0000FF;">(</span><span style="color: #000000;">radians</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #000000;">cos_t</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">cos</span><span style="color: #0000FF;">(</span><span style="color: #000000;">radians</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">nx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ny</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">naxes</span><span style="color: #0000FF;">[</span><span style="color: #000000;">axis</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">points</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">atom</span> <span style="color: #000000;">x</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">points</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">nx</span><span style="color: #0000FF;">],</span>
|
||||
<span style="color: #000000;">y</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">points</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">ny</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #000000;">points</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">nx</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">*</span><span style="color: #000000;">cos_t</span> <span style="color: #0000FF;">-</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">*</span><span style="color: #000000;">sin_t</span>
|
||||
<span style="color: #000000;">points</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">ny</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">*</span><span style="color: #000000;">cos_t</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">*</span><span style="color: #000000;">sin_t</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">points</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">projection</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">points</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000080;font-style:italic;">--
|
||||
-- project points from {0,0,d} onto the perpendicular plane through {0,0,0}
|
||||
--</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">points</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">atom</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">,</span><span style="color: #000000;">z</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">points</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span>
|
||||
<span style="color: #000000;">denom</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">-</span><span style="color: #000000;">z</span><span style="color: #0000FF;">/</span><span style="color: #000000;">d</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">points</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">X</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">/</span><span style="color: #000000;">denom</span>
|
||||
<span style="color: #000000;">points</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">Y</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">/</span><span style="color: #000000;">denom</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">points</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">nearest</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">points</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000080;font-style:italic;">--
|
||||
-- return the index of the nearest point (highest z value)
|
||||
--</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #7060A8;">largest</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">vslice</span><span style="color: #0000FF;">(</span><span style="color: #000000;">points</span><span style="color: #0000FF;">,</span><span style="color: #000000;">Z</span><span style="color: #0000FF;">),</span><span style="color: #004600;">true</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">draw_cube</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">cx</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">cy</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000080;font-style:italic;">-- {cx,cy} is the centre point of the canvas</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">points</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">corners</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">points</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">rotate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">points</span><span style="color: #0000FF;">,</span><span style="color: #000000;">rx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">X</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">points</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">rotate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">points</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ry</span><span style="color: #0000FF;">,</span><span style="color: #000000;">Y</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">points</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">rotate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">points</span><span style="color: #0000FF;">,</span><span style="color: #000000;">rz</span><span style="color: #0000FF;">,</span><span style="color: #000000;">Z</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">points</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">projection</span><span style="color: #0000FF;">(</span><span style="color: #000000;">points</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1000</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">np</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">nearest</span><span style="color: #0000FF;">(</span><span style="color: #000000;">points</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000080;font-style:italic;">--
|
||||
-- find the three faces that contain the nearest point,
|
||||
-- then for each of those faces let diag be the point
|
||||
-- that is diagonally opposite said nearest point, and
|
||||
-- order by/draw those faces furthest diag away first.
|
||||
-- (one or two of them may be completely obscured due
|
||||
-- to the effects of the perspective projection.)
|
||||
-- (you could of course draw all six faces, as long as
|
||||
-- the 3 furthest are draw first/obliterated, which
|
||||
-- is what that commented-out "else" would achieve.)
|
||||
--</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">faceset</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">faces</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">fi</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">faces</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">np</span><span style="color: #0000FF;">,</span><span style="color: #000000;">fi</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- k:=2..5, or 0</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">k</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">diag</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">k</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">2</span> <span style="color: #000080;font-style:italic;">-- {2,3,4,5} --> {4,5,2,3}
|
||||
-- aka swap 2<=>4 & 3<=>5</span>
|
||||
<span style="color: #000000;">diag</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">fi</span><span style="color: #0000FF;">[</span><span style="color: #000000;">diag</span><span style="color: #0000FF;">]</span> <span style="color: #000080;font-style:italic;">-- 1..8, diagonally opp. np</span>
|
||||
<span style="color: #000000;">faceset</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">faceset</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">points</span><span style="color: #0000FF;">[</span><span style="color: #000000;">diag</span><span style="color: #0000FF;">][</span><span style="color: #000000;">Z</span><span style="color: #0000FF;">],</span><span style="color: #000000;">i</span><span style="color: #0000FF;">})</span>
|
||||
<span style="color: #000080;font-style:italic;">-- else
|
||||
-- faceset = append(faceset,{-9999,i})</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #000000;">faceset</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sort</span><span style="color: #0000FF;">(</span><span style="color: #000000;">faceset</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">faceset</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">face</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">faces</span><span style="color: #0000FF;">[</span><span style="color: #000000;">faceset</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]]</span>
|
||||
<span style="color: #7060A8;">cdCanvasSetForeground</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cd_canvas</span><span style="color: #0000FF;">,</span><span style="color: #000000;">face</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span>
|
||||
<span style="color: #000080;font-style:italic;">-- first fill sides (with bresenham edges), then
|
||||
-- redraw edges, but anti-aliased aka smoother</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">modes</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #004600;">CD_FILL</span><span style="color: #0000FF;">,</span><span style="color: #004600;">CD_CLOSED_LINES</span><span style="color: #0000FF;">}</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">modes</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #7060A8;">cdCanvasBegin</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cd_canvas</span><span style="color: #0000FF;">,</span><span style="color: #000000;">modes</span><span style="color: #0000FF;">[</span><span style="color: #000000;">m</span><span style="color: #0000FF;">])</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">fdx</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #000000;">5</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">pt</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">points</span><span style="color: #0000FF;">[</span><span style="color: #000000;">face</span><span style="color: #0000FF;">[</span><span style="color: #000000;">fdx</span><span style="color: #0000FF;">]]</span>
|
||||
<span style="color: #7060A8;">cdCanvasVertex</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cd_canvas</span><span style="color: #0000FF;">,</span><span style="color: #000000;">cx</span><span style="color: #0000FF;">+</span><span style="color: #000000;">pt</span><span style="color: #0000FF;">[</span><span style="color: #000000;">X</span><span style="color: #0000FF;">],</span><span style="color: #000000;">cy</span><span style="color: #0000FF;">-</span><span style="color: #000000;">pt</span><span style="color: #0000FF;">[</span><span style="color: #000000;">Y</span><span style="color: #0000FF;">])</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #7060A8;">cdCanvasEnd</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cd_canvas</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">canvas_action_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000000;">canvas</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">cdCanvasActivate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cd_canvas</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">cdCanvasClear</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cd_canvas</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">w</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">h</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupGetIntInt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"DRAWSIZE"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">draw_cube</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">w</span><span style="color: #0000FF;">/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">h</span><span style="color: #0000FF;">/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">))</span>
|
||||
<span style="color: #7060A8;">cdCanvasFlush</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cd_canvas</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_DEFAULT</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">canvas_map_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000000;">canvas</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">IupGLMakeCurrent</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()=</span><span style="color: #004600;">JS</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">cd_canvas</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">cdCreateCanvas</span><span style="color: #0000FF;">(</span><span style="color: #004600;">CD_IUP</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">canvas</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">else</span>
|
||||
<span style="color: #004080;">atom</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupGetDouble</span><span style="color: #0000FF;">(</span><span style="color: #004600;">NULL</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"SCREENDPI"</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">25.4</span>
|
||||
<span style="color: #000000;">cd_canvas</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">cdCreateCanvas</span><span style="color: #0000FF;">(</span><span style="color: #004600;">CD_GL</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"10x10 %g"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">res</span><span style="color: #0000FF;">})</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #7060A8;">cdCanvasSetBackground</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cd_canvas</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">CD_PARCHMENT</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_DEFAULT</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">canvas_resize_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000080;font-style:italic;">/*canvas*/</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">canvas_width</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">canvas_height</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupGetIntInt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"DRAWSIZE"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">atom</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupGetDouble</span><span style="color: #0000FF;">(</span><span style="color: #004600;">NULL</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"SCREENDPI"</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">25.4</span>
|
||||
<span style="color: #7060A8;">cdCanvasSetAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cd_canvas</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"SIZE"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"%dx%d %g"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">canvas_width</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">canvas_height</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">res</span><span style="color: #0000FF;">})</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_DEFAULT</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">timer_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandln</span> <span style="color: #000080;font-style:italic;">/*ih*/</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000080;font-style:italic;">-- (feel free to add a bit more randomness here, maybe)</span>
|
||||
<span style="color: #000000;">rx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">rx</span><span style="color: #0000FF;">+</span><span style="color: #000000;">359</span><span style="color: #0000FF;">,</span><span style="color: #000000;">360</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">ry</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ry</span><span style="color: #0000FF;">+</span><span style="color: #000000;">359</span><span style="color: #0000FF;">,</span><span style="color: #000000;">360</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">rz</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">rz</span><span style="color: #0000FF;">+</span><span style="color: #000000;">359</span><span style="color: #0000FF;">,</span><span style="color: #000000;">360</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">IupRedraw</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_IGNORE</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #7060A8;">IupOpen</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #000000;">canvas</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupGLCanvas</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"RASTERSIZE=640x480"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">IupSetCallbacks</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"ACTION"</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"canvas_action_cb"</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #008000;">"MAP_CB"</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"canvas_map_cb"</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #008000;">"RESIZE_CB"</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"canvas_resize_cb"</span><span style="color: #0000FF;">)})</span>
|
||||
<span style="color: #000000;">dlg</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupDialog</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span><span style="color: #008000;">`TITLE="%s"`</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">title</span><span style="color: #0000FF;">})</span>
|
||||
<span style="color: #7060A8;">IupShow</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">IupSetAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"RASTERSIZE"</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">NULL</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">Ihandle</span> <span style="color: #000000;">hTimer</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupTimer</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"timer_cb"</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">30</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()!=</span><span style="color: #004600;">JS</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #7060A8;">IupMainLoop</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #7060A8;">IupClose</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
|
||||
|
||||
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
|
||||
<!--
|
||||
37
Task/Draw-a-rotating-cube/PostScript/draw-a-rotating-cube.ps
Normal file
37
Task/Draw-a-rotating-cube/PostScript/draw-a-rotating-cube.ps
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
%!PS-Adobe-3.0
|
||||
%%BoundingBox: 0 0 400 400
|
||||
|
||||
/ed { exch def } def
|
||||
/roty { dup sin /s ed cos /c ed [[c 0 s neg] [0 1 0] [s 0 c]] } def
|
||||
/rotz { dup sin /s ed cos /c ed [[c s neg 0] [s c 0] [0 0 1]] } def
|
||||
/dot { /a ed /b ed
|
||||
a 0 get b 0 get mul
|
||||
a 1 get b 1 get mul
|
||||
a 2 get b 2 get mul
|
||||
add add } def
|
||||
|
||||
/mmul { /v ed [exch {v dot} forall] } def
|
||||
/transall { /m ed [exch {m exch mmul}forall] } def
|
||||
|
||||
/vt
|
||||
[[1 1 1] [-1 1 1]
|
||||
[1 -1 1] [-1 -1 1]
|
||||
[1 1 -1] [-1 1 -1]
|
||||
[1 -1 -1] [-1 -1 -1]]
|
||||
-45 roty transall
|
||||
2 sqrt 1 atan rotz transall
|
||||
def
|
||||
|
||||
/xy { exch get {} forall pop } def
|
||||
/page {
|
||||
/a ed /v vt a roty transall def
|
||||
0 setlinewidth 100 100 scale 2 2 translate
|
||||
/edge { v xy moveto v xy lineto stroke } def
|
||||
|
||||
0 1 2 3 4 5 6 7 0 2 1 3 4 6 5 7 0 4 1 5 2 6 3 7
|
||||
1 1 12 { pop edge } for
|
||||
showpage
|
||||
} def
|
||||
|
||||
0 {3.2 add dup page } loop
|
||||
%%EOF
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
void setup() {
|
||||
size(500, 500, P3D);
|
||||
}
|
||||
void draw() {
|
||||
background(0);
|
||||
// position
|
||||
translate(width/2, height/2, -width/2);
|
||||
// optional fill and lighting colors
|
||||
noStroke();
|
||||
strokeWeight(4);
|
||||
fill(192, 255, 192);
|
||||
pointLight(255, 255, 255, 0, -500, 500);
|
||||
// rotation driven by built-in timer
|
||||
rotateY(millis()/1000.0);
|
||||
// draw box
|
||||
box(300, 300, 300);
|
||||
}
|
||||
18
Task/Draw-a-rotating-cube/Python/draw-a-rotating-cube.py
Normal file
18
Task/Draw-a-rotating-cube/Python/draw-a-rotating-cube.py
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
from visual import *
|
||||
scene.title = "VPython: Draw a rotating cube"
|
||||
|
||||
scene.range = 2
|
||||
scene.autocenter = True
|
||||
|
||||
print "Drag with right mousebutton to rotate view."
|
||||
print "Drag up+down with middle mousebutton to zoom."
|
||||
|
||||
deg45 = math.radians(45.0) # 0.785398163397
|
||||
|
||||
cube = box() # using defaults, see http://www.vpython.org/contents/docs/defaults.html
|
||||
cube.rotate( angle=deg45, axis=(1,0,0) )
|
||||
cube.rotate( angle=deg45, axis=(0,0,1) )
|
||||
|
||||
while True: # Animation-loop
|
||||
rate(50)
|
||||
cube.rotate( angle=0.005, axis=(0,1,0) )
|
||||
70
Task/Draw-a-rotating-cube/Racket/draw-a-rotating-cube.rkt
Normal file
70
Task/Draw-a-rotating-cube/Racket/draw-a-rotating-cube.rkt
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
#lang racket/gui
|
||||
(require math/matrix math/array)
|
||||
|
||||
(define (Rx θ)
|
||||
(matrix [[1.0 0.0 0.0]
|
||||
[0.0 (cos θ) (- (sin θ))]
|
||||
[0.0 (sin θ) (cos θ)]]))
|
||||
|
||||
(define (Ry θ)
|
||||
(matrix [[ (cos θ) 0.0 (sin θ)]
|
||||
[ 0.0 1.0 0.0 ]
|
||||
[(- (sin θ)) 0.0 (cos θ)]]))
|
||||
|
||||
(define (Rz θ)
|
||||
(matrix [[(cos θ) (- (sin θ)) 0.0]
|
||||
[(sin θ) (cos θ) 0.0]
|
||||
[ 0.0 0.0 1.0]]))
|
||||
|
||||
(define base-matrix
|
||||
(matrix* (identity-matrix 3 100.0)
|
||||
(Rx (- (/ pi 2) (atan (sqrt 2))))
|
||||
(Rz (/ pi 4.0))))
|
||||
|
||||
(define (current-matrix)
|
||||
(matrix* (Ry (/ (current-inexact-milliseconds) 1000.))
|
||||
base-matrix))
|
||||
|
||||
(define corners
|
||||
(for*/list ([x '(-1.0 1.0)]
|
||||
[y '(-1.0 1.0)]
|
||||
[z '(-1.0 1.0)])
|
||||
(matrix [[x] [y] [z]])))
|
||||
|
||||
(define lines
|
||||
'((0 1) (0 2) (0 4) (1 3) (1 5)
|
||||
(2 3) (2 6) (3 7) (4 5) (4 6)
|
||||
(5 7) (6 7)))
|
||||
|
||||
(define ox 200.)
|
||||
(define oy 200.)
|
||||
|
||||
(define (draw-line dc a b)
|
||||
(send dc draw-line
|
||||
(+ ox (array-ref a #(0 0)))
|
||||
(+ oy (array-ref a #(1 0)))
|
||||
(+ ox (array-ref b #(0 0)))
|
||||
(+ oy (array-ref b #(1 0)))))
|
||||
|
||||
(define (draw-cube c dc)
|
||||
(define-values (w h) (send dc get-size))
|
||||
(set! ox (/ w 2))
|
||||
(set! oy (/ h 2))
|
||||
(define cs (for/vector ([c (in-list corners)])
|
||||
(matrix* (current-matrix) c)))
|
||||
(for ([l (in-list lines)])
|
||||
(match-define (list i j) l)
|
||||
(draw-line dc (vector-ref cs i) (vector-ref cs j))))
|
||||
|
||||
(define f (new frame% [label "cube"]))
|
||||
(define c (new canvas% [parent f] [min-width 400] [min-height 400] [paint-callback draw-cube]))
|
||||
(send f show #t)
|
||||
|
||||
(send* (send c get-dc)
|
||||
(set-pen "black" 1 'solid)
|
||||
(set-smoothing 'smoothed))
|
||||
|
||||
(define (refresh)
|
||||
(send c refresh))
|
||||
|
||||
(define t (new timer% [notify-callback refresh] [interval 35] [just-once? #f]))
|
||||
93
Task/Draw-a-rotating-cube/Raku/draw-a-rotating-cube.raku
Normal file
93
Task/Draw-a-rotating-cube/Raku/draw-a-rotating-cube.raku
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
use Terminal::Caca;
|
||||
given my $canvas = Terminal::Caca.new {
|
||||
.title('Rosetta Code - Rotating cube - Press any key to exit');
|
||||
|
||||
sub scale-and-translate($x, $y, $z) {
|
||||
$x * 5 / ( 5 + $z ) * 15 + 40,
|
||||
$y * 5 / ( 5 + $z ) * 7 + 15,
|
||||
$z;
|
||||
}
|
||||
|
||||
sub rotate3d-x( $x, $y, $z, $angle ) {
|
||||
my ($cosθ, $sinθ) = cis( $angle * π / 180.0 ).reals;
|
||||
$x,
|
||||
$y * $cosθ - $z * $sinθ,
|
||||
$y * $sinθ + $z * $cosθ;
|
||||
}
|
||||
|
||||
sub rotate3d-y( $x, $y, $z, $angle ) {
|
||||
my ($cosθ, $sinθ) = cis( $angle * π / 180.0 ).reals;
|
||||
$x * $cosθ - $z * $sinθ,
|
||||
$y,
|
||||
$x * $sinθ + $z * $cosθ;
|
||||
}
|
||||
|
||||
sub rotate3d-z( $x, $y, $z, $angle ) {
|
||||
my ($cosθ, $sinθ) = cis( $angle * π / 180.0 ).reals;
|
||||
$x * $cosθ - $y * $sinθ,
|
||||
$x * $cosθ + $y * $sinθ,
|
||||
$z;
|
||||
}
|
||||
|
||||
# Unit cube from polygon mesh, aligned to axes
|
||||
my @mesh =
|
||||
[ [1, 1, -1], [-1, -1, -1], [-1, 1, -1] ], # far face
|
||||
[ [1, 1, -1], [-1, -1, -1], [ 1, -1, -1] ],
|
||||
[ [1, 1, 1], [-1, -1, 1], [-1, 1, 1] ], # near face
|
||||
[ [1, 1, 1], [-1, -1, 1], [ 1, -1, 1] ];
|
||||
@mesh.push: [$_».rotate( 1)».Array] for @mesh[^4]; # positive and
|
||||
@mesh.push: [$_».rotate(-1)».Array] for @mesh[^4]; # negative rotations
|
||||
|
||||
# Rotate to correct orientation for task
|
||||
for ^@mesh X ^@mesh[0] -> ($i, $j) {
|
||||
@(@mesh[$i;$j]) = rotate3d-x |@mesh[$i;$j], 45;
|
||||
@(@mesh[$i;$j]) = rotate3d-z |@mesh[$i;$j], 40;
|
||||
}
|
||||
|
||||
my @colors = red, blue, green, cyan, magenta, yellow;
|
||||
|
||||
loop {
|
||||
for ^359 -> $angle {
|
||||
.color( white, white );
|
||||
.clear;
|
||||
|
||||
# Flatten 3D into 2D and rotate for all faces
|
||||
my @faces-z;
|
||||
my $c-index = 0;
|
||||
for @mesh -> @triangle {
|
||||
my @points;
|
||||
my $sum-z = 0;
|
||||
for @triangle -> @node {
|
||||
my ($px, $py, $z) = scale-and-translate |rotate3d-y |@node, $angle;
|
||||
@points.append: $px.Int, $py.Int;
|
||||
$sum-z += $z;
|
||||
}
|
||||
|
||||
@faces-z.push: %(
|
||||
color => @colors[$c-index++ div 2],
|
||||
points => @points,
|
||||
avg-z => $sum-z / +@points;
|
||||
);
|
||||
}
|
||||
|
||||
# Draw all faces
|
||||
# Sort by z to draw farthest first
|
||||
for @faces-z.sort( -*.<avg-z> ) -> %face {
|
||||
# Draw filled triangle
|
||||
.color( %face<color>, %face<color> );
|
||||
.fill-triangle( |%face<points> );
|
||||
# And frame
|
||||
.color( black, black );
|
||||
.thin-triangle( |%face<points> );
|
||||
}
|
||||
|
||||
.refresh;
|
||||
exit if .wait-for-event(key-press);
|
||||
}
|
||||
}
|
||||
|
||||
# Cleanup on scope exit
|
||||
LEAVE {
|
||||
.cleanup;
|
||||
}
|
||||
}
|
||||
77
Task/Draw-a-rotating-cube/Ring/draw-a-rotating-cube.ring
Normal file
77
Task/Draw-a-rotating-cube/Ring/draw-a-rotating-cube.ring
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
#===================================================================#
|
||||
# Based on Original Sample from RayLib (https://www.raylib.com/)
|
||||
# Ported to RingRayLib by Ring Team
|
||||
#===================================================================#
|
||||
|
||||
load "raylib.ring"
|
||||
|
||||
screenWidth = 800
|
||||
screenHeight = 450
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d picking")
|
||||
|
||||
camera = Camera3D(
|
||||
10, 10, 10,
|
||||
0, 0, 0 ,
|
||||
0, 1, 0 ,
|
||||
45,
|
||||
CAMERA_PERSPECTIVE
|
||||
)
|
||||
|
||||
cubePosition = Vector3( 0, 1, 0 )
|
||||
cubeSize = Vector3( 2, 2, 2 )
|
||||
|
||||
ray = Ray(0,0,0,0,0,0)
|
||||
|
||||
collision = false
|
||||
|
||||
SetCameraMode(camera, CAMERA_FREE)
|
||||
|
||||
SetTargetFPS(60)
|
||||
|
||||
while !WindowShouldClose()
|
||||
|
||||
UpdateCamera(camera)
|
||||
|
||||
if IsMouseButtonPressed(MOUSE_LEFT_BUTTON)
|
||||
if !collision
|
||||
ray = GetMouseRay(GetMousePosition(), camera)
|
||||
|
||||
collision = CheckCollisionRayBox(ray,
|
||||
BoundingBox( cubePosition.x - cubeSize.x/2, cubePosition.y - cubeSize.y/2, cubePosition.z - cubeSize.z/2,
|
||||
cubePosition.x + cubeSize.x/2, cubePosition.y + cubeSize.y/2, cubePosition.z + cubeSize.z/2 ) )
|
||||
else collision = false
|
||||
ok
|
||||
ok
|
||||
|
||||
BeginDrawing()
|
||||
|
||||
ClearBackground(RAYWHITE)
|
||||
|
||||
BeginMode3D(camera)
|
||||
|
||||
if collision
|
||||
DrawCube(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, RED)
|
||||
DrawCubeWires(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, MAROON)
|
||||
|
||||
DrawCubeWires(cubePosition, cubeSize.x + 0.2f, cubeSize.y + 0.2f, cubeSize.z + 0.2f, GREEN)
|
||||
else
|
||||
DrawCube(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, GRAY)
|
||||
DrawCubeWires(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, DARKGRAY)
|
||||
ok
|
||||
|
||||
DrawRay(ray, MAROON)
|
||||
DrawGrid(10, 1)
|
||||
|
||||
EndMode3D()
|
||||
|
||||
DrawText("Try selecting the box with mouse!", 240, 10, 20, DARKGRAY)
|
||||
|
||||
if collision DrawText("BOX SELECTED", (screenWidth - MeasureText("BOX SELECTED", 30)) / 2, screenHeight * 0.1f, 30, GREEN) ok
|
||||
|
||||
DrawFPS(10, 10)
|
||||
|
||||
EndDrawing()
|
||||
end
|
||||
|
||||
CloseWindow()
|
||||
88
Task/Draw-a-rotating-cube/Scala/draw-a-rotating-cube.scala
Normal file
88
Task/Draw-a-rotating-cube/Scala/draw-a-rotating-cube.scala
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
import java.awt.event.ActionEvent
|
||||
import java.awt._
|
||||
|
||||
import javax.swing.{JFrame, JPanel, Timer}
|
||||
|
||||
import scala.math.{Pi, atan, cos, sin, sqrt}
|
||||
|
||||
object RotatingCube extends App {
|
||||
|
||||
class RotatingCube extends JPanel {
|
||||
private val vertices: Vector[Array[Double]] =
|
||||
Vector(Array(-1, -1, -1), Array(-1, -1, 1), Array(-1, 1, -1),
|
||||
Array(-1, 1, 1), Array(1, -1, -1), Array(1, -1, 1), Array(1, 1, -1), Array(1, 1, 1))
|
||||
|
||||
private val edges: Vector[(Int, Int)] =
|
||||
Vector((0, 1), (1, 3), (3, 2), (2, 0), (4, 5), (5, 7),
|
||||
(7, 6), (6, 4), (0, 4), (1, 5), (2, 6), (3, 7))
|
||||
|
||||
setPreferredSize(new Dimension(640, 640))
|
||||
setBackground(Color.white)
|
||||
scale(100)
|
||||
rotateCube(Pi / 4, atan(sqrt(2)))
|
||||
|
||||
new Timer(17, (_: ActionEvent) => {
|
||||
rotateCube(Pi / 180, 0)
|
||||
repaint()
|
||||
}).start()
|
||||
|
||||
override def paintComponent(gg: Graphics): Unit = {
|
||||
def drawCube(g: Graphics2D): Unit = {
|
||||
g.translate(getWidth / 2, getHeight / 2)
|
||||
for {edge <- edges
|
||||
xy1: Array[Double] = vertices(edge._1)
|
||||
xy2: Array[Double] = vertices(edge._2)
|
||||
} {
|
||||
g.drawLine(xy1(0).toInt, xy1(1).toInt, xy2(0).toInt, xy2(1).toInt)
|
||||
g.fillOval(xy1(0).toInt -4, xy1(1).toInt - 4, 8, 8)
|
||||
g.setColor(Color.black)
|
||||
}
|
||||
}
|
||||
|
||||
super.paintComponent(gg)
|
||||
val g: Graphics2D = gg.asInstanceOf[Graphics2D]
|
||||
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
|
||||
drawCube(g)
|
||||
}
|
||||
|
||||
private def scale(s: Double): Unit = {
|
||||
for {node <- vertices
|
||||
i <- node.indices
|
||||
} node(i) *= s
|
||||
}
|
||||
|
||||
private def rotateCube(angleX: Double, angleY: Double): Unit = {
|
||||
def sinCos(x: Double) = (sin(x), cos(x))
|
||||
|
||||
val ((sinX, cosX), (sinY, cosY)) = (sinCos(angleX), sinCos(angleY))
|
||||
|
||||
for {
|
||||
node <- vertices
|
||||
x: Double = node(0)
|
||||
y: Double = node(1)
|
||||
} {
|
||||
def f(p: Double, q: Double)(a: Double, b: Double) = a * p + b * q
|
||||
|
||||
def fx(a: Double, b: Double) = f(cosX, sinX)(a, b)
|
||||
|
||||
def fy(a: Double, b: Double) = f(cosY, sinY)(a, b)
|
||||
|
||||
node(0) = fx(x, -node(2))
|
||||
val z = fx(node(2), x)
|
||||
node(1) = fy(y, -z)
|
||||
node(2) = fy(z, y)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
new JFrame("Rotating Cube") {
|
||||
add(new RotatingCube(), BorderLayout.CENTER)
|
||||
pack()
|
||||
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE)
|
||||
setLocationRelativeTo(null)
|
||||
setResizable(false)
|
||||
setVisible(true)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
:-1→Xmin:1→Xmax
|
||||
:-1→Ymin:1→Ymax
|
||||
:AxesOff
|
||||
:Degrees
|
||||
:While 1
|
||||
:For(X,0,359,5
|
||||
:sin(X-120→I%
|
||||
:sin(X→PV
|
||||
:sin(X+120→FV
|
||||
:Line(0,1,I%,.3
|
||||
:Line(0,1,PV,.3
|
||||
:Line(0,1,FV,.3
|
||||
:Line(0,-1,-I%,-.3
|
||||
:Line(0,-1,-PV,-.3
|
||||
:Line(0,-1,-FV,-.3
|
||||
:Line(.3,I%,-.3,-PV
|
||||
:Line(.3,I%,-.3,-FV
|
||||
:Line(.3,PV,-.3,-I%
|
||||
:Line(.3,PV,-.3,-FV
|
||||
:Line(.3,FV,-.3,-I%
|
||||
:Line(.3,FV,-.3,-PV
|
||||
:End
|
||||
:End
|
||||
133
Task/Draw-a-rotating-cube/Tcl/draw-a-rotating-cube.tcl
Normal file
133
Task/Draw-a-rotating-cube/Tcl/draw-a-rotating-cube.tcl
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
# matrix operation support:
|
||||
package require math::linearalgebra
|
||||
namespace import ::math::linearalgebra::matmul
|
||||
namespace import ::math::linearalgebra::crossproduct
|
||||
namespace import ::math::linearalgebra::dotproduct
|
||||
namespace import ::math::linearalgebra::sub
|
||||
|
||||
# returns a cube as a list of faces,
|
||||
# where each face is a list of (3space) points
|
||||
proc make_cube {{radius 1}} {
|
||||
set dirs {
|
||||
A { 1 1 1}
|
||||
B { 1 1 -1}
|
||||
C { 1 -1 -1}
|
||||
D { 1 -1 1}
|
||||
E {-1 1 1}
|
||||
F {-1 1 -1}
|
||||
G {-1 -1 -1}
|
||||
H {-1 -1 1}
|
||||
}
|
||||
set faces {
|
||||
{A B C D}
|
||||
{D C G H}
|
||||
{H G F E}
|
||||
{E F B A}
|
||||
{A D H E}
|
||||
{C B F G}
|
||||
}
|
||||
lmap fa $faces {
|
||||
lmap dir $fa {
|
||||
lmap x [dict get $dirs $dir] {
|
||||
expr {1.0 * $x * $radius}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# a matrix constructor
|
||||
proc Matrix {m} {
|
||||
tailcall lmap row $m {
|
||||
lmap e $row {
|
||||
expr 1.0*($e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
proc identity {} {
|
||||
Matrix {
|
||||
{1 0 0}
|
||||
{0 1 0}
|
||||
{0 0 1}
|
||||
}
|
||||
}
|
||||
|
||||
# some matrices useful for animation:
|
||||
proc rotateZ {theta} {
|
||||
Matrix {
|
||||
{ cos($theta) -sin($theta) 0 }
|
||||
{ sin($theta) cos($theta) 0 }
|
||||
{ 0 0 1 }
|
||||
}
|
||||
}
|
||||
proc rotateY {theta} {
|
||||
Matrix {
|
||||
{ sin($theta) 0 cos($theta) }
|
||||
{ 0 1 0 }
|
||||
{ cos($theta) 0 -sin($theta) }
|
||||
}
|
||||
}
|
||||
proc rotateX {theta} {
|
||||
Matrix {
|
||||
{ 1 0 0 }
|
||||
{ 0 cos($theta) -sin($theta) }
|
||||
{ 0 sin($theta) cos($theta) }
|
||||
}
|
||||
}
|
||||
|
||||
proc camera {flen} {
|
||||
Matrix {
|
||||
{ $flen 0 0 }
|
||||
{ 0 $flen 0 }
|
||||
{ 0 0 0 }
|
||||
}
|
||||
}
|
||||
|
||||
proc render {canvas object} {
|
||||
|
||||
set W [winfo width $canvas]
|
||||
set H [winfo height $canvas]
|
||||
|
||||
set fl 1.0
|
||||
set t [expr {[clock microseconds] / 1000000.0}]
|
||||
|
||||
set transform [identity]
|
||||
set transform [matmul $transform [rotateX [expr {atan(1)}]]]
|
||||
set transform [matmul $transform [rotateZ [expr {atan(1)}]]]
|
||||
|
||||
set transform [matmul $transform [rotateY $t]]
|
||||
set transform [matmul $transform [camera $fl]]
|
||||
|
||||
foreach face $object {
|
||||
# do transformations into screen space:
|
||||
set points [lmap p $face { matmul $p $transform }]
|
||||
# calculate a normal
|
||||
set o [lindex $points 0]
|
||||
set v1 [sub [lindex $points 1] $o]
|
||||
set v2 [sub [lindex $points 2] $o]
|
||||
set normal [crossproduct $v1 $v2]
|
||||
|
||||
set cosi [dotproduct $normal {0 0 -1.0}]
|
||||
if {$cosi <= 0} { ;# rear-facing!
|
||||
continue
|
||||
}
|
||||
|
||||
set points [lmap p $points {
|
||||
lassign $p x y
|
||||
list [expr {$x + $W/2}] [expr {$y + $H/2}]
|
||||
}]
|
||||
set points [concat {*}$points]
|
||||
$canvas create poly $points -outline black -fill red
|
||||
}
|
||||
}
|
||||
|
||||
package require Tk
|
||||
pack [canvas .c] -expand yes -fill both
|
||||
|
||||
proc tick {} {
|
||||
.c delete all
|
||||
render .c $::world
|
||||
after 50 tick
|
||||
}
|
||||
set ::world [make_cube 100]
|
||||
tick
|
||||
95
Task/Draw-a-rotating-cube/Wren/draw-a-rotating-cube.wren
Normal file
95
Task/Draw-a-rotating-cube/Wren/draw-a-rotating-cube.wren
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
import "graphics" for Canvas, Color
|
||||
import "dome" for Window
|
||||
import "math" for Math
|
||||
|
||||
var Nodes = [
|
||||
[-1, -1, -1],
|
||||
[-1, -1, 1],
|
||||
[-1, 1, -1],
|
||||
[-1, 1, 1],
|
||||
[ 1, -1, -1],
|
||||
[ 1, -1, 1],
|
||||
[ 1, 1, -1],
|
||||
[ 1, 1, 1]
|
||||
]
|
||||
|
||||
var Edges = [
|
||||
[0, 1],
|
||||
[1, 3],
|
||||
[3, 2],
|
||||
[2, 0],
|
||||
[4, 5],
|
||||
[5, 7],
|
||||
[7, 6],
|
||||
[6, 4],
|
||||
[0, 4],
|
||||
[1, 5],
|
||||
[2, 6],
|
||||
[3, 7]
|
||||
]
|
||||
|
||||
class RotatingCube {
|
||||
construct new(width, height) {
|
||||
Window.title = "Rotating cube"
|
||||
Window.resize(width, height)
|
||||
Canvas.resize(width, height)
|
||||
_width = width
|
||||
_height = height
|
||||
_fore = Color.blue
|
||||
}
|
||||
|
||||
init() {
|
||||
scale(100)
|
||||
rotateCube(Num.pi / 4, Math.atan(2.sqrt))
|
||||
drawCube()
|
||||
}
|
||||
|
||||
update() {
|
||||
rotateCube(Num.pi / 180, 0)
|
||||
}
|
||||
|
||||
draw(alpha) {
|
||||
drawCube()
|
||||
}
|
||||
|
||||
scale(s) {
|
||||
for (node in Nodes) {
|
||||
node[0] = node[0] * s
|
||||
node[1] = node[1] * s
|
||||
node[2] = node[2] * s
|
||||
}
|
||||
}
|
||||
|
||||
drawCube() {
|
||||
Canvas.cls(Color.white)
|
||||
Canvas.offset(_width / 2, _height / 2)
|
||||
for (edge in Edges) {
|
||||
var xy1 = Nodes[edge[0]]
|
||||
var xy2 = Nodes[edge[1]]
|
||||
Canvas.line(Math.round(xy1[0]), Math.round(xy1[1]),
|
||||
Math.round(xy2[0]), Math.round(xy2[1]), _fore)
|
||||
}
|
||||
for (node in Nodes) {
|
||||
Canvas.rectfill(Math.round(node[0]) - 4, Math.round(node[1]) - 4, 8, 8, _fore)
|
||||
}
|
||||
}
|
||||
|
||||
rotateCube(angleX, angleY) {
|
||||
var sinX = Math.sin(angleX)
|
||||
var cosX = Math.cos(angleX)
|
||||
var sinY = Math.sin(angleY)
|
||||
var cosY = Math.cos(angleY)
|
||||
for (node in Nodes) {
|
||||
var x = node[0]
|
||||
var y = node[1]
|
||||
var z = node[2]
|
||||
node[0] = x * cosX - z * sinX
|
||||
node[2] = z * cosX + x * sinX
|
||||
z = node[2]
|
||||
node[1] = y * cosY - z * sinY
|
||||
node[2] = z * cosY + y * sinY
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var Game = RotatingCube.new(640, 640)
|
||||
29
Task/Draw-a-rotating-cube/XPL0/draw-a-rotating-cube.xpl0
Normal file
29
Task/Draw-a-rotating-cube/XPL0/draw-a-rotating-cube.xpl0
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
def Size=100., Speed=0.05; \drawing size and rotation speed
|
||||
real X, Y, Z, Farthest; \arrays: 3D coordinates of vertices
|
||||
int I, J, K, ZI, Edge;
|
||||
def R2=sqrt(2.), R3=sqrt(3.), R13=sqrt(1./3.), R23=sqrt(2./3.), R232=R23*2.;
|
||||
\vertex:0 1 2 3 4 5 6 7
|
||||
[X:= [ 0., R2, 0., -R2, 0., R2, 0., -R2];
|
||||
Y:= [ -R3, -R13, R13, -R13, -R13, R13, R3, R13];
|
||||
Z:= [ 0., -R23, -R232, -R23, R232, R23, 0., R23];
|
||||
Edge:= [0,1, 1,2, 2,3, 3,0, 4,5, 5,6, 6,7, 7,4, 0,4, 1,5, 2,6, 3,7];
|
||||
SetVid($101); \set 640x480x8 graphics
|
||||
repeat Farthest:= 0.0; \find the farthest vertex
|
||||
for I:= 0 to 8-1 do
|
||||
if Z(I) > Farthest then [Farthest:= Z(I); ZI:= I];
|
||||
Clear; \erase screen
|
||||
for I:= 0 to 2*12-1 do \for all the vertices...
|
||||
[J:= Edge(I); I:= I+1; \get vertex numbers for edge
|
||||
Move(Fix(X(J)*Size)+640/2, Fix(Y(J)*Size)+480/2);
|
||||
K:= Edge(I);
|
||||
Line(Fix(X(K)*Size)+640/2, Fix(Y(K)*Size)+480/2,
|
||||
if J=ZI ! K=ZI then $F001 \dashed blue\ else $0C \red\);
|
||||
];
|
||||
DelayUS(55000);
|
||||
for I:= 0 to 8-1 do
|
||||
[X(I):= X(I) + Z(I)*Speed; \rotate vertices about Y axis
|
||||
Z(I):= Z(I) - X(I)*Speed; \ (which rotates in X-Z plane)
|
||||
];
|
||||
until KeyHit; \run until a key is struck
|
||||
SetVid(3); \restore normal text mode
|
||||
]
|
||||
34
Task/Draw-a-rotating-cube/Yabasic/draw-a-rotating-cube.basic
Normal file
34
Task/Draw-a-rotating-cube/Yabasic/draw-a-rotating-cube.basic
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
// Rosetta Code problem: http://rosettacode.org/wiki/Draw_a_rotating_cube
|
||||
// adapted to Yabasic by Galileo, 05/2022
|
||||
|
||||
// GFA Punch (code from tigen.ti-fr.com/)
|
||||
// Carré 3D en rotation
|
||||
|
||||
open window 50, 70
|
||||
backcolor 0,0,0
|
||||
clear window
|
||||
color 255,255,255
|
||||
|
||||
do
|
||||
clear window
|
||||
x = COS(T) * 20
|
||||
y = SIN(T) * 18
|
||||
r = SIN(T + T)
|
||||
|
||||
line (x + 40), (y + 40 - r), (-y + 40), (x + 40 - r)
|
||||
line (-y + 40), (x + 40 - r), (-x + 40), (-y + 40 - r)
|
||||
line (-x + 40), (-y + 40 - r), (y + 40), (-x + 40 - r)
|
||||
line (y + 40), (-x + 40 - r), (x + 40), (y + 40 - r)
|
||||
|
||||
line (x + 40), (y + 20 + r), (-y + 40), (x + 20 + r)
|
||||
line (-y + 40), (x + 20 + r), (-x + 40), (-y + 20 + r)
|
||||
line (-x + 40), (-y + 20 + r), (y + 40), (-x + 20 + r)
|
||||
line (y + 40), (-x + 20 + r), (x + 40), (y + 20 + r)
|
||||
line (x + 40), (y + 40 - r), (x + 40), (y + 20 + r)
|
||||
line (-y + 40), (x + 40 - r), (-y + 40), (x + 20 + r)
|
||||
line (-x + 40), (-y + 40 - r), (-x + 40), (-y + 20 + r)
|
||||
line (y + 40), (-x + 40 - r), (y + 40), (-x + 20 + r)
|
||||
|
||||
pause 0.02
|
||||
T = T + 0.15
|
||||
loop
|
||||
57
Task/Draw-a-rotating-cube/Zig/draw-a-rotating-cube.zig
Normal file
57
Task/Draw-a-rotating-cube/Zig/draw-a-rotating-cube.zig
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
const std = @import("std");
|
||||
const c = @cImport({
|
||||
@cInclude("raylib.h");
|
||||
@cInclude("rlgl.h");
|
||||
});
|
||||
|
||||
const dark_mode = true;
|
||||
const show_grid = false;
|
||||
|
||||
pub fn main() !void {
|
||||
const screen_width = 640;
|
||||
const screen_height = 360;
|
||||
|
||||
const cube_side = 1;
|
||||
const size = c.Vector3{ .x = cube_side, .y = cube_side, .z = cube_side };
|
||||
const position = c.Vector3{ .x = 0, .y = 0, .z = 0 };
|
||||
const x_rot = 45;
|
||||
const y_center = std.math.sqrt(@as(f32, 3)) * cube_side / 2;
|
||||
const z_rot = std.math.atan(@as(f32, std.math.sqrt1_2)) * 180 / std.math.pi;
|
||||
|
||||
c.SetConfigFlags(c.FLAG_WINDOW_RESIZABLE | c.FLAG_VSYNC_HINT);
|
||||
c.InitWindow(screen_width, screen_height, "Draw a Rotating Cube");
|
||||
defer c.CloseWindow();
|
||||
|
||||
var camera = c.Camera{
|
||||
.position = .{ .x = 3, .y = 3, .z = 3 },
|
||||
.target = .{ .x = 0, .y = y_center, .z = 0 }, // Center of cube
|
||||
.up = .{ .x = 0, .y = 1, .z = 0 },
|
||||
.fovy = 45, // Camera field-of-view Y
|
||||
.projection = c.CAMERA_PERSPECTIVE,
|
||||
};
|
||||
|
||||
c.SetTargetFPS(60);
|
||||
|
||||
while (!c.WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
c.UpdateCamera(&camera, c.CAMERA_ORBITAL);
|
||||
|
||||
c.BeginDrawing();
|
||||
defer c.EndDrawing();
|
||||
|
||||
c.ClearBackground(if (dark_mode) c.BLACK else c.RAYWHITE);
|
||||
{
|
||||
c.BeginMode3D(camera);
|
||||
defer c.EndMode3D();
|
||||
{
|
||||
c.rlPushMatrix();
|
||||
defer c.rlPopMatrix();
|
||||
c.rlTranslatef(0, y_center, 0);
|
||||
c.rlRotatef(z_rot, 0, 0, 1);
|
||||
c.rlRotatef(x_rot, 1, 0, 0);
|
||||
c.DrawCubeWiresV(position, size, if (dark_mode) c.LIME else c.BLACK);
|
||||
}
|
||||
if (show_grid) c.DrawGrid(12, 0.75);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue