42253

Выполнение базовых преобразований на плоскости

Лабораторная работа

Информатика, кибернетика и программирование

Трансляция точки выполняется путем добавления смещения [m n] к ее координатам [x y], в результате чего получается точка с новыми координатами. Для объекта, описываемого множеством точек, все точки объекта перемещаются на одинаковые расстояния вдоль параллельных прямых. В матричной форме трансляция выполняется путем умножения однородных координат точки на матрицу трансляции

Русский

2013-10-28

98.5 KB

3 чел.

ФЕДЕРАЛЬНОЕ АГЕНТСТВО ПО ОБРАЗОВАНИЮ

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

«НАЦИОНАЛЬНЫЙ ИССЛЕДОВАТЕЛЬСКИЙ

ТОМСКИЙ ПОЛИТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ»

Институт кибернетики

Информационные системы и технологии

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

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

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

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

Студент

гр. 8990             ____________ А.С. Цуркова

                   (подпись)

                                       _    

                      (дата)

Руководитель

доцент каф. ВТ____________ О.С. Токарева

                   (подпись)

                             _

                (дата)

Томск – 2012

Цель работы

Изучить способы выполнения базовых преобразований на плоскости.

Задание

Написать программу, выполняющие следующие функции:

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

Требования:

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

• Повернуть относительно точки L на 30 градусов по часовой стрелке.

Теоретические положения

В ходе выполнения данной работы были созданы массивы trgl[3][3],okr[9][3],oval[9][3] для хранения точек треугольника, окружности и овала соответственно. Был реализован пересчет мировых координат в экранные: perevod() .

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

Трансляция точки выполняется путем добавления смещения [m n] к ее координатам [x y], в результате чего получается точка с новыми координатами. Для объекта, описываемого множеством точек, все точки объекта перемещаются на одинаковые расстояния вдоль параллельных прямых. В матричной форме трансляция выполняется путем умножения однородных координат точки на матрицу трансляции:

.

Отражение – преобразование, генерирующее зеркальное отображение объекта.

- отражение относительно оси x (y=0),

 - отражение относительно оси y (x=0),

- отражение относительно начала координат,

- отражение относительно оси y=x,

 - отражение относительно оси y=x.

Двумерный поворот – перемещение объекта по круговой траектории на плоскости xoy. В этом случае объект поворачивается относительно оси вращения, перпендикулярной плоскости xoy. Для двумерного поворота задается точка, вокруг которой будет производится поворот и угол вращения. Поворот точки на угол φ вокруг начала координат выполняется путем умножения однородных координат точки на матрицу поворота R:

.

В компьютерной графике поворот на положительный угол φ выполняется против часовой стрелки.

Масштабирование выполняется путем умножения однородных координат точки на матрицу масштабирования S:

, где sx, sy – любые положительные числа, sx – коэффициент масштабирования по x, sy – коэффициент масштабирования по y. При sx>1 и sy>1 масштаб увеличивается, при sx<1 (sx>0) и sy<1 (sy >0)–  уменьшается.

Все преобразования были реализованы в среде C++ Builder при помощи синтаксиса языка C++.

Текст программы

#include <vcl.h>

#include <stdio.h>

#include <math.h>

#pragma hdrstop

#include "lab3.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm1 *Form1;

float trgl[3][3],okr[9][3],oval[9][3];

float trglR[3][3],okrR[9][3],ovalR[9][3];

void novii();

void trglris();

void okrris();

void ovalris();

void novkord();

void perevod();

int pointpov[1][2];

float matrix[3][3],massiv[42];

void reading();

void multiply();

//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{

}

//---------------------------------------------------------------------------

void perevod()

{

for (int i=0;i<3;i++)

{

 trglR[i][0]=trgl[i][0]*10+Form1->Plosk->Width/2;

 trglR[i][1]=Form1->Plosk->Height/2-trgl[i][1]*10;

}

for (int i=0;i<9;i++)

{

 okrR[i][0]=okr[i][0]*10+Form1->Plosk->Width/2;

 okrR[i][1]=Form1->Plosk->Height/2-okr[i][1]*10;

}

for (int i=0;i<9;i++)

{

 ovalR[i][0]=oval[i][0]*10+Form1->Plosk->Width/2;

 ovalR[i][1]=Form1->Plosk->Height/2-oval[i][1]*10;

}

}

