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]

}

ВЫВОД

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


 

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

30112. Хромосомная теория наследственности (Т. X. Морган и др.) 18.08 KB
  Хромосомная теория наследственности Т. Доказано что количество наследственных признаков организма значительно превышает число хромосом гаплоидного набора. Так в гаплоидном наборе классического объекта генетических исследований мухидрозофилы есть только четыре хромосомы но число наследственных признаков и соответственно генов которые их определяют несомненно значительно больше. Это означает что в каждой хромосоме находится много генов.
30113. Генетика пола, Искусственная регуляция пола 42.68 KB
  Генетика пола Пол это совокупность признаков и свойств организма определяющих его участие в размножении. Пол особи может определяться: а до оплодотворения яйцеклетки сперматозоидом прогамное определение пола; б в момент оплодотворения сингамное определение пола; в после оплодотворения эпигамное определение пола. У морского кольчатого червя бонеллия определение пола происходит в процессе онтогенеза: если личинка садится на дно из нее развивается самка а если...
30114. Цитоплазматическое наследование 12.96 KB
  Цитоплазматическое наследование: Для того чтобы та или иная структура могла выполнять роль материального носителя наследственности и обеспечивать количественные закономерности наследования как уже было сказано она должна обладать тремя основными свойствами: выполнять жизненно важные функции в метаболизме клетки обладать способностью к самовоспроизведению точно распределяться в дочерние клетки при делении. Так центриоли участвуют в образовании веретена при делении клетки пластиды обеспечивают некоторые синтетические процессы митохондрии...
30115. Взаимодействие генов 14.76 KB
  Полное доминирование заключается в том что в гетерозиготе полученной при скрещивании представителей чистых линий различающихся по одной пара альтернативных признаков один из двух аллелей не проявляет своего действия. В фенотипе 3 частей проявился доминантный признак а у 1 части рецессивный. При неполном доминировании гибриды первого поколения имеют фенотип укладывающийся в рамки проявления признака между исходными родителями и никогда их не достигающий т. признак может быть любым но не как у представителей чистых линий: меньше...
30116. Инструментальные материалы. Упрочняющая обработка 220 KB
  Инструментальными являются материалы, основное назначение которых - оснащение рабочей части инструментов. К ним относятся инструментальные углеродистые, легированные и быстрорежущие стали, твердые сплавы, минералокерамика, сверхтвердые материалы.
30117. Генные мутации 33.8 KB
  Генные мутации. По последствиям генных мутаций их классифицируют на нейтральные регуляторные и динамические а также на миссенс и нонсенсмутации. Нейтральная мутации молчащая мутация мутация не имеет фенотипического выражения например в результате вырожденности генетического кода. Динамические мутации мутации обусловленные увеличением числа тринуклеотидных повторов в функционально значимых частях гена.
30118. Хромосомные мутации и геномные мутации 16.53 KB
  Хромосомные мутации и геномные мутации. Различают два основных типа хромосомных мутаций: численные хромосомные мутации и структурные хромосомные мутации. В свою очередь численные мутации делятся на анэуплоидии когда мутации выражаются в утрате или появлении дополнительной одной либо нескольких хромосом и полиплоидии когда увеличивается число гаплоидных наборов хромосом. Потерю одной из хромосом называют моносомией а возникновение дополнительной хромосомы у любой пары хромосом трисомией.
30119. Модификационная (фенотипическая) изменчивость 16.63 KB
  Характеристика: обратимость изменения исчезают при смене специфических условий окружающей среды спровоцировавших их групповой характер изменения в фенотипе не наследуются наследуется норма реакции генотипа статистическая закономерность вариационных рядов затрагивает фенотип при этом не затрагивая сам генотип.По размаху нормы реакции узкая более характерна для качественных признаков широкая более характерна для количественных признаков 3.По длительности: есть лишь у особи или группы особей которые подверглись влиянию...
30120. Генетика популяций. Генетическая структура популяций и идеальная популяция 37.55 KB
  При описании систем скрещивания в идеальной популяции широко используется понятие панмиксии случайного свободного скрещивания при котором вероятность встречи гамет не зависит ни от генотипа ни от возраста скрещивающихся особей. Если исключить половой отбор то к панмиктической популяции применима концепция гаметного резервуара согласно которой в популяции в период размножения формируется гаметный резервуар генный пул включающий банк женских гамети банк...