Федеральное Агентство по образованию
ГОУ ВПО Уральский государственный технический университет – УПИ
ТЕПЛОЭНЕРГЕТИЧЕСКИЙ ФАКУЛЬТЕТ
КАФЕДРА ПРИКЛАДНОЙ МАТЕМАТИКИ
КОМПЬЮТЕРНАЯ ГРАФИКА
Преподаватель: Костоусов В. Б.
Студент: Ахмадинуров М.М.
Группа: Т-430
СОДЕРЖАНИЕ
1.1. Классы C++: VECTOR и MATRIX 3
2.1. Классы C++: VECTOR и MATRIX 7
2.1.1.4. Результат работы программы 12
2.1.2.4. Результат работы программы 17
2.2.1.4. Результат работы программы 20
2.2.2.4. Результат работы программы 25
1.1. Классы C++: VECTOR и MATRIX
Построить трехмерную модель тора и визуализировать её используя классы C++ для работы с векторами и преобразованиями: VECTOR и MATRIX.
ТОР (от лат. torus - выпуклость) – геометрическое тело, образуемое вращением окружности вокруг непересекающей его и лежащей в одной с ним плоскости прямой (Рис. 1).
Приблизительную форму тора имеет спасательный круг, баранка.
Рис. 1
Построить трехмерную модель куба с нормалями к граням и визуализировать её используя классы C++ для работы с векторами и преобразованиями: VECTOR и MATRIX.
КУБ (лат. cubus, от греч. kybos) – один из пяти типов правильных многогранников, правильный прямоугольный параллелепипед; имеет 6 квадратных граней, 12 ребер, 8 вершин, в каждой сходится 3 ребра (Рис.2).
Рис. 2
1.2. OpenGL
Поверхность задана формулой:
Z (x, y) = (sin x2 + cos y2 ) xy
Поверхность имеет такой вид (Рис. 3).
Рис. 3
Пружина – модификация тора, получаемая из последнего путем распространения вдоль оси OZ, при этом большой радиус не меняется (Рис. 4).
Рис. 4
x = (R + r cos(f)) sin(k w),
y = (R + r cos(f)) cos(k w),
z = r sin(f) + k w,
где k – константа, определяющая шаг витков спирали по высоте. Углы f и w должны изменяться в полном круговом диапазоне, например от 0 до 360.
2.1. Классы C++: VECTOR и MATRIX
Строить тор будем, опираясь на его определение. Тор – геометрическое тело, образуемое вращением окружности вокруг непересекающей его и лежащей в одной с ним плоскости прямой.
То есть задача построения тора разбивается на две подзадачи:
1. Определение координат окружности;
2. Вращение окружности вокруг вектора w, находящегося в центре тора, при этом сохраняя координаты вращающейся окружности (Рис. 5).
Рис. 5
Базовую окружность строим в плоскости YOZ. Координаты окружности определяем с помощью формул перехода из полярной системы координат в декартовую, то есть в нашем случае:
y = r*cos φ;
z = r*sin φ.
Угол φ задаем формулой 2π/n, где n – число, определяющее сглаженность окружности, чем больше, тем лучше.
Вращение вокруг вектора w (0, 1, 0) реализуется с помощью матрицы поворота и функции Rotate () из класса Matrix. Координаты повернутой окружности получаем путем умножения матрицы поворота на вершины базовой окружности.
Tor_form.cpp
#include <vcl.h>
#pragma hdrstop
#include "TOR.h"
#include "TOR_form.h"
//------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
disp=new Display(300,350,700,700,0.05,0.05,Form1->Canvas);
tor=new Tor();
}
//------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
disp->Clear();
Vector v(1,1,2);
v=v/(!v);
Matrix A=Rotate(v,0.1);
tor->Transform(A);
tor->Show();
}
Tor.h
#define N 50 // количество окружностей в торе
#define n 20 // количество ребер в окружности
#define r 2 // радиус малого круга
#define R 7 // радиус тора
Display * disp;
class Tor
{
int i, j;
Vector Circle[n], Ver[N][n];
double fi;
public:
//--- Tor ---
Tor()
{
// определяем вершинки круга
fi = (2*M_PI)/n;
for (i=0; i<n; i++)
{
Circle[i] = Vector(0, r*cos(i*fi), r*sin(i*fi)+R);
}
// определяем вершины тора
fi = (2*M_PI)/N;
//вектор, вокруг которого происходит вращение окружности
Vector w(0, 1, 0);
w=w/(!w);
for (j=0; j<N; j++)
{
// поворачиваем окружность вокруг вектора w
Matrix B=Rotate(w, j*fi);
// записываем координаты вершин тора
for (i=0; i<n; i++)
{
Ver[j][i]=B*Circle[i];
}
}
}
//--- Show ---
void Show()
{
disp->MoveTo(Ver[0][0].x, Ver[0][0].y);
for (j=0; j<N; j++)
{
// рисуем кольца
for (i=0; i<n; i++)
{
disp->LineTo(Ver[j][i].x, Ver[j][i].y);
}
disp->LineTo(Ver[j][0].x, Ver[j][0].y);
// рисуем грани
if (j<N-1) {
for (i=0; i<n; i++)
{
disp->MoveTo(Ver[j][i].x, Ver[j][i].y);
disp->LineTo(Ver[j+1][i].x, Ver[j+1][i].y);
}
}
}
// рисуем окончательные грани
for (i=0; i<n; i++)
{
disp->MoveTo(Ver[N-1][i].x, Ver[N-1][i].y);
disp->LineTo(Ver[0][i].x, Ver[0][i].y);
}
}
//--- Transform ---
void Transform(Matrix & M)
{
for (j=0; j<N; j++)
for (i=0; i<n; i++)
{
Ver[j][i]=M*Ver[j][i];
}
Matrix M1=M;
M1.Invert();
M1.Transpose();
}
};
Disp.h
class Display
{
int x_org,y_org,W,H;
double dx,dy;
TCanvas * Canva;
public:
Display(int ax_org,
int ay_org,
int aW,
int aH,
double adx,
double ady,
TCanvas * aCanva)
{
x_org=ax_org;
y_org=ay_org;
W=aW;
H=aH;
dx=adx;
dy=ady;
Canva=aCanva;
};
int Convx2xs(double x)
{
int xs;
xs=x_org+x/dx;
return xs;
};
int Convy2ys(double y)
{
int ys;
ys=y_org+y/dy;
return ys;
};
void MoveTo(double x,double y)
{
Canva->MoveTo(Convx2xs(x),Convy2ys(y));
};
void LineTo(double x,double y)
{
Canva->LineTo(Convx2xs(x),Convy2ys(y));
};
void Clear()
{
Canva->Brush->Color=clWhite;
TRect rect;
rect.right=H;
rect.bottom=W;
rect.left=0;
rect.top=0;
Canva->FillRect(rect);
};
};
Результат работы программы рисования тора приведен на Рис. 6.
Рис.6
Строить куб будем, опираясь на его определение.
Куб – правильный прямоугольный параллелепипед; имеет 6 квадратных граней, 8 вершин и 12 ребер. К тому же необходимо к каждой грани построить нормаль, итого будет 6 нормалей.
Куб задаем с помощью вершин, на основе которых считаем нормали к граням. Для отображения куба удобно использовать грани, поэтому определяем координаты всех граней.
Все 8 вершин задаем вручную.
Нормали определяем так:
1. Берем два вектора лежащих в одной плоскости грани и исходящих из одной точки
и .Координаты этих векторов определяем так:
V1 (x1, y1, z1), V2(x2, y2, z2) – две вершины, тогда вектор, проходящий через эти точки равен
= (x2-x1, y2-y1, z2-z1)2. Находим
, векторное произведение векторов и = x = ( (ay bz – az by), (ax bz – az bx), (ax by – ay bx) ) ┴ и ┴ , значит – нормаль к грани.