Общий алгоритм рисования вращающихся "непрозрачных" 3-мерных фигур
{Borland Pascal 7.0
CUBE.PAS: Общий алгоритм рисования вращающихся "непрозрачных" 3-мерных фигур
Classic example. Modify by V.Ivanov}
uses Graph, Crt;
procedure DrawCube;
label
nextj;
type
cube=array[1..8] of record x,y,z:integer end;
{verts-координаты (xyz) вершин фигуры}
const
verts:cube=(
(x: 1; y: 1; z: 1), {1-я вершина}
(x: 1; y: 1; z:-1), {2}
(x: 1; y:-1; z: 1), {3}
(x: 1; y:-1; z:-1), {4}
(x:-1; y: 1; z: 1), {5}
(x:-1; y: 1; z:-1), {6}
(x:-1; y:-1; z: 1), {7}
(x:-1; y:-1; z:-1)); {8}
{g- это описания из каких вершин в состоят грани
(в массиве лежат номера точек в нумерации verts) }
g:array[1..6, 1..4] of shortint=
((1,2,4,3),
(1,2,6,5),
(1,3,7,5),
(3,4,8,7),
(2,4,8,6),
(5,6,8,7));
var
Alfa,Beta,Gamma, {проекции единичного вектора поворота (его длина=1)}
Teta, {Угол поворота точек пространства}
DT:real; {Приращение (прибавка) угла Teta}
c:cube; {Массив для координат вращаемых вершин}
procedure Rotate(var x,y,z:integer);
{Поворот точки вокруг единичного вектора (Alfa, Beta, Gamma) на угол Teta}
var
cosT, sinT, One_cosT, AOne_cosT, BOne_cosT,GsinT:real;
xn,yn,zn:integer;
begin
{Это сложное преобразование взято из справочника по стереометрии}
cosT:=cos(Teta);
sinT:=sin(Teta);
One_cosT :=1.0-cosT;
AOne_cosT:=Alfa*One_cosT;
BOne_cosT:=Beta*One_cosT;
GsinT:=Gamma*sinT;
xn:=trunc(
x*( cosT + Alfa * AOne_cosT)+
y*( GsinT + Beta * AOne_cosT)+
z*(-Beta*sinT + Gamma * AOne_cosT));
yn:=trunc(
x*(-GSinT + Beta * AOne_cosT)+
y*( cosT + Beta * BOne_cosT)+
z*( Alfa*sinT + Gamma * BOne_cosT));
zn:=trunc(
x*( Beta*sinT + Gamma * AOne_cosT)+
y*(-alfa*sinT + Gamma * BOne_cosT)+
z*( cosT + Gamma*Gamma*One_cosT));
x:=xn; y:=yn; z:=zn;
delay(1);
end;
function minz:integer;
{нахождение самой "задней" точки, т.е. с минимальным z (ось z идет от нас)}
var j,m:integer;
begin
m:=1;
for j:=2 to 8 do
if c[j].z< c[m].z then m:=j;
minz:=m;
end;
var
Pnts:array[1..5] of record {Буфер для рисования точек грани через FillPoly}
x,y:integer
end;
min:integer; {номер самой "задней" точки}
x0,y0:integer; {Центр изображения}
a: integer; {Коэф. увеличения изображения}
i,j,k:integer; {Параметры циклов}
page:word; {Текущая видео страница}
begin
page:=0;
x0:=120;
y0:=100;
a:=40;
Alfa:=0.6;
Beta:=0.7;
Gamma:=sqrt(1.0-Alfa*Alfa-Beta*Beta); {3-мерная теорема Пифагора}
Teta:=0;
DT:=2*Pi/100;{2.0*Pi/20;}
{Масштабируем и поворачиваем все вершины на угол Teta}
for i:=1 to 8 do
begin
c[i].x:=verts[i].x*a;
c[i].y:=verts[i].y*a;
c[i].z:=verts[i].z*a;
Rotate(c[i].x,c[i].y,c[i].z)
end;
min:=MinZ; {находим самую заднюю вершину}
SetVisualPage((Page+1)mod 2);
for k:=0 to 2500 do
begin
SetActivePage(page); {Делаем активной невидимую страницу}
{Рисуем 6 граней}
for j:=1 to 6 do
begin
{Пропуск невидимой грани содержащей самую "заднюю" точку}
for i:=1 to 4 do if min=g[j,i] then goto nextj; {goto необходим!}
{Проходим по вершинам грани}
for i:=1 to 4 do
begin
{Берем проекцию вершины на плоскость xoy (т.е. коорд. x и у) }
Pnts[i].x:=x0+c[g[j,i]].x;
Pnts[i].y:=y0+trunc(0.775*c[g[j,i]].y) {0.775- к-т сжатия EGA HI}
end;
SetFillStyle(SolidFill, word(j+8)); {Каждой грани своя закраска}
{Pnts[5]:=Pnts[1];} {Это нужно при DrawPoly}
FillPoly(4,Pnts); {Рисуем грань}
nextJ:
end;
SetVisualPage(Page); {Показываем рисунок: делаем видимой страницу}
SetActivePage((Page+1)mod 2); {Делаем активной невид. стр. для Bar}
{Поворачиваем вершины}
for i:=1 to 8 do
begin
c[i].x:=verts[i].x*a;
c[i].y:=verts[i].y*a;
c[i].z:=verts[i].z*a;
Rotate(c[i].x,c[i].y,c[i].z)
end;
min:=MinZ;
SetFillStyle(SolidFill, Black);
Bar(0,0,x0*2,y0*2); {Стираем старое изображение на невид. стр.}
Teta:=Teta+DT; {Увеличиваем угол поворота}
Page:=(Page+1)mod 2; {Меняем страницу (0-> 1; 1->0) }
if KeyPressed then
exit; {Если нажали клавишу - конец}
end;
end;
var drv,mode:integer;
begin
drv:=EGA;
mode:=EGAHI;
InitGraph(drv,mode,'C:\compilat\tp\bgi');
DrawCube;
end.
---
* Origin: I like: Pas, Delphi, C++, Asm, Physics (2:5030/433.20)
Оставить комментарий
Комментарии
1.


28 февраля 2005, 11:55:19
Простите, любезный, это не алгоритм - это его реализация. Ну и что с этим "припаскаленым" алгоритмом делать?
