Реферат: Трехмерная графика. Теория
Трехмерная графика
Краткие теоретическиесведения.
Каждая точка пространства(кроме начальной точки О) может быть задана четверкой одновременно не равныхнулю чисел ((x,y,z,1) или, более обще, (hx,hy,hz,h), где />). Эта четверкаопределена однозначно с точностью до общего множителя. Предложенный подход даетвозможность воспользоваться матричной записью и в более сложных, трехмерныхзадачах.
Как известно, любое аффинноепреобразование в трехмерном пространстве может быть представлено в видесуперпозиции вращений растяжений, отражений и переносов. Поэтому достаточноподробно описать матрицы только этих последних преобразований.
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 <math.h>class Vector{public: doublex, y, z; Vector () {}; Vector ( double v ) { x = y = z = v; };
Vector ( constVector& v ) { x = v.x; y = v.y; z = v.z; };
Vector ( doublevx, 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 Vectoroperator + ( const Vector&, const Vector& );
friend Vectoroperator — ( const Vector&, const Vector& );
friend Vectoroperator * ( const Vector&, const Vector& );
friend Vectoroperator * ( double, const Vector& );
friend Vectoroperator * ( const Vector&, double );
friend Vectoroperator / ( const Vector&, double );
friend Vectoroperator / ( const Vector&, const Vector& );
friend doubleoperator & ( const Vector& u, const Vector& v )
{ return u.x *v.x + u.y * v.y + u.z * v.z; };
friend Vectoroperator ^ ( 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; };
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 VectorVector :: operator — () const
{
return Vector (-x, -y, -z );
}
inline Vectoroperator + ( const Vector& u, const Vector& v )
{
return Vector (u.x + v.x, u.y + v.y, u.z + v.z );
}
inline Vectoroperator — ( const Vector& u, const Vector& v )
{
return Vector (u.x — v.x, u.y — v.y, u.z — v.z );
}
inline Vectoroperator * ( const Vector& u, const Vector& v )
{
return Vector (u.x * v.x, u.y * v.y, u.z * v.z );
}
inline Vectoroperator * ( const Vector& u, double f )
{
return Vector (u.x * f, u.y * f, u.z * f );
}
inline Vectoroperator * ( double f, const Vector& v )
{
return Vector ( f* v.x, f * v.y, f * v.z );
}
inline Vectoroperator / ( const Vector& u, const Vector& v )
{
return Vector (u.x / v.x, u.y / v.y, u.z / v.z );
}
inline Vectoroperator / ( 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 VectorNormalize ( Vector& v ) { return v / !v; }
Vector RndVector();
Vector& Clip (Vector& v );
#endif
----------------------------------------------------------------------------
// Файлvector.срр
#include<math.h>
#include<stdlib.h>
#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& v )
{
if ( v.x < 0.0) v.x = 0.0;
else
if ( v.x > 1.0) v.x = 1.0;
if ( v.y < 0.0) v.y = 0.0;
else
if ( v.y > 1.0) v.y = 1.0;
if ( v.z < 0.0) v.z = 0.0;
else
if ( v.z > 1.0) v.z = 1.0;
return v;
}
С этой целью создается класс 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 Matrixoperator + ( const Matrix&, const Matrix& );
friend Matrixoperator — ( const Matrix&, const Matrix& );
friend Matrixoperator * ( const Matrix&, double );
friend Matrixoperator * ( const Matrix&, const Matrix& );
friend Vectoroperator * ( 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 ();
Matrix MirrorZ ();
#endif
//---------------------------------------------------------------------------
// Файл matrix.cpp
#include<math.h>#include «matrix.h»Matrix :: Matrix ( double v ){ intj; for ( int i = 0; i < 4; i++ ) for ( j = 0; j < 4; j++ ) x [i][j] = ( i== j )? v: 0.0; x [3][3] = 1;}void Matrix :: Invert ()
{
Matrix Out ( 1 );
for ( int i = 0;i < 4; i++ ) {
double d = x[i][i];
if ( d != 1.0 ) {
for ( int j = 0;j < 4; j++ ) {
Out.x [i][j] /= d;
x [i][j] /= d;
}
}
for ( int j = 0;j < 4; j++ ) {
if ( j != i ) {
if ( x[j][i] !=0.0 ) {
double mulby =x[j][i];
for ( int k = 0;k < 4; k++ ) {
x [j][k] -= mulby* x [i][k];
Out.x [j][k] -=mulby * Out.x [i][k];
}
}
}
}
}
*this = Out;
}
void Matrix ::Transpose ()
{
double t;
int j;
for ( int i = 0;i < 4; i++ )
for ( j = 0; j< 4; j++ )
if ( i != j ) {
t = x [i][j];
x [i][j] = x[j][i];
x [j][i] = t;
}
}
Matrix& Matrix:: operator += ( const Matrix& A )
{
int j;
for ( int i = 0;i < 4; i++ )
for ( j = 0; j< 4; j++ )
x [i][j] += A.x[i][j];
return *this;
}
Matrix& Matrix:: operator -= ( const Matrix& A )
{
int j;
for ( int i = 0;i < 4; i++ )
for ( j = 0; j< 4; j++ )
x [i][j] -= A.x[i][j];
return *this;
}
Matrix& Matrix:: operator *= ( double v )
{
int j;
for ( int i = 0;i < 4; i++ )
for ( j = 0; j< 4; j++ )
x [i][j] *= v;
return *this;
}
Matrix& Matrix:: operator *= ( const Matrix& A )
{
Matrix res =*this;
int j;
for ( int i = 0;i < 4; i++ )
for ( j = 0; j< 4; j++ ) {
double sum = 0;
for ( int k = 0;k < 4; k++ )
sum += res.x[i][k] * A.x [k][j];
x [i][j] = sum;
}
return *this;
}
Matrix operator +( const Matrix& A, const Matrix& B )
{
Matrix res;
int j;
for ( int i = 0;i < 4; i++ )
for ( j = 0; j< 4; j++ )
res.x [i][j] =A.x [i][j] + B.x [i][j];
return res;
}
Matrix operator — ( const Matrix& A, const Matrix& B )
{
Matrix res;
int j;
for ( int i = 0;i < 4; i++ )
for ( j = 0; j< 4; j++ )
res.x [i][j] =A.x [i][j] — B.x [i][j];
return res;
}
Matrix operator *( const Matrix& A, const Matrix& B )
{
Matrix res;
int j;
for ( int i = 0;i < 4; i++ )
for ( j = 0; j< 4; j++ ) {
double sum = 0;
for ( int k = 0;k < 4; k++ )
sum += A.x [i][k]* B.x [k][j];
res.x [i][j] =sum;
}
return res;
}
Matrix operator *( const Matrix& A, double v )
{
Matrix res;
int j;
for ( int i = 0;i < 4; i++ )
for ( j = 0; j< 4; j++ )
res.x [i][j] =A.x [i][j] * v;
return res;
}
Vector operator *( const Matrix& M, const Vector& v )
{
Vector res;
res.x = v.x * M.x[0][0] + v.y * M.x [1][0] + v.z * M.x [2][0] + M.x [3][0];
res.y = v.x * M.x[0][1] + v.y * M.x [1][1] + v.z * M.x [2][1] + M.x [3][1];
res.z = v.x * M.x[0][2] + v.y * M.x [1][2] + v.z * M.x [2][2] + M.x [3][2];
double denom =v.x * M.x [0][3] + v.y * M.x [1][3] +
v.z * M.x [2][3]+ M.x[3][3];
if ( denom != 1.0)
res /= denom;
return res;
}
Matrix Translate (const Vector& Loc )
{
Matrix res ( 1 );
res.x [3][0] =Loc.x;
res.x [3][1] =Loc.y;
res.x [3][2] =Loc.z;
return res;
};
Matrix Scale (const Vector& v )
{
Matrix res ( 1 );
res.x [0][0] =v.x;
res.x [1][1] =v.y;
res.x [2][2] =v.z;
return res;
};
Matrix RotateX (double Angle )
{
Matrix res ( 1 );
double Cosine =cos ( Angle );
double Sine = sin( Angle );
res.x [1][1] =Cosine;
res.x [2][1] = — Sine;
res.x [1][2] =Sine;
res.x [2][2] =Cosine;
return res;
};
Matrix RotateY (double Angle )
{
Matrix res ( 1 );
double Cosine =cos ( Angle );
double Sine = sin( Angle );
res.x [0][0] =Cosine;
res.x [2][0] = — Sine;
res.x [0][2] =Sine;
res.x [2][2] =Cosine;
return res;
};
Matrix RotateZ (double Angle )
{
Matrix res ( 1 );
double Cosine =cos ( Angle );
double Sine = sin( Angle );
res.x [0][0] =Cosine;
res.x [1][0] = — Sine;
res.x [0][1] =Sine;
res.x [1][1] =Cosine;
return res;
};
Matrix Rotate (const Vector& axis, double angle )
{
Matrix res ( 1 );
double Cosine =cos ( angle );
double Sine = sin( angle );
res.x [0][0] =axis.x * axis.x + ( 1 — axis.x * axis.x ) * Cosine;
res.x [0][1] =axis.x * axis.y * ( 1 — Cosine ) + axis.z * Sine;
res.x [0][2] =axis.x * axis.z * ( 1 — Cosine ) — axis.y * Sine;
res.x [0][3] = 0;
res.x [1][0] =axis.x * axis.y * ( 1 — Cosine ) — axis.z * Sine;
res.x [1][1] =axis.y * axis.y + ( 1 — axis.y * axis.y ) * Cosine;
res.x [1][2] =axis.y * axis.z * ( 1 — Cosine ) + axis.x * Sine;
res.x [1][3] = 0;
res.x [2][0] =axis.x * axis.z * ( 1 — Cosine ) + axis.y * Sine;
res.x [2][1] =axis.y * axis.z * ( 1 — Cosine ) — axis.x * Sine;
res.x [2][2] =axis.z * axis.z + ( 1 — axis.z * axis.z ) * Cosine;
res.x [2][3] = 0;
res.x [3][0] = 0;
res.x [3][1] = 0;
res.x [3][2] = 0;
res.x [3][3] = 1;
return res;
};
Matrix MirrorX ()
{
Matrix res ( 1 );
res.x [0][0] =-1;
return res;
};
Matrix MirrorY ()
{
Matrix res ( 1 );
res.x [1][1] =-1;
return res;
};
Matrix MirrorZ ()
{
Matrix res ( 1 );
res.x [2][2] =-1;
return res;
}
В следующей библиотеке былареализована работа с трехмерными объектами: гранью, графическим объектом ипространством. Реализованы следующие возможности:
поворот объектов вокругкоординатных осей;
зеркальное отображениеобъектов по отношению к координатным осям;
центральное и параллельноепроектирование;
масштабирование объектов;
удаление невидимыхповерхностей;
перемещение объектов впространстве.
//Файл3dworks.h
#ifndef__3DWORKS__#define __3DWORKS__#include <graphics.h>
#include<stdlib.h>
#include«vector.h»
#include«matrix.h»
#define OneSd 0
#define TwoSds 1
#define MaxPoints10
#define MaxFacets10
#define MaxObjects10
class Polygon
{
public:
int PointNumber;
Vector * Point;
Vector Normal;
Vector Center;
int Color;
int TwoSides;
Polygon () {};
Polygon ( Vector*, int, int, int );
void Draw ( constVector& );
void Move ( constVector& );
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 ( constVector& );
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 ( constVector& );
};
int IsVisible (const Polygon&, const Vector& );
void DrawBSPTree (BSPNode *, const Vector& );
#endif
//----------------------------------------------------------------------------
//Файл3dworks.cpp
#include«3dworks.h»// Polygon's methodsPolygon :: Polygon ( Vector *PointArr, int PointNum, int Col, int TS ){ if ( PointNum <= MaxPoints ) {PointNumber = PointNum; Point = PointArr; Color = Col; TwoSides = TS;
Normal =Normalize (
( Point [1] — Point [0] ) ^ ( Point [PointNumber-1] — Point [0] ));
Center = 0;
for ( int i = 0;i < PointNumber; i++ )
Center +=Point[i];
Center /=PointNumber;
}
}
void Polygon ::Move ( const Vector& v )
{
Matrix m =Translate ( v );
for ( int i = 0;i < PointNumber; i++ )
Point[i] = m *Point[i];
Center = m *Center;
}
void Polygon ::Rotate ( double Alfa, double Beta, double Gamma )
{
Matrix m =RotateX ( Alfa ) * RotateY ( Beta ) * RotateZ ( Gamma );
for ( int i = 0;i < PointNumber; i++ )
Point[i] = m *Point[i];
Normal = m *Normal;
Center = m *Center;
}
void Polygon ::PolyScale ( const Vector& v )
{
Matrix m = Scale( v );
for ( int i = 0;i < PointNumber; i++ )
Point[i] = m *Point[i];
Center = m *Center;
}
void Polygon ::PolyMirrorX ()
{
Matrix m =MirrorX();
for ( int i = 0;i < PointNumber; i++ )
Point[i] = m *Point[i];
Center = m *Center;
Normal = m *Normal;
}
void Polygon ::PolyMirrorY ()
{
Matrix m =MirrorY();
for ( int i = 0;i < PointNumber; i++ )
Point[i] = m *Point[i];
Center = m *Center;
Normal = m *Normal;
}
void Polygon ::PolyMirrorZ ()
{
Matrix m =MirrorZ();
for ( int i = 0;i < PointNumber; i++ )
Point[i] = m *Point[i];
Center = m *Center;
Normal = m *Normal;
}
void Polygon ::Draw ( const Vector& PrCenter )
{
int VisPoint[MaxPoints* 2], k = 0;
for ( int i = 0;i < PointNumber; i++ ) {
double Coeff = 1/ ( 1 — Point[i].z / PrCenter.z );
VisPoint[k++] = (int ) Point[i].x * Coeff + 320;
VisPoint[k++] = (int ) -Point[i].y * Coeff + 175;
}
setcolor ( Color);
setfillstyle ( 1,Color );
fillpoly (PointNumber, VisPoint );
}
// GrObject'smethods
GrObject ::GrObject ( Polygon * FacetArr, int FacetNum, const Vector& Crds )
{
if ( FacetNum<= MaxFacets )
{
FacetNumber =FacetNum;
Facet = FacetArr;
Coords = Crds;
}
}
void GrObject ::Move ( const Vector& v )
{
for ( int i = 0;i < FacetNumber; i++ )
Facet[i].Move ( v);
Coords =Translate ( v ) * Coords;
}
void GrObject ::Rotate ( double Alfa, double Beta, double Gamma )
{
for ( int i = 0;i < FacetNumber; i++ )
Facet[i].Rotate (Alfa, Beta, Gamma );
Coords = RotateX( Alfa ) * RotateY ( Beta ) * RotateZ ( Gamma ) * Coords;
}
void GrObject ::ObjScale ( const Vector& v )
{
for ( int i = 0;i < FacetNumber; i++ )
Facet[i].PolyScale( v );
Coords = Scale (v ) * Coords;
}
void GrObject ::ObjMirrorX ()
{
Matrix m =MirrorX();
for ( int i = 0;i < FacetNumber; i++ )
Facet[i].PolyMirrorX();
Coords = m *Coords;
}
void GrObject ::ObjMirrorY ()
{
Matrix m =MirrorY();
for ( int i = 0;i < FacetNumber; i++ )
Facet[i].PolyMirrorY();
Coords = m *Coords;
}
void GrObject ::ObjMirrorZ ()
{
Matrix m =MirrorZ();
for ( int i = 0;i < FacetNumber; i++ )
Facet[i].PolyMirrorZ();
Coords = m *Coords;
}
// Space's methods
Space :: Space (GrObject * Obj, int ObjectNum )
{
if ( ObjectNum<= MaxObjects )
{
ObjectNumber =ObjectNum;
for ( int i = 0;i < ObjectNumber; i++ )
Object[i] =&Obj[i];
};
}
void Space :: Add( GrObject * Obj )
{
if ( ObjectNumber< MaxObjects ) Object [ObjectNumber++] = Obj;
}
void Space :: Draw( const Vector& PrCenter )
{
}
// Other functions
int IsVisible (const Polygon& Poly, const Vector& PrCenter )
{
return (Poly.Normal & ( PrCenter — Poly.Point[0] )) < 0 || Poly.TwoSides;
}
void DrawBSPTree (BSPNode * Tree, const Vector& PrCntr )
{
if (( Tree ->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<dos.h>#include <graphics.h>#include <math.h>
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include«3dworks.h»
void DrawObject (GrObject* Obj, const Vector& v )
{
for ( int i = 0;i < Obj->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; deleteP2;
delete P3; deleteP4;
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 ();
}