You are on page 1of 10

Федеральное агентство по образованию

Государственное образовательное учреждение высшего


профессионального образования
«ТОМСКИЙ ПОЛИТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ»

Факультет автоматики и вычислительной техники


Направление (специальность) – Информационные системы

Кафедра вычислительной техники

Базовые алгоритмы 2D-геометрии


Отчет по лабораторной работе № 3

по дисциплине компьютерная геометрия и графика

Исполнитель
студент, 8960 _________ Е. И. Блеч
(подпись)
_____________________
(дата)

Руководитель
доцент, к.т.н _________ О.С. Токарева
(подпись)
_____________________
(дата)

Томск –2009

Цель работы: Изучить Базовые алгоритмы 2D-геометрии.


Требования:
- управление организовать через интерфейсные элементы (меню, кнопки и
т.д.);
- реализация всех преобразований через перемножение матриц, используя
однородные координаты;
- полное масштабирование реализовать через коэффициент s матрицы
преобразований.

- предусмотреть возможность восстановления исходного положения фигуры;


- предусмотреть возможность выполнить композицию преобразований.

Задание №1

• Отразить относительно оси Y= -X;


• увеличить на 50%;
• повернуть на 45 градусов по часовой стрелке.
1. Исходный текст программы:
//---------------------------------------------------------------------------
#include <vcl.h>
#include <math.h>
#include <string.h>
#include <stdio.h>

#pragma hdrstop

#include "unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TMainForm *MainForm;
const n = 1031;
const POINT_IN_CIRCLE = 1024;
double Matr[n][2], // Матрица точек пространства старая
MatrNew[n][2]; // преобразованная
double Preob[3][3];
int x0, y0,
ImgWidth, ImgHeight, R;

