Помощь - Поиск - Пользователи - Календарь
Полная версия: 3d графика
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
shinkirou
Нужно построить 3d модели на TP. Пошарил по сети, нашел этот пример.
Помогите разобраться (хоть откомментировать), а то с процедурным не оч, а сдавать скоро, копипаст не хотелось бы нести.

 Uses Graph, Crt;

Const N=8;
M=12;

Type Coord = record
X,Y,Z : Real;
End;

Rebro = record
B,E,C : Word;
End;

Var
grDriver : Integer;
grMode : Integer;
A : Array [1..N] of Coord;
B : Array [1..M] of Rebro;
Key : Char;
I : Byte;
L,C : Coord;
Ux, Uy, Uz : Real;

Procedure Tr3d(P,T:Coord; Var R:Coord);
Type Matrix = Array [1..4,1..4] Of Real;
Var I,J : Byte;
O : Matrix;
Begin
For I := 1 To 4 Do For J := 1 To 4 Do If I = J Then O[I,J] := 1
Else O[I,J] := 0;

O[1,4] := T.X;
O[2,4] := T.Y;
O[3,4] := T.Z;

R.X := O[1,1] * P.X + O[1,2] * P.Y + O[1,3] * P.Z + O[1,4];
R.Y := O[2,1] * P.X + O[2,2] * P.Y + O[2,3] * P.Z + O[2,4];
R.Z := O[3,1] * P.X + O[3,2] * P.Y + O[3,3] * P.Z + O[3,4];
End;

Procedure Sr3d(P,S:Coord; Var R:Coord);
Type Matrix = Array [1..4,1..4] Of Real;
Var I,J : Byte;
O : Matrix;
Begin
For I := 1 To 4 Do For J := 1 To 4 Do If I = J Then O[I,J] := 1
Else O[I,J] := 0;

O[1,1] := S.X;
O[2,2] := S.Y;
O[3,3] := S.Z;

R.X := O[1,1] * P.X + O[1,2] * P.Y + O[1,3] * P.Z + O[1,4];
R.Y := O[2,1] * P.X + O[2,2] * P.Y + O[2,3] * P.Z + O[2,4];
R.Z := O[3,1] * P.X + O[3,2] * P.Y + O[3,3] * P.Z + O[3,4];
End;

Procedure UX3d(P:Coord; Teta:Real; Var R:Coord);
Type Matrix = Array [1..4,1..4] Of Real;
Var I,J : Byte;
O : Matrix;
Begin
For I := 1 To 4 Do For J := 1 To 4 Do If I = J Then O[I,J] := 1
Else O[I,J] := 0;
O[2,2] := COS(Teta);
O[2,3] := -SIN(Teta);
O[3,2] := SIN(Teta);
O[3,3] := COS(Teta);

R.X := O[1,1] * P.X + O[1,2] * P.Y + O[1,3] * P.Z + O[1,4];
R.Y := O[2,1] * P.X + O[2,2] * P.Y + O[2,3] * P.Z + O[2,4];
R.Z := O[3,1] * P.X + O[3,2] * P.Y + O[3,3] * P.Z + O[3,4];
End;

Procedure UY3d(P:Coord; Teta:Real; Var R:Coord);
Type Matrix = Array [1..4,1..4] Of Real;
Var I,J : Byte;
O : Matrix;
Begin
For I := 1 To 4 Do For J := 1 To 4 Do If I = J Then O[I,J] := 1
Else O[I,J] := 0;
O[1,1] := COS(Teta);
O[1,3] := -SIN(Teta);
O[3,1] := SIN(Teta);
O[3,3] := COS(Teta);

R.X := O[1,1] * P.X + O[1,2] * P.Y + O[1,3] * P.Z + O[1,4];
R.Y := O[2,1] * P.X + O[2,2] * P.Y + O[2,3] * P.Z + O[2,4];
R.Z := O[3,1] * P.X + O[3,2] * P.Y + O[3,3] * P.Z + O[3,4];
End;

Procedure UZ3d(P:Coord; Teta:Real; Var R:Coord);
Type Matrix = Array [1..4,1..4] Of Real;
Var I,J : Byte;
O : Matrix;
Begin
For I := 1 To 4 Do For J := 1 To 4 Do If I = J Then O[I,J] := 1
Else O[I,J] := 0;
O[1,1] := COS(Teta);
O[1,2] := -SIN(Teta);
O[2,1] := SIN(Teta);
O[2,2] := COS(Teta);