//---------------------------------------------------------------------------

void trglris()

{

Form1->Plosk->Canvas->MoveTo(trglR[0][0],trglR[0][1]);

Form1->Plosk->Canvas->LineTo(trglR[1][0],trglR[1][1]);

Form1->Plosk->Canvas->LineTo(trglR[2][0],trglR[2][1]);

Form1->Plosk->Canvas->LineTo(trglR[0][0],trglR[0][1]);

}

//--------------------------------------------------------------------------

void okrris()

{

Form1->Plosk->Canvas->MoveTo(okrR[0][0],okrR[0][1]);

for (int i=1;i<8;i++)

{

 Form1->Plosk->Canvas->LineTo(okrR[i+1][0],okrR[i+1][1]);

}

Form1->Plosk->Canvas->LineTo(okrR[0][0],okrR[0][1]);

}

//-------------------------------------------------------------------------

void ovalris()

{

Form1->Plosk->Canvas->MoveTo(ovalR[0][0],ovalR[0][1]);

for (int i=1;i<8;i++)

{

 Form1->Plosk->Canvas->LineTo(ovalR[i][0],ovalR[i][1]);

}

Form1->Plosk->Canvas->LineTo(ovalR[0][0],ovalR[0][1]);

}

//-------------------------------------------------------------------------

void novkord()

{

Form1->Plosk->Canvas->Brush->Color=clWhite;

Form1->Plosk->Canvas->FillRect(Form1->Canvas->ClipRect);

Form1->Plosk->Canvas->Rectangle((pointpov[0][0]*10+Form1->Plosk->Width/2)

       ,(Form1->Plosk->Height/2-pointpov[0][1]*10)

       ,(pointpov[0][0]*10+Form1->Plosk->Width/2)+3

       ,(Form1->Plosk->Height/2-pointpov[0][1]*10)+3);

Form1->Plosk->Canvas->MoveTo(0,(Form1->Plosk->Height)/2);

Form1->Plosk->Canvas->LineTo(Form1->Plosk->Width,(Form1->Plosk->Height)/2);

int incr=0;

for (int i=(Form1->Plosk->Width)/2;;incr=incr+10)

{

 if (((i-incr)>=0)&&((i+incr)<=(Form1->Plosk->Width)))

   {

 Form1->Plosk->Canvas->MoveTo(i-incr,(Form1->Plosk->Height)/2-3);

 Form1->Plosk->Canvas->LineTo(i-incr,(Form1->Plosk->Height)/2+3);

 Form1->Plosk->Canvas->MoveTo(i+incr,(Form1->Plosk->Height)/2-3);

 Form1->Plosk->Canvas->LineTo(i+incr,(Form1->Plosk->Height)/2+3);

   }

 else break;

}

Form1->Plosk->Canvas->MoveTo(Form1->Plosk->Width-10,(Form1->Plosk->Height)/2-4);

Form1->Plosk->Canvas->LineTo(Form1->Plosk->Width,(Form1->Plosk->Height)/2);

Form1->Plosk->Canvas->MoveTo(Form1->Plosk->Width-10,(Form1->Plosk->Height)/2+4);

Form1->Plosk->Canvas->LineTo(Form1->Plosk->Width,(Form1->Plosk->Height)/2);

//---------------------------------------------------------//

Form1->Plosk->Canvas->MoveTo((Form1->Plosk->Width)/2,0);

Form1->Plosk->Canvas->LineTo((Form1->Plosk->Width)/2,Form1->Plosk->Height);

incr=0;

for (int i=(Form1->Plosk->Height)/2;;incr=incr+10)

{

 if (((i-incr)>=0)&&((i+incr)<=(Form1->Plosk->Height)))

   {

 Form1->Plosk->Canvas->MoveTo((Form1->Plosk->Width)/2-3,i-incr);

 Form1->Plosk->Canvas->LineTo((Form1->Plosk->Width)/2+3,i-incr);

 Form1->Plosk->Canvas->MoveTo((Form1->Plosk->Width)/2-3,i+incr);

 Form1->Plosk->Canvas->LineTo((Form1->Plosk->Width)/2+3,i+incr);

   }

 else break;

}

Form1->Plosk->Canvas->MoveTo((Form1->Plosk->Width)/2-4,10);

Form1->Plosk->Canvas->LineTo((Form1->Plosk->Width)/2,0);

Form1->Plosk->Canvas->MoveTo((Form1->Plosk->Width)/2+4,10);

Form1->Plosk->Canvas->LineTo((Form1->Plosk->Width)/2,0);

}