//---------------------------------------------------------------------------
__fastcall TMainForm::TMainForm(TComponent* Owner)
: TForm(Owner)
{
string str_buf [4];

EditDX->Enabled = false;
EditDY->Enabled = false;
ImgWidth = Img->Width;
ImgHeight = Img->Height;
x0 = ImgWidth/2,
y0 = ImgHeight/2;
R = 50;
double a;
int deltaR = 70;

// Координаты окружности
for (int i = 0; i < POINT_IN_CIRCLE; i++)
{
a = (double) i * 2.0 * M_PI / (double) n;
MatrNew[i][0] = Matr[i][0] = -deltaR + R * cos(a);
MatrNew[i][1] = Matr[i][1] = -deltaR + R * sin(a);
}
// Координаты прямоугольника
MatrNew[1024][0] = Matr[1024][0] = -10; // x4
MatrNew[1024][1] = Matr[1024][1] = -90; // y4
MatrNew[1025][0] = Matr[1025][0] = -10; // x3
MatrNew[1025][1] = Matr[1025][1] = -10; // y3
MatrNew[1026][0] = Matr[1026][0] = -95; // x2
MatrNew[1026][1] = Matr[1026][1] = -10; // y2
MatrNew[1027][0] = Matr[1027][0] = -95; // x1
MatrNew[1027][1] = Matr[1027][1] = -90; // y1

// Координаты треугольника
MatrNew[1028][0] = Matr[1028][0] = -160;
MatrNew[1028][1] = Matr[1028][1] = -65;
MatrNew[1029][0] = Matr[1029][0] = -15;
MatrNew[1029][1] = Matr[1029][1] = 45;
MatrNew[1030][0] = Matr[1030][0] = -80;
MatrNew[1030][1] = Matr[1030][1] = 80;
DrawForm(MatrNew);
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::Multiplication(double D[][2],double Tr[][3])
{
double A[n][3];
for(int i = 0; i < n; i++)
{
A[i][0] = D[i][0];
A[i][1] = D[i][1];
A[i][2] = 1;
}
double C[n][3];
double buf = 0;
for(int i = 0; i < n; i++)
for(int j = 0; j < 3; j++)
{
for(int k = 0; k < 3; k++)
{
buf += A[i][k]*Tr[k][j];
}
C[i][j] = buf;
buf = 0;
}
for(int i = 0; i < n; i++)
for(int j = 0; j < 2; j++)
D[i][j] = C[i][j];
}

void __fastcall TMainForm::DrawForm(double Mas[][2])


{
int MasN[n][2];
for(int i = 0; i < n; i++)
{
MasN[i][0] = x0 + Mas[i][0];
MasN[i][1] = y0 + Mas[i][1];
}
TCanvas* C = Img->Canvas;
// Снаружи квадрат
C->Pen->Color = clBlack;
C->Rectangle(0,0,ImgWidth,ImgHeight);
C->MoveTo(ImgWidth/2,10);
C->LineTo(ImgWidth/2,ImgHeight-10);
C->MoveTo(10, ImgHeight/2);
C->LineTo(ImgWidth-10,ImgHeight/2);
C->Brush->Style = bsClear;
C->MoveTo(MasN[0][0], MasN[0][1]);

// Окружность
for (int i = 1; i < POINT_IN_CIRCLE; i++)
{
C->LineTo(MasN[i][0], MasN[i][1]);
}
C->LineTo(MasN[0][0], MasN[0][1]);

// Квадрат
C->Brush->Style = bsSolid;
C->MoveTo(MasN[1024][0],MasN[1024][1]);
C->LineTo(MasN[1025][0],MasN[1025][1]);
C->LineTo(MasN[1026][0],MasN[1026][1]);
C->LineTo(MasN[1027][0],MasN[1027][1]);
C->LineTo(MasN[1024][0],MasN[1024][1]);
// Треугольник
Img->Canvas->Pen->Width=2;
C->MoveTo(MasN[1028][0],MasN[1028][1]);
C->LineTo(MasN[1029][0],MasN[1029][1]);
C->LineTo(MasN[1030][0],MasN[1030][1]);
C->LineTo(MasN[1028][0],MasN[1028][1]);

Img->Canvas->Pen->Width=1;

}
//---------------------------------------------------------------------------

void __fastcall TMainForm::InvBtnXClick(TObject *Sender)


{
Preob[0][0] = 1; Preob[0][1] = 0; Preob[0][2] = 0;
Preob[1][0] = 0; Preob[1][1] = -1; Preob[1][2] = 0;
Preob[2][0] = 0; Preob[2][1] = 0; Preob[2][2] = 1;
Multiplication(MatrNew,Preob);
DrawForm(MatrNew);
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::InvBtnYClick(TObject *Sender)


{
Preob[0][0] = -1; Preob[0][1] = 0; Preob[0][2] = 0;
Preob[1][0] = 0; Preob[1][1] = 1; Preob[1][2] = 0;
Preob[2][0] = 0; Preob[2][1] = 0; Preob[2][2] = 1;
Multiplication(MatrNew,Preob);
DrawForm(MatrNew);
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::PreobBtnClick(TObject *Sender)


{
int dx, dy;

dx = (int)StrToFloat(DxEdit->Text);
dy = (int)StrToFloat(DyEdit->Text);

Preob[0][0] = 1; Preob[0][1] = 0; Preob[0][2] = 0;


Preob[1][0] = 0; Preob[1][1] = 1; Preob[1][2] = 0;
Preob[2][0] = dx; Preob[2][1] = dy; Preob[2][2] = 1;
Multiplication(MatrNew,Preob);
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::InvBtnXYClick(TObject *Sender)
{
Preob[0][0] = 0; Preob[0][1] = -1; Preob[0][2] = 0;
Preob[1][0] = -1; Preob[1][1] = 0; Preob[1][2] = 0;
Preob[2][0] = 0; Preob[2][1] = 0; Preob[2][2] = -1;
Multiplication(MatrNew,Preob);
DrawForm(MatrNew);
}
//---------------------------------------------------------------------------
//масштабирование по X и Y +
void __fastcall TMainForm::ScaleBtnClick(TObject *Sender)
{
double kx, ky;
kx = double(StrToFloat(ScEditX->Text));
ky = double(StrToFloat(ScEditY->Text));
// (kx < ky )? scale = kx : scale = ky;
Preob[0][0] = kx; Preob[0][1] = 0; Preob[0][2] = 0; //kx
Preob[1][0] = 0; Preob[1][1] = ky; Preob[1][2] = 0; //ky
Preob[2][0] = 0; Preob[2][1] = 0; Preob[2][2] = 1;
Multiplication(MatrNew,Preob);
DrawForm(MatrNew);
}
//---------------------------------------------------------------------------
//сброс изменений +
void __fastcall TMainForm::ResetBtnClick(TObject *Sender)
{
for(int i = 0; i < n; i++)
{
MatrNew[i][0] = Matr[i][0];
MatrNew[i][1] = Matr[i][1];
}
DrawForm(MatrNew);
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::RdBtnDClick(TObject *Sender)
{
EditDX->Enabled = true;
EditDY->Enabled = true;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::RdBtnCClick(TObject *Sender)


{
EditDX->Enabled = false;
EditDY->Enabled = false;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::TurnBtnClick(TObject *Sender)


{
double a = StrToInt(EditAngle->Text);

a = M_PI/180*a;
if(RdBtnC->Checked)
{
Preob[0][0] = cos(a); Preob[0][1] = sin(a); Preob[0][2] = 0;
Preob[1][0] = -sin(a); Preob[1][1] = cos(a); Preob[1][2] = 0;
Preob[2][0] = 0; Preob[2][1] = 0; Preob[2][2] = 1;
Multiplication(MatrNew,Preob);
DrawForm(MatrNew);
}
else
{
int m = StrToInt(EditDX->Text),
n = -StrToInt(EditDY->Text);
Preob[0][0] = 1; Preob[0][1] = 0; Preob[0][2] = 0;
Preob[1][0] = 0; Preob[1][1] = 1; Preob[1][2] = 0;
Preob[2][0] = -m; Preob[2][1] = -n; Preob[2][2] = 1;
Multiplication(MatrNew,Preob);
Preob[0][0] = cos(a); Preob[0][1] = sin(a); Preob[0][2] = 0;
//матрица поворота
Preob[1][0] = -sin(a); Preob[1][1] = cos(a); Preob[1][2] = 0;
Preob[2][0] = 0; Preob[2][1] = 0; Preob[2][2] = 1;
Multiplication(MatrNew,Preob);
Preob[0][0] = 1; Preob[0][1] = 0; Preob[0][2] = 0; //матрица-
результат
Preob[1][0] = 0; Preob[1][1] = 1; Preob[1][2] = 0;
Preob[2][0] = m; Preob[2][1] = n; Preob[2][2] = 1;
Multiplication(MatrNew,Preob);
DrawForm(MatrNew);
}
}
//---------------------------------------------------------------------------
2. Выполнение программы:
Исходное состояние:

Масштабируем в 1,5 раза – то есть увеличиваем на 50%:


Поворот на 45 градусов по часовой стрелке:

Отразить относительно оси Y= -X;


Композиция преобразований:
Масштабировать в 1,5 раза и повернуть на 45 градусов:

Вывод:
Реализовано управление через интерфейсные элементы, все преобразования
через матрицу преобразований, предусмотрена возможность восстановления
исходного положения фигуры, и выполнение композиции преобразований.