unit u3D;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, StdCtrls;
type
TExPoint=record //punkt w 3D
x,y,z:Extended;
end;
TmainF=class(TForm)
Cpanel:TPanel; //panel sterowania
ox:TEdit; //pola aktualnego obrotu
oy:TEdit;
oz:TEdit;
Label1:TLabel; //jakieś etykiety
Label2:TLabel;
Label3:TLabel;
Label4:TLabel;
Label5:TLabel;
Label6:TLabel;
Label7:TLabel;
Label8:TLabel;
kr:TEdit; // długość krawędzi sześcianu
dis:TImage; //obrazek do wyświetlania 3D
pe:TEdit; //współczynnik perspektywy
dist:TEdit; //odległość od środka bryły
stB:TButton; //start/stop
procedure stBClick(Sender:TObject);
procedure FormCreate(Sender:TObject);
procedure draw3D; //renderowanie
procedure FormResize(Sender: TObject);
private
Fmap:TBitmap; //mapa tymczasowa (żeby nie mrógało)
a,d,p:Extended; // długość krawędzi sześcianu, odległośc od kamery, współczynnik perspektywy
ang,vang:TExPoint; //aktualny kont obrotu, prędkość obrotów
public
{ Public declarations }
end;
const
wall:array[0..5,0..3]of byte=((0,1,2,3),(0,1,5,4),(0,3,7,4),(1,2,6,5),(2,3,7,6),(4,5,6,7));//jak przepisywać punkty do ścian
var
mainF:TmainF;
function str2ex(s:string;def:Extended):Extended; //zmienna w string na extended
function exmod(n,x:Extended):Extended; //reszta z dzielenia przez
implementation
{$R *.DFM}
procedure TmainF.draw3D;
//renderowanie 3D
var
i,c:integer; //do obsługi pentli
sd:boolean; //czy już posortowane
temp:TExPoint; //tymczasowy punkt w 3D
pt:array[0..7]of TExPoint; //tablica wieszhołków sześcianu
sr:array[0..5]of Extended; //tablica środków ścian
sci:array[0..5,0..3]of TExPoint; //tablica ścian (ich wierzchołków)
sci2D:array[0..5,0..3]of TPoint; //tablica wierzchołków ścian po przekształceniu do 2D
begin
pt[1].x:=a/2; //przypisanie wartości współrzędnym odpowiednich punktów
pt[0].x:=-pt[1].x;
pt[2].x:=pt[1].x;
pt[5].x:=pt[1].x;
pt[6].x:=pt[1].x;
pt[3].x:=pt[0].x;
pt[4].x:=pt[0].x;
pt[7].x:=pt[0].x;
pt[0].y:=pt[0].x+d;
pt[1].y:=pt[0].y;
pt[2].y:=pt[0].y;
pt[3].y:=pt[0].y;
pt[4].y:=pt[1].x+d;
pt[5].y:=pt[4].y;
pt[6].y:=pt[4].y;
pt[7].y:=pt[4].y;
pt[0].z:=pt[0].x;
pt[1].z:=pt[0].z;
pt[5].z:=pt[0].z;
pt[4].z:=pt[0].z;
pt[2].z:=pt[1].x;
pt[3].z:=pt[2].z;
pt[6].z:=pt[2].z;
pt[7].z:=pt[2].z;
for i:=0 to 7 do begin //obrót punktów wokół osi o konty podane w ang
pt[i].x:=pt[i].ysin(ang.z)+pt[i].xcos(ang.z);
pt[i].y:=pt[i].xsin(ang.z)+pt[i].ycos(ang.z);
pt[i].y:=pt[i].zsin(ang.x)+pt[i].ycos(ang.x);
pt[i].z:=pt[i].ysin(ang.x)+pt[i].zcos(ang.x);
pt[i].x:=pt[i].zsin(ang.y)+pt[i].xcos(ang.y);
pt[i].z:=pt[i].xsin(ang.y)+pt[i].zcos(ang.y);
end;
for i:=0 to 5 do for c:=0 to 3 do begin //przepisanie współrzędnych do ścian (według wzoru)
sci[i,c]:=pt[wall[i,c]];
end;
for i:=0 to 5 do begin //obliczenie środków poszczególnych ścian (tylko y)
sr[i]:=(sci[i,0].y+sci[i,1].y+sci[i,2].y+sci[i,3].y)/4;
end;
repeat //posortowanie ścian według odległości do "kamery"
sd:=true;
for i:=0 to 4 do if sr[i]x do n:=n-x;
while n