Министерство образования Украины
Кафедра ПО ЭВМ
ОТЧЕТ
О лабораторной работе на тему:
«Трехмерная графика»
по дисциплине «Компьютерная графика»
Краткие теоретические сведения.
). Эта четверка определена однозначно с точностью до общего множителя.
Предложенный подход дает возможность воспользоваться матричной записью
и в более сложных , трехмерных задачах.
Как известно, любое аффинное преобразование в трехмерном пространстве
может быть представлено в виде суперпозиции вращений растяжений,
отражений и переносов. Поэтому достаточно подробно описать матрицы
только этих последних преобразований.
A. Матрицы вращения в пространстве.
Матрица вращения вокруг оси абсцисс на угол q:
Матрица вращения вокруг оси ординат на угол w:
Матрица вращения вокруг оси аппликат на угол x:
Б. Матрица растяжения (сжатия):
здесь a>0 – коэффициент растяжения (сжатия) вдоль оси
абсцисс,b>0-коэффициент растяжения (сжатия) вдоль оси
ординат,y>0-коэффициент растяжения (сжатия) вдоль оси аппликат.
В. Матрица отражения .
Матрица отражения относительно плоскости xOy:
Матрица отражения относительно плоскости yOz:
Матрица отражения относительно плоскости zOx:
Г. Матрица переноса :
Здесь (r,q,v)-вектор переноса.
Заметим, что, как и в двумерном случае , все выписанные матрицы не
вырождены.
Ортографическая проекция – картинная плоскость совпадает с одной из
координатных плоскостей или параллельна ей. Матрица проектирования
вдоль оси Х на плоскость YOZ имеет вид
В случае , если плоскость проектирования параллельна координатной
плоскости, необходимо умножить матрицу [Px] на матрицу сдвига . Имеем
Аналогично записываются матрицы проектирования вдоль 2-х координатных
осей:
Аксонометрическая проекция – проектирующие прямые перпендикулярны
картинной плоскости .
Различают три вида проекций в зависимости от взаимного расположения
плоскости проектирования и координатных осей:
триметрия-нормальный вектор картинной плоскости образует с ортами
координатных осей попарно различные углы(рис.15);
диметрия-два угла между нормалью картинной плоскости и координатными
осями равны (рис. 16).
– изометрия-все три угла между нормалью картинной плоскости и
координатными осями равны (рис. 17).
Каждый из трех видов указанных проекций получается комбинацией
поворотов, за которой следует параллельное проектирование.
Перспективные (центральные) проекции строятся более сложно .
Предположим что центр проектирования лежит на оси Z – C (0,0,c) а
плоскость проектирования совпадает с координатной плоскостью XOY
(рис. 19) . Возьмем в пространстве произвольную точку M(x,y,z),
проведем через нее и точку С прямую и запишем ее параметрические
уравнения . Имеем:
X`= xt , Y`=yt, Z`= c+(z-c)t
Найдем координаты точки пересечения этой прямой с плоскостью XOY.
Из того , что z`=0, получаем
Тот же самый результат мы получим, привлекая матрицу
В самом деле,
Mатрица проектирования, конечно, вырождена ; матрица же
соответствующего перспективного преобразования(без проектирования) имеет
следующий вид
Язык С++ предоставляет очень удобные средства, позволяющие заметно
упростить работу с векторами и преобразованиями в пространстве.
Рассмотрим реализацию работы с векторами.
// Файл vector.h
#ifndef __VECTOR__
#define __VECTOR__
#include class Vector { public: double x, y, z; Vector () {}; Vector ( double v ) { x = y = z = v; }; Vector ( const Vector& v ) { x = v.x; y = v.y; z = v.z; }; Vector ( double vx, double vy, double vz ) { x = vx; y = vy; z = vz; Vector& operator = ( const Vector& v ) { x = v.x; y = v.y; z = v.z; return *this; } Vector& operator = ( double f ) { x = y = z = f; return *this; }; Vector operator – () const; Vector& operator += ( const Vector& ); Vector& operator -= ( const Vector& ); Vector& operator *= ( const Vector& ); Vector& operator *= ( double ); Vector& operator /= ( double ); friend Vector operator + ( const Vector&, const Vector& ); friend Vector operator – ( const Vector&, const Vector& ); friend Vector operator * ( const Vector&, const Vector& ); friend Vector operator * ( double, const Vector& ); friend Vector operator * ( const Vector&, double ); friend Vector operator / ( const Vector&, double ); friend Vector operator / ( const Vector&, const Vector& ); friend double operator & ( const Vector& u, const Vector& v ) { return u.x * v.x + u.y * v.y + u.z * v.z; }; friend Vector operator ^ ( const Vector&, const Vector& ); double operator ! () { return (double) sqrt ( x * x + y * y + z * z ); double& operator [] ( int n ) { return *( &x + n ); }; int operator ( double v ) { return x > v && y > v && z > v; }; }; class Ray { public: Vector Org; Vector Dir; Ray () {}; Ray ( Vector& o, Vector& d ) { Org = o, Dir = d; }; Vector Point ( double t ) { return Org + Dir * t; }; }; inline Vector Vector :: operator – () const { return Vector ( -x, -y, -z ); } inline Vector operator + ( const Vector& u, const Vector& v ) { return Vector ( u.x + v.x, u.y + v.y, u.z + v.z ); } inline Vector operator – ( const Vector& u, const Vector& v ) { return Vector ( u.x – v.x, u.y – v.y, u.z – v.z ); } inline Vector operator * ( const Vector& u, const Vector& v ) { return Vector ( u.x * v.x, u.y * v.y, u.z * v.z ); } inline Vector operator * ( const Vector& u, double f ) { return Vector ( u.x * f, u.y * f, u.z * f ); } inline Vector operator * ( double f, const Vector& v ) { return Vector ( f * v.x, f * v.y, f * v.z ); } inline Vector operator / ( const Vector& u, const Vector& v ) { return Vector ( u.x / v.x, u.y / v.y, u.z / v.z ); } inline Vector operator / ( const Vector& u, double f ) { return Vector ( u.x / f, u.y / f, u.z / f ); } inline Vector& Vector :: operator += ( const Vector& v ) { x += v.x; y += v.y; z += v.z; return *this; } inline Vector& Vector :: operator -= ( const Vector& v ) { x -= v.x; y -= v.y; z -= v.z; return *this; } inline Vector& Vector :: operator *= ( const Vector& v ) { x *= v.x; y *= v.y; z *= v.z; return *this; } inline Vector& Vector :: operator *= ( double v ) { x *= v; y *= v; z *= v; return *this; } inline Vector& Vector :: operator /= ( double v ) { x /= v; y /= v; z /= v; return *this; } inline Vector Normalize ( Vector& v ) { return v / !v; } Vector RndVector (); Vector& Clip ( Vector& v ); #endif ———————————————————————— // Файл vector.срр #include #include #include “vector.h” Vector operator ^ ( const Vector& u, const Vector& v ) { return Vector ( u.y * v.z – u.z * v.y, u.z * v.x – u.x * v.z, u.x * v.y – u.y * v.x ); } Vector RndVector () { Vector v ( rand () – 0.5 * RAND_MAX, rand () – 0.5 * RAND_MAX, rand () – 0.5 * RAND_MAX ); return Normalize ( v ); } Vector& Clip ( Vector& С этой целью создается класс Vector, содержащий в себе компоненты – – унарный минус и поэлементное вычитание векторов; + – поэлементное сложение векторов; * – умножение вектора на число; * – поэлементное умножение векторов; / – деление вектора на число; / – поэлементное деление векторов; & – скалярное произведение векторов; ^ – векторное произведение; ! – длина вектора; [] – компонента вектора. При этом стандартные приоритеты операций сохраняются. Кроме этих операций определяются также некоторые простейшие функции для Normalize – нормирование вектора; RndVector – получение почти равномерно распределенного случайного Clip – отсечение вектора. С использованием этого класса можно в естественной и удобной форме Аналогичным образом вводится класс Matrix, служащий для представления //Файл matrix.h #ifndef __MATRIX__ #define __MATRIX__ #include “vector.h” class Matrix { public: double x [4][4]; Matrix () {}; Matrix ( double ); Matrix& operator += ( const Matrix& ); Matrix& operator -= ( const Matrix& ); Matrix& operator *= ( const Matrix& ); Matrix& operator *= ( double ); Matrix& operator /= ( double ); void Invert (); void Transpose (); friend Matrix operator + ( const Matrix&, const Matrix& ); friend Matrix operator – ( const Matrix&, const Matrix& ); friend Matrix operator * ( const Matrix&, double ); friend Matrix operator * ( const Matrix&, const Matrix& ); friend Vector operator * ( const Matrix&, const Vector& ); }; Matrix Translate ( const Vector& ); Matrix Scale ( const Vector& ); Matrix RotateX ( double ); Matrix RotateY ( double ); Matrix RotateZ ( double ); Matrix Rotate ( const Vector&, double ); Matrix MirrorX (); Matrix MirrorY (); Ma???????????????????????????????????????????????????? // Файл matrix.cpp #include #include “matrix.h” Matrix :: Matrix ( double v ) { int j; for ( int i = 0; i #include #include “vector.h” #include “matrix.h” #define OneSd 0 #define TwoSds 1 #define MaxPoints 10 #define MaxFacets 10 #define MaxObjects 10 class Polygon { public: int PointNumber; Vector * Point; Vector Normal; Vector Center; int Color; int TwoSides; Polygon () {}; Polygon ( Vector *, int, int, int ); void Draw ( const Vector& ); void Move ( const Vector& ); void Rotate ( double, double, double ); void PolyScale ( const Vector& ); void PolyMirrorX (); void PolyMirrorY (); void PolyMirrorZ (); }; class GrObject { public: int FacetNumber; Polygon * Facet; Vector Coords; GrObject () {}; GrObject ( Polygon *, int, const Vector& ); void Move ( const Vector& ); void Rotate ( double, double, double ); void ObjScale ( const Vector& ); void ObjMirrorX (); void ObjMirrorY (); void ObjMirrorZ (); }; struct BSPNode { Polygon * Poly; double d; BSPNode * Left; BSPNode * Right; }; class Space { public: int ObjectNumber; GrObject * Object [MaxObjects]; Space () { ObjectNumber = 0; }; Space ( GrObject *, int ); void Add ( GrObject * ); void Draw ( const Vector& ); }; int IsVisible ( const Polygon&, const Vector& ); void DrawBSPTree ( BSPNode *, const Vector& ); #endif //———————————————————————- //Файл 3dworks.cpp #include “3dworks.h” // Polygon’s methods Polygon :: Polygon ( Vector * PointArr, int PointNum, int Col, int TS ) { if ( PointNum Poly -> Normal & PrCntr ) > Tree -> d ) { if ( Tree -> Right != NULL ) DrawBSPTree ( Tree -> Right, PrCntr ); Tree -> Poly -> Draw ( PrCntr ); if ( Tree -> Left != NULL ) DrawBSPTree ( Tree -> Left, PrCntr ); } else { if ( Tree -> Left != NULL ) DrawBSPTree ( Tree -> Left, PrCntr ); Tree -> Poly -> Draw ( PrCntr ); if ( Tree -> Right != NULL ) DrawBSPTree ( Tree -> Right, PrCntr ); } } Далее представлена демонстрационная программа, которая выполняет все //Файл 3dgame.cpp #include #include #include #include #include #include #include “3dworks.h” void DrawObject ( GrObject* Obj, const Vector& v ) { for ( int i = 0; i FacetNumber; i++ ) if ( IsVisible ( Obj->Facet[i], v )) Obj->Facet[i].Draw ( v ); } main () { Vector Poly1[3], Poly2[3], Poly3[3], Poly4[3]; Polygon O[4]; Vector A ( -50, 0, 0 ), B ( 0, 0, 50 ), C ( 50, 0, 0 ), D ( 0, 100, 0 ), PrCenter ( 0, 0, 1000 ); Poly1[0] = A; Poly2[0] = B; Poly1[1] = D; Poly2[1] = D; Poly1[2] = B; Poly2[2] = C; Poly3[0] = C; Poly4[0] = C; Poly3[1] = A; Poly4[1] = D; Poly3[2] = B; Poly4[2] = A; Polygon * P1 = new Polygon ( Poly1, 3, 11, OneSd ); Polygon * P2 = new Polygon ( Poly2, 3, 12, OneSd ); Polygon * P3 = new Polygon ( Poly3, 3, 13, OneSd ); Polygon * P4 = new Polygon ( Poly4, 3, 14, OneSd ); O[0] = *P1; O[1] = *P2; O[2] = *P3; O[3] = *P4; delete P1; delete P2; delete P3; delete P4; GrObject * Obj = new GrObject ( O, 4, Vector ( 0 ) ); double fi = 0.1, psi = 0.1, step = 0.1; int ch = 0, Page = 3; int driver = DETECT, mode, res; initgraph ( &driver, &mode, “” ); if ( ( res = graphresult () ) != grOk ) { printf ( “\nGraphics error: %s\n”, grapherrormsg ( res ) ); exit ( 1 ); } setgraphmode ( 1 ); DrawObject ( Obj, PrCenter ); do { setactivepage ( Page % 2 ); clearviewport (); if ( kbhit ()) { switch ( ch = getch() ) { case ‘+’: Obj->ObjScale ((1.1,1.1,1.1)); break; case ‘-‘: Obj->ObjScale ((0.9,0.9,0.9)); break; case ‘x’: Obj->ObjMirrorX (); break; case ‘y’: Obj->ObjMirrorY (); break; case ‘z’: Obj->ObjMirrorZ (); break; }; if ( ch == 0 ) { switch ( ch = getch () ) { case 72 : fi -= step; break; case 80 : fi += step; break; case 75 : psi += step; break; case 77 : psi -= step; break; }; }; }; Obj->Rotate ( fi, psi, 0 ); DrawObject ( Obj, PrCenter ); setvisualpage ( Page++ % 2 ); if ( fi == 0 && psi == 0 ) while ( !kbhit ()); } while ( ch != 27 ); delete Obj; closegraph (); }
};
};
—-
v??????????‰??????????††??????????????†??????????????†???†???????‰??????
????????‰??????????††??????????????†??????
вектора, и для этого класса переопределяются основные знаки операций.
работы с векторами:
единичного вектора;
записывать сложные векторные выражения.
матриц преобразований в трехмерном пространстве. Для этого класса также
производится переопределение основных знаков операций.
——
вышеперечисленные операции с тетраэдром.
Нашли опечатку? Выделите и нажмите CTRL+Enter