unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls;
type
TForm1 = class(TForm)
Timer1: TTimer;
StartPos: TButton;
RotateX: TButton;
RotateY: TButton;
RotateZ: TButton;
Button3: TButton;
Button4: TButton;
Button5: TButton;
Button1: TButton;
Button2: TButton;
Button6: TButton;
Button7: TButton;
Button8: TButton;
Button9: TButton;
procedure Timer1Timer(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure StartPosClick(Sender: TObject);
procedure RotateXClick(Sender: TObject);
procedure RotateYClick(Sender: TObject);
procedure RotateZClick(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button6Click(Sender: TObject);
procedure Button7Click(Sender: TObject);
procedure Button8Click(Sender: TObject);
procedure Button9Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
Mas :array [1..10] of array [1..4] of real; //массив вершин фигуры
Dop :array [1..4] of array [1..4] of real; //матрица преобразования
DopX :array [1..4] of array [1..4] of real; //4 дополнительных матрицы для поворотов
DopY :array [1..4] of array [1..4] of real;
DopZ :array [1..4] of array [1..4] of real;
Dof :array [1..4] of array [1..4] of real;
FiXY,FiYZ,FiXZ :real; //углы поворотов относительно осей
X0,Y0,Z0 :integer;
implementation
{$R *.dfm}
procedure TForm1.Timer1Timer(Sender: TObject);
var
i,j: integer;
Buf :array [1..4] of real; //вспомогательный массив
begin
for i:=1 to 3 do //перремножим дополнительные матрицы,
for j:=1 to 3 do //чтобы получить матрицу преобразования
Dof[i][j]:=DopX[j][1]*DopY[i][1]+DopX[j][2]*DopY[i][2]+DopX[j][3]*DopY[i][3];
for i:=1 to 3 do
for j:=1 to 3 do
Dop[i][j]:=Dof[j][1]*DopZ[i][1]+Dof[j][2]*DopZ[i][2]+Dof[j][3]*DopZ[i][3];
for i:=1 to 10 do //выполним преобразование координат, умножив
begin //массив вершин на матрицу преобразования
for j:=1 to 4 do
begin
Buf[j]:=Dop[j][1]*Mas[i][1]+Dop[j][2]*Mas[i][2]+Dop[j][3]*Mas[i][3]+
Dop[j][4]*Mas[i][4];
end;
Mas[i][1]:=Buf[1]/Buf[4]; //четвертая координата вершин должна быть
Mas[i][2]:=Buf[2]/Buf[4]; //равна 1, поэтому делим на нее все координаты
Mas[i][3]:=Buf[3]/Buf[4];
Mas[i][4]:=1;
end;
Form1.Canvas.Pen.Color:=clBlack; //очистка экрана
Form1.Canvas.Brush.Color:=clWhite;
Form1.Canvas.Rectangle(-1,-1,880,720);
Buf[1]:=Sqrt(3)*0.5; //сохраним постоянно используемое число
Form1.Canvas.Pen.Color:=clRed; // Цвет красный
Form1.Canvas.Pen.Width:=3; //Толшена линии
Form1.Canvas.MoveTo(250,0); //во вспомогательном массиве
Form1.Canvas.LineTo(250,448);
Form1.Canvas.Pen.Color:=clBlue; // Цветголубой
Form1.Canvas.LineTo(0,580); //рисуем оси координат под углом 120o
Form1.Canvas.MoveTo(250,448);
Form1.Canvas.Pen.Color:=clGreen; // Цвет зелёный
Form1.Canvas.LineTo(880,680);
Form1.Canvas.Pen.Color:=clyellow; // Цвет Желтый
//используем все координаты для отображения
Form1.Canvas.Pen.Width:=4;//Толшена линии
Form1.Canvas.MoveTo(X0+Round(-Buf[1]*Mas[5][1]+Buf[1]*Mas[5][3]),
Y0+Round(Mas[5][2]-0.5*Mas[5][1]-0.5*Mas[5][3]));
Form1.Canvas.LineTo(X0+Round(-Buf[1]*Mas[1][1]+Buf[1]*Mas[1][3]),
Y0+Round(Mas[1][2]-0.5*Mas[1][1]-0.5*Mas[1][3]));
Form1.Canvas.LineTo(X0+Round(-Buf[1]*Mas[2][1]+Buf[1]*Mas[2][3]),
Y0+Round(Mas[2][2]-0.5*Mas[2][1]-0.5*Mas[2][3]));
Form1.Canvas.LineTo(X0+Round(-Buf[1]*Mas[3][1]+Buf[1]*Mas[3][3]),
Y0+Round(Mas[3][2]-0.5*Mas[3][1]-0.5*Mas[3][3]));
Form1.Canvas.LineTo(X0+Round(-Buf[1]*Mas[4][1]+Buf[1]*Mas[4][3]),
Y0+Round(Mas[4][2]-0.5*Mas[4][1]-0.5*Mas[4][3]));
Form1.Canvas.LineTo(X0+Round(-Buf[1]*Mas[5][1]+Buf[1]*Mas[5][3]),
Y0+Round(Mas[5][2]-0.5*Mas[5][1]-0.5*Mas[5][3]));
Form1.Canvas.LineTo(X0+Round(-Buf[1]*Mas[6][1]+Buf[1]*Mas[6][3]),
Y0+Round(Mas[6][2]-0.5*Mas[6][1]-0.5*Mas[6][3]));
Form1.Canvas.LineTo(X0+Round(-Buf[1]*Mas[7][1]+Buf[1]*Mas[7][3]),
Y0+Round(Mas[7][2]-0.5*Mas[7][1]-0.5*Mas[7][3]));
Form1.Canvas.LineTo(X0+Round(-Buf[1]*Mas[1][1]+Buf[1]*Mas[1][3]),
Y0+Round(Mas[1][2]-0.5*Mas[1][1]-0.5*Mas[1][3]));
Form1.Canvas.MoveTo(X0+Round(-Buf[1]*Mas[7][1]+Buf[1]*Mas[7][3]),
Y0+Round(Mas[7][2]-0.5*Mas[7][1]-0.5*Mas[7][3]));
Form1.Canvas.LineTo(X0+Round(-Buf[1]*Mas[8][1]+Buf[1]*Mas[8][3]),
Y0+Round(Mas[8][2]-0.5*Mas[8][1]-0.5*Mas[8][3]));
Form1.Canvas.LineTo(X0+Round(-Buf[1]*Mas[2][1]+Buf[1]*Mas[2][3]),
Y0+Round(Mas[2][2]-0.5*Mas[2][1]-0.5*Mas[2][3]));
Form1.Canvas.MoveTo(X0+Round(-Buf[1]*Mas[8][1]+Buf[1]*Mas[8][3]),
Y0+Round(Mas[8][2]-0.5*Mas[8][1]-0.5*Mas[8][3]));
Form1.Canvas.LineTo(X0+Round(-Buf[1]*Mas[9][1]+Buf[1]*Mas[9][3]),
Y0+Round(Mas[9][2]-0.5*Mas[9][1]-0.5*Mas[9][3]));
Form1.Canvas.LineTo(X0+Round(-Buf[1]*Mas[3][1]+Buf[1]*Mas[3][3]),
Y0+Round(Mas[3][2]-0.5*Mas[3][1]-0.5*Mas[3][3]));
Form1.Canvas.MoveTo(X0+Round(-Buf[1]*Mas[9][1]+Buf[1]*Mas[9][3]),
Y0+Round(Mas[9][2]-0.5*Mas[9][1]-0.5*Mas[9][3]));
Form1.Canvas.LineTo(X0+Round(-Buf[1]*Mas[10][1]+Buf[1]*Mas[10][3]),
Y0+Round(Mas[10][2]-0.5*Mas[10][1]-0.5*Mas[10][3]));
Form1.Canvas.LineTo(X0+Round(-Buf[1]*Mas[4][1]+Buf[1]*Mas[4][3]),
Y0+Round(Mas[4][2]-0.5*Mas[4][1]-0.5*Mas[4][3]));
Form1.Canvas.MoveTo(X0+Round(-Buf[1]*Mas[10][1]+Buf[1]*Mas[10][3]),
Y0+Round(Mas[10][2]-0.5*Mas[10][1]-0.5*Mas[10][3]));
Form1.Canvas.LineTo(X0+Round(-Buf[1]*Mas[6][1]+Buf[1]*Mas[6][3]),
Y0+Round(Mas[6][2]-0.5*Mas[6][1]-0.5*Mas[6][3]));
Form1.Canvas.CopyRect(Rect(0,0,880,720), //реализуем двойную буферизацию
Form1.Canvas, Rect(0,0,880,720));
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Form1.WindowState:=wsNormal; //окно во весь экран wsNormal,wsMaximized
X0:=250; //координаты осей
Y0:=250;
FiYZ:=0; FiXY:=0; FiXZ:=0; //углы поворотов
Mas[1][1] :=0; Mas[1][2] :=0; Mas[1][3] :=0; Mas[1][4]:=1; //задаем массив точек
Mas[2][1] :=100; Mas[2][2] :=0; Mas[2][3] :=80; Mas[2][4]:=1;
Mas[3][1] :=60; Mas[3][2] :=0; Mas[3][3] :=200; Mas[3][4]:=1;
Mas[4][1] :=-60; Mas[4][2] :=0; Mas[4][3] :=200; Mas[4][4]:=1;
Mas[5][1] :=-100; Mas[5][2] :=0; Mas[5][3] :=80; Mas[5][4]:=1;
Mas[6][1] :=-100; Mas[6][2] :=200; Mas[6][3] :=80; Mas[6][4]:=1;
Mas[7][1] :=0; Mas[7][2] :=200; Mas[7][3] :=0; Mas[7][4]:=1;
Mas[8][1] :=100; Mas[8][2] :=200; Mas[8][3] :=80; Mas[8][4]:=1;
Mas[9][1] :=60; Mas[9][2] :=200; Mas[9][3] :=200; Mas[9][4]:=1;
Mas[10][1]:=-60; Mas[10][2]:=200; Mas[10][3]:=200; Mas[10][4]:=1;
Dop[1][1]:=1; Dop[2][1]:=0; Dop[3][1]:=0; Dop[4][1]:=0; //задаем матрицу преобразования
Dop[1][2]:=0; Dop[2][2]:=1; Dop[3][2]:=0; Dop[4][2]:=0; //и дополнительные матрицы
Dop[1][3]:=0; Dop[2][3]:=0; Dop[3][3]:=1; Dop[4][3]:=0; //единичными матрицами
Dop[1][4]:=0; Dop[2][4]:=0; Dop[3][4]:=0; Dop[4][4]:=1;
//матрица для поворота вокруг Оx
DopX[1][1]:=1; DopX[2][1]:=0; DopX[3][1]:=0; DopX[4][1]:=0;
DopX[1][2]:=0; DopX[2][2]:=1; DopX[3][2]:=0; DopX[4][2]:=0;
DopX[1][3]:=0; DopX[2][3]:=0; DopX[3][3]:=1; DopX[4][3]:=0;
DopX[1][4]:=0; DopX[2][4]:=0; DopX[3][4]:=0; DopX[4][4]:=1;
//матрица для поворота вокруг Оу
DopY[1][1]:=1; DopY[1][2]:=0; DopY[1][3]:=0; DopY[1][4]:=0;
DopY[2][1]:=0; DopY[2][2]:=1; DopY[2][3]:=0; DopY[2][4]:=0;
DopY[3][1]:=0; DopY[3][2]:=0; DopY[3][3]:=1; DopY[3][4]:=0;
DopY[4][1]:=0; DopY[4][2]:=0; DopY[4][3]:=0; DopY[4][4]:=1;
//матрица для поворота вокруг Оz
DopZ[1][1]:=1; DopZ[1][2]:=0; DopZ[1][3]:=0; DopZ[1][4]:=0;
DopZ[2][1]:=0; DopZ[2][2]:=1; DopZ[2][3]:=0; DopZ[2][4]:=0;
DopZ[3][1]:=0; DopZ[3][2]:=0; DopZ[3][3]:=1; DopZ[3][4]:=0;
DopZ[4][1]:=0; DopZ[4][2]:=0; DopZ[4][3]:=0; DopZ[4][4]:=1;
end;
procedure TForm1.StartPosClick(Sender: TObject);
begin
Form1.FormCreate(Sender);
end;
procedure TForm1.RotateXClick(Sender: TObject);
begin
FiYZ:=0.05; //ную матрицу
DopX[2][2]:=Cos(FiYZ); //находим значения дополнительной матрицы исполь-
DopX[3][2]:=Sin(FiYZ); //зуя значения угла поворота относительно оси Ox
DopX[2][3]:=-DopX[3][2];
DopX[3][3]:=DopX[2][2];
end;
procedure TForm1.RotateYClick(Sender: TObject);
begin
FiXZ:=0.05;
DopY[1][1]:=Cos(FiXZ); //находим значения дополнительной матрицы исполь-
DopY[1][3]:=Sin(FiXZ); //зуя значения угла поворота относительно оси Oy
DopY[3][1]:=-DopY[1][3];
DopY[3][3]:=DopY[1][1];
end;
procedure TForm1.RotateZClick(Sender: TObject);
begin
FiXY:=-0.05;
DopZ[1][1]:=Cos(FiXY); //находим значения дополнительной матрицы исполь-
DopZ[2][1]:=Sin(FiXY); //зуя значения угла поворота относительно оси Oz.
DopZ[1][2]:=-DopZ[2][1];
DopZ[2][2]:=DopZ[1][1];
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
Dop[3][4]:=-5;
end;
procedure TForm1.Button4Click(Sender: TObject);
begin
Dop[2][4]:=-5;
end;
procedure TForm1.Button5Click(Sender: TObject);
begin
Dop[1][4]:=-5;
end;
procedure TForm1.Button1Click(Sender: TObject);
var //тельно одной из координатных
i :integer;
begin
for i:=1 to 10 do //динату, которая не задает дан-
Mas[i][3]:=-Mas[i][3];
end;
procedure TForm1.Button2Click(Sender: TObject);
var
i :integer;
begin
for i:=1 to 10 do
Mas[i][2]:=-Mas[i][2];
end;
procedure TForm1.Button6Click(Sender: TObject);
var
i :integer;
begin
for i:=1 to 10 do
Mas[i][4]:=-Mas[i][4];
end;
procedure TForm1.Button7Click(Sender: TObject);
begin
Dop[4][4]:=0.99;
end;
procedure TForm1.Button8Click(Sender: TObject);
begin
Dop[4][4]:=1.01;
end;
procedure TForm1.Button9Click(Sender: TObject);
begin
Dop[4][4]:=1;
end;
end.