//-----------------------------------------------------------------------------

void novii()

{

for(int i=0;i<3;i++)

 for(int j=0;j<3;j++)matrix[i][j]=0;

trgl[0][0]=massiv[0]; trgl[0][1]=massiv[1];

trgl[1][0]=massiv[2];   trgl[1][1]=massiv[3];

trgl[2][0]=massiv[4];   trgl[2][1]=massiv[5];

okr[0][0]=massiv[6];   okr[0][1]=massiv[7]; okr[0][2]=1;

okr[1][0]=massiv[8];   okr[1][1]=massiv[9]; okr[1][2]=1;

okr[2][0]=massiv[10];   okr[2][1]=massiv[11]; okr[2][2]=1;

okr[3][0]=massiv[12];   okr[3][1]=massiv[13]; okr[3][2]=1;

okr[4][0]=massiv[14];   okr[4][1]=massiv[15]; okr[4][2]=1;

okr[5][0]=massiv[16];   okr[5][1]=massiv[17]; okr[5][2]=1;

okr[6][0]=massiv[18];   okr[6][1]=massiv[19]; okr[6][2]=1;

okr[7][0]=massiv[20];   okr[7][1]=massiv[21]; okr[7][2]=1;

okr[8][0]=massiv[22];   okr[8][1]=massiv[23]; okr[8][2]=1;

oval[0][0]=massiv[24];   oval[0][1]=massiv[25]; oval[0][2]=1;

oval[1][0]=massiv[26];   oval[1][1]=massiv[27]; oval[1][2]=1;

oval[2][0]=massiv[28];   oval[2][1]=massiv[29]; oval[2][2]=1;

oval[3][0]=massiv[30];   oval[3][1]=massiv[31]; oval[3][2]=1;

oval[4][0]=massiv[32];   oval[4][1]=massiv[33]; oval[4][2]=1;

oval[5][0]=massiv[34];   oval[5][1]=massiv[35]; oval[5][2]=1;

oval[6][0]=massiv[36];   oval[6][1]=massiv[37]; oval[6][2]=1;

oval[7][0]=massiv[38];   oval[7][1]=massiv[39]; oval[7][2]=1;

pointpov[0][0]=massiv[40]; pointpov[0][1]=massiv[41];

perevod();

trglris();

okrris();

ovalris();

}

//---------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)

{

reading();

pointpov[0][0]=1; pointpov[0][1]=-2;

novkord();

novii();

}

//---------------------------------------------------------------------------

void __fastcall TForm1::retrnClick(TObject *Sender)

{

Form1->Plosk->Canvas->Brush->Color=clWhite;

Form1->Plosk->Canvas->FillRect(Canvas->ClipRect);

novkord();

novii();

}

//---------------------------------------------------------------------------

void __fastcall TForm1::SdvigVNClick(TObject *Sender)

{

Form1->Canvas->Brush->Color=clBlack;

novkord();

matrix[0][0]=1;

matrix[0][1]=0;

matrix[1][0]=0;

matrix[1][1]=1;

matrix[0][2]=0;

matrix[1][2]=0;

if(Form1->CheckBox1->Checked==true)matrix[2][1]=2;

else matrix[2][1]=-2;

matrix[2][0]=0;

matrix[2][2]=1;

trgl[0][2]=1;

trgl[1][2]=1;

trgl[2][2]=1;

multiply();

perevod();

trglris();

okrris();

ovalris();

}

//---------------------------------------------------------------------------

void __fastcall TForm1::SdvigPLClick(TObject *Sender)

