Помощь - Поиск - Пользователи - Календарь
Полная версия: 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
О! Нашел вроде что-то поприличней:
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.