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]

}

ВЫВОД

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


 

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

3707. Акционерная собственность и проблемы её формирования в Российской Федерации 265 KB
  Экономическое и юридическое содержание акционерной формы собственности. Право собственности закрепляет материальную основу любого общества - экономические отношения собственности. Поэтому отношения собственности и право собственности является юр...
3708. Астрология. Наука о звездах 194 KB
  Земля – одно из бесчисленных небесных тел. Чтобы лучше изучить Землю, надо знать и то, что происходит на небе. Поэтому уже в древние времена появилась практическая необходимость в науке о небесных явлениях. Ведь жизнь людей на Земле во...
3709. Антропонимы как средство сатиры и юмора в рассказах А.П. Чехова 149.5 KB
  В своей работе я анализирую антропонимическую систему в рассказах раннего творчества А.П. Чехова ( 1880 – 1883 гг. ) и антропонимическую систему в рассказах более позднего периода (1886 – 1900 гг.). Ранние рассказы: «Письмо к ученому соседу»...
3710. Кредитные отношения между коммерческим банком и Нимировским спиртзаводом 1.66 MB
  Банковская система - одна из важнейших и неотъемлемых структур рыночной экономики. Поэтому сегодня, в условиях перехода Украины к рыночным отношениям, резко возрастает к ней внимание и интерес. Это обусловлено тем, что в Украине совершается...
3711. Особенности банковского аудита 163 KB
  Сущность, необходимость и виды аудита. Профессия аудитора известна с глубокой древности. Еще примерно в 200 г. до н.э. квесторы (должностные лица, ведавшие финансовыми и судебными делами Римской империи) осуществляли контроль за государственными ...
3712. Бактериологическое (биологическое) оружие 135.5 KB
  Бактериологическое оружие (биологическое) является средством массового поражения людей, животных и уничтожения сельскохозяйственных культур. Основу его поражающего действия составляют бактериальные средства, к которым относятся болезнетворн...
3713. Current asset management in the enterprise 172.91 KB
  Current asset management in the enterprise The crisis of 2008 still affects business-to-business companies. Many of them have problems with current assets in general and with accounts receivable in particular. In a given paper a field research is co...
3714. Флористическое разнообразие мезмайской котловины (Северо-Западный Кавказ) 258.41 KB
  Флористическое разнообразие мезмайской котловины (Северо-Западный Кавказ) Введение Северо-Западный Кавказ - один из богатейших во флористическом отношении регионов Российской Федерации, насчитывающий около 2500 видов дикорастущих аборигенных растени...
3715. Теоретические основы специальной (коррекционной) педагогики как науки 207 KB
  Теоретические основы специальной (коррекционной) педагогики как науки Тема 1. Введение. Специальная (коррекционная) педагогика как наука Тема 2. Связь специальной (коррекционной) педагогики с другими науками Тема 3. Понимание отклонений в разви...