{

Form1->Canvas->Brush->Color=clBlack;

novkord();

matrix[0][0]=1;

matrix[0][1]=0;

matrix[1][0]=0;

matrix[1][1]=1;

matrix[0][2]=0;

matrix[1][2]=0;

if(Form1->CheckBox2->Checked==true)matrix[2][0]=2;

else matrix[2][0]=-2;

matrix[2][1]=0;

matrix[2][2]=1;

trgl[0][2]=1;

trgl[1][2]=1;

trgl[2][2]=1;

multiply();

perevod();

trglris();

okrris();

ovalris();

}

//---------------------------------------------------------------------------

void __fastcall TForm1::povorotClick(TObject *Sender)

{

novkord();

double ugol;

ugol=M_PI/6;

matrix[0][0]=cos(ugol);

matrix[0][1]=-sin(ugol);

matrix[1][0]=sin(ugol);

matrix[1][1]=cos(ugol);

matrix[0][2]=0;

matrix[1][2]=0;

matrix[2][0]=-pointpov[0][0]*cos(ugol)-pointpov[0][1]*sin(ugol)+pointpov[0][0];

matrix[2][1]=pointpov[0][0]*sin(ugol)-pointpov[0][1]*cos(ugol)+pointpov[0][1];

matrix[2][2]=1;

trgl[0][2]=1;

trgl[1][2]=1;

trgl[2][2]=1;

multiply();

perevod();

trglris();

okrris();

ovalris();

}

//---------------------------------------------------------------------------

void __fastcall TForm1::OtrXClick(TObject *Sender)

{

Form1->Plosk->Canvas->Pen->Color=clWhite;

perevod();

trglris();

okrris();

ovalris();

matrix[0][0]=1;

matrix[0][1]=0;

matrix[1][0]=0;

matrix[1][1]=-1;

multiply();

Form1->Plosk->Canvas->Pen->Color=clBlack;

perevod();

trglris();

okrris();

ovalris();

}

//---------------------------------------------------------------------------

void __fastcall TForm1::otrYClick(TObject *Sender)

{

Form1->Plosk->Canvas->Pen->Color=clWhite;

perevod();

trglris();

okrris();

ovalris();

matrix[0][0]=-1;

matrix[0][1]=0;

matrix[1][0]=0;

matrix[1][1]=1;

multiply();

Form1->Plosk->Canvas->Pen->Color=clBlack;

perevod();

trglris();

okrris();

ovalris();

}

//---------------------------------------------------------------------------

void __fastcall TForm1::ScaleClick(TObject *Sender)

{

Form1->Plosk->Canvas->Pen->Color=clWhite;

perevod();

trglris();

okrris();

ovalris();

matrix[0][1]=0;

matrix[1][0]=0;

if (Form1->CheckBox3->Checked==true)

  {

matrix[0][0]=2.0;

matrix[1][1]=2.0;

  }

else

  {

matrix[0][0]=0.5;

matrix[1][1]=0.5;

  }

multiply();

Form1->Plosk->Canvas->Pen->Color=clBlack;

perevod();

trglris();

okrris();

ovalris();

}

//---------------------------------------------------------------------------

void __fastcall TForm1::FormKeyPress(TObject *Sender, char &Key)

{

if(Key=='1')Form1->retrnClick(Sender);

if(Key=='2')Form1->povorotClick(Sender);

if(Key=='3')Form1->SdvigVNClick(Sender);

if(Key=='4')Form1->SdvigPLClick(Sender);

if(Key=='5')Form1->OtrXClick(Sender);

if(Key=='6')Form1->otrYClick(Sender);

if(Key=='7')Form1->ScaleClick(Sender);

}

//---------------------------------------------------------------------------

void reading()

{

TFileStream *file=new TFileStream("figuri.dat",fmOpenRead);

TStringList *list=new TStringList;

list->LoadFromStream(file);

AnsiString Spisok=list->Text;

delete list;

delete file;

AnsiString temp="";

int mas[42],i1=0;

for (int i = 0; i < (Spisok.Length()-2); i++)

{

 if ((Spisok.c_str()[i] != ' '))

   temp=temp+Spisok.c_str()[i];

 else

 {

  mas[i1] = StrToInt(temp);

  temp = "";

  i1++;

 }

}

for (int i=0;i<42;i++)

   massiv[i]=mas[i]/10;

}

//----------------------------------------------------------------------------

void multiply ()

{

float tmpshape[3][3];

for (int k = 0; k < 3; k++)

for (int i = 0; i < 3; i++)

{

  tmpshape[k][i] = 0;

  for (int j = 0; j < 3; j++)

  {

 tmpshape[k][i] =tmpshape[k][i]+ matrix[j][i]*trgl[k][j];

  }

}

 for (int i = 0; i < 3; i++)

for (int j = 0; j < 2; j++) trgl[i][j]=tmpshape[i][j];

float tmpokr[9][3];

 for (int k = 0; k < 9; k++)

for (int i = 0; i < 3; i++)

{

  tmpokr[k][i] = 0;

  for (int j = 0; j < 3; j++)

  {

 tmpokr[k][i] =tmpokr[k][i]+ matrix[j][i]*okr[k][j];

  }

}

 for (int i = 0; i < 9; i++)

for (int j = 0; j < 2; j++) okr[i][j]=tmpokr[i][j];

 float tmpoval[9][3];

 for (int k = 0; k < 9; k++)

for (int i = 0; i < 3; i++)

{

  tmpoval[k][i] = 0;

  for (int j = 0; j < 3; j++)

  {

 tmpoval[k][i] =tmpoval[k][i]+ matrix[j][i]*oval[k][j];

  }

}

 for (int i = 0; i < 9; i++)

for (int j = 0; j < 2; j++) oval[i][j]=tmpoval[i][j]

}

ВЫВОД

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


 

А также другие работы, которые могут Вас заинтересовать

4664. Принципы построения систем допусков и посадок 108 KB
  Принципы построения систем допусков и посадок Системы допусков и посадок Систематизация и классификация используются как универсальный инструмент познания. Изучение некоторой системы объектов всегда основано на выделении их наиболее существенных...
4665. Шероховатость и волнистость поверхностей деталей 318 KB
  Шероховатость и волнистость поверхностей Реальная поверхность, ограничивающая деталь, в отличие от номинальной – геометрически правильной и гладкой – имеет сложный профиль, характеризующийся макрогеометрией (отклонения формы) и микрогеом...
4666. Налоговое право Российской федерации. Курс лекций 515 KB
  Основные понятия и положения налогового кодекса Налоговый кодекс РФ определяет налог как обязательный, индивидуально безвозмездный платеж, взимаемый с организаций и физических лиц в форме отчуждения принадлежащих им на праве собственности...
4667. Стандартизация, взаимозаменяемость, контроль в производстве 90.5 KB
  Стандартизация, взаимозаменяемость, контроль Кустарное производство изделий было чисто индивидуальным и основанным на пригонке деталей друг к другу. Взаимозаменяемость появилась как ответ на необходимость серийно выпускать промышленные изделия. В...
4668. Семьеведение. Учебное пособие для студентов. Познание семьи 485.64 KB
  В пособии рассматривается проблематика семьеведения – области комплексных междисциплинарных исследований любви, семьи и брака. Систематизирован разнообразный научный материал, позволяющий представить различные аспекты семейной жизни. Пособие пр...
4669. Основы проектирования режущего инструмента 1.94 MB
  Протяжки и прошивки. Назначение, классификация, определение и область применения Протяжка – это многолезвийный РИ с рядом последовательно – выступающим одно над другим лезвий в направлении, перпендикулярном к направлению скорости гл...
4670. Основные понятия в области нормирования точности 148 KB
  Основные понятия в области нормирования точности Терминология, применяемая в конкретной области науки или техники, для незнакомого с ней человека весьма напоминает иностранный язык. Если выражения посадка с зазором и посадка с натягом понятны не...
4671. Информационное обеспечение систем управления. Построение запросов при работе с базой данных 710.5 KB
  Тестовая база данных Перед изучением языка SQL необходимо рассмотреть тестовую базу данных на которой будут отрабатываться все запросы. Наша тестовая база данных полностью соответствует рассмотренной в учебном пособии по нормализации данных и создан...
4672. Организационно-технологические модели строительного производства 983 KB
  Организационно-технологические модели строительного производства Задача курсовой работы Задачей курсовой работы является закрепление студентом знаний полученных при прохождении теоретического курса Организационно-технологические модели строительного...