Реферат: Трехмерная графика. Теория

Трехмерная графика

Краткие теоретическиесведения.

Каждая точка пространства(кроме начальной точки О) может быть задана четверкой одновременно не равныхнулю чисел ((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 ();

}

еще рефераты
Еще работы по информатике, программированию