R.X := O[1,1] * P.X + O[1,2] * P.Y + O[1,3] * P.Z + O[1,4];
R.Y := O[2,1] * P.X + O[2,2] * P.Y + O[2,3] * P.Z + O[2,4];
R.Z := O[3,1] * P.X + O[3,2] * P.Y + O[3,3] * P.Z + O[3,4];
End;

Procedure Fig;
Begin
A[ 1].X := 10; A[ 1].Y := 10; A[ 1].Z := 10;
A[ 2].X := 10; A[ 2].Y := 10; A[ 2].Z := -10;
A[ 3].X := 10; A[ 3].Y := -10; A[ 3].Z := -10;
A[ 4].X := 10; A[ 4].Y := -10; A[ 4].Z := 10;
A[ 5].X := -10; A[ 5].Y := 10; A[ 5].Z := 10;
A[ 6].X := -10; A[ 6].Y := 10; A[ 6].Z := -10;
A[ 7].X := -10; A[ 7].Y := -10; A[ 7].Z := -10;
A[ 8].X := -10; A[ 8].Y := -10; A[ 8].Z := 10;

B[ 1].B := 1; B[ 1].E := 2; B[ 1].C := 10;
B[ 2].B := 2; B[ 2].E := 3; B[ 2].C := 10;
B[ 3].B := 3; B[ 3].E := 4; B[ 3].C := 10;
B[ 4].B := 4; B[ 4].E := 1; B[ 4].C := 10;

B[ 5].B := 5; B[ 5].E := 6; B[ 5].C := 13;
B[ 6].B := 6; B[ 6].E := 7; B[ 6].C := 13;
B[ 7].B := 7; B[ 7].E := 8; B[ 7].C := 13;
B[ 8].B := 8; B[ 8].E := 5; B[ 8].C := 13;

B[ 9].B := 1; B[ 9].E := 5; B[ 9].C := 7;
B[10].B := 2; B[10].E := 6; B[10].C := 7;
B[11].B := 3; B[11].E := 7; B[11].C := 7;
B[12].B := 4; B[12].E := 8; B[12].C := 7;

End;

Procedure Draw3D;
Var I : Byte;
XB, YB, XE, YE : Real;
Begin
For I := 1 To M Do Begin
SetColor(B[I].C);
XB := A[B[I].B].X;
YB := A[B[I].B].Y;
XE := A[B[I].E].X;
YE := A[B[I].E].Y;
Line( Trunc(XB), Trunc(YB), Trunc(XE), Trunc(YE) );
End;
End;

Procedure Hide3D;
Var I : Byte;
XB, YB, XE, YE : Real;
Begin
SetColor(Black);
For I := 1 To M Do Begin
XB := A[B[I].B].X;
YB := A[B[I].B].Y;
XE := A[B[I].E].X;
YE := A[B[I].E].Y;
Line( Trunc(XB), Trunc(YB), Trunc(XE), Trunc(YE) );
End;
End;

Begin
ClrScr;

WriteLn('1-2 ‚вращение по оси OZ');
WriteLn('3-4 ‚вращение по оси OY');
WriteLn('5-6 ‚вращение по оси OX');
WriteLn('7-8 приблизить\отдалить');

ReadLn;

Fig;

C.X := 5; C.Y := 5; C.Z := 5;
For I := 1 To N Do Sr3d(A[I], C, A[I]);
L.X := 200; L.Y := 200; L.Z := 200;
For I := 1 To N Do Tr3d(A[I], L, A[I]);

grDriver := Detect;
InitGraph(grDriver,grMode,'c:\tp\bgi\');

Draw3D;

Key := ' ';
While Key <> #27 Do Begin
Key := ReadKey;

If Key = '1' Then Begin
Hide3D;

L.X := -L.X; L.Y := -L.Y; L.Z := -L.Z;
For I := 1 To N Do Tr3d(A[I], L, A[I]);

Uz := Pi/120; For I := 1 To N Do Uz3d(A[i],Uz,A[i]);

L.X := -L.X; L.Y := -L.Y; L.Z := -L.Z;
For I := 1 To N Do Tr3d(A[I], L, A[I]);

Draw3D;
End;

If Key = '2' Then Begin
Hide3D;

L.X := -L.X; L.Y := -L.Y; L.Z := -L.Z;
For I := 1 To N Do Tr3d(A[I], L, A[I]);

Uz := -Pi/120; For I := 1 To N Do Uz3d(A[i],Uz,A[i]);

L.X := -L.X; L.Y := -L.Y; L.Z := -L.Z;
For I := 1 To N Do Tr3d(A[I], L, A[I]);

Draw3D;
End;

If Key = '3' Then Begin
Hide3D;

L.X := -L.X; L.Y := -L.Y; L.Z := -L.Z;
For I := 1 To N Do Tr3d(A[I], L, A[I]);

Uy := Pi/120; For I := 1 To N Do Uy3d(A[i],Uy,A[i]);

L.X := -L.X; L.Y := -L.Y; L.Z := -L.Z;
For I := 1 To N Do Tr3d(A[I], L, A[I]);

Draw3D;
End;

If Key = '4' Then Begin
Hide3D;

L.X := -L.X; L.Y := -L.Y; L.Z := -L.Z;
For I := 1 To N Do Tr3d(A[I], L, A[I]);

Uy := -Pi/120; For I := 1 To N Do Uy3d(A[i],Uy,A[i]);

L.X := -L.X; L.Y := -L.Y; L.Z := -L.Z;
For I := 1 To N Do Tr3d(A[I], L, A[I]);

Draw3D;
End;

If Key = '5' Then Begin
Hide3D;

L.X := -L.X; L.Y := -L.Y; L.Z := -L.Z;
For I := 1 To N Do Tr3d(A[I], L, A[I]);

Ux := Pi/120; For I := 1 To N Do Ux3d(A[i],Ux,A[i]);

L.X := -L.X; L.Y := -L.Y; L.Z := -L.Z;
For I := 1 To N Do Tr3d(A[I], L, A[I]);

Draw3D;
End;

If Key = '6' Then Begin
Hide3D;

L.X := -L.X; L.Y := -L.Y; L.Z := -L.Z;
For I := 1 To N Do Tr3d(A[I], L, A[I]);

Ux := -Pi/120; For I := 1 To N Do Ux3d(A[i],Ux,A[i]);

L.X := -L.X; L.Y := -L.Y; L.Z := -L.Z;
For I := 1 To N Do Tr3d(A[I], L, A[I]);

Draw3D;
End;

If Key = '7' Then Begin
Hide3D;
L.X := -L.X; L.Y := -L.Y; L.Z := -L.Z;
For I := 1 To N Do Tr3d(A[I], L, A[I]);

C.X := 1.1; C.Y := 1.1; C.Z := 1.1;
For I := 1 To N Do Sr3d(A[I], C, A[I]);

L.X := -L.X; L.Y := -L.Y; L.Z := -L.Z;
For I := 1 To N Do Tr3d(A[I], L, A[I]);
Draw3D;
End;

If Key = '8' Then Begin
Hide3D;
L.X := -L.X; L.Y := -L.Y; L.Z := -L.Z;
For I := 1 To N Do Tr3d(A[I], L, A[I]);

C.X := 0.9; C.Y := 0.9; C.Z := 0.9;
For I := 1 To N Do Sr3d(A[I], C, A[I]);

L.X := -L.X; L.Y := -L.Y; L.Z := -L.Z;
For I := 1 To N Do Tr3d(A[I], L, A[I]);

Draw3D;
End;
End;
Hide3D;

CloseGraph;

End.


TarasBer
Это не очень удачный пример.
Глупо преобразовывать всё пространство, когда все преобразования можно хранить в специальной матрице. Тут были попытки так сделать (матрица заводится и заполняется внутри процедуры), но они абсолютно бессмысленные, видимо автор "слышал звон, да не знает где он".
В общем, на эту тему лучше почитайте http://pmg.org.ru/basic3d/index.html
shinkirou
а хоть какой-то комментарий к коду можно? blush.gif
а то я балдею от разбора, графикой в принципе никогда не занимался ypriamii.gif
ЗЫ
за ссылку спасиб, довольно просто написано, сижу, изучаю)
shinkirou
О! Нашел вроде что-то поприличней:
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.