(double v) (return x> v & & y> v & & z> v;);
); p> 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;);
); p>
inline Vector Vector:: operator - () const
(Return Vector (-x,-y,-z);
) p>
inline Vector operator + (const Vector & u, const Vector & v)
(Return Vector (ux + vx, uy + vy, uz + vz);
) p>
inline Vector operator - (const Vector & u, const Vector & v)
(Return Vector (ux - vx, uy - vy, uz - vz);
) p>
inline Vector operator * (const Vector & u, const Vector & v)
(Return Vector (ux * vx, uy * vy, uz * vz);
) p>
inline Vector operator * (const Vector & u, double f)
(Return Vector (ux * f, uy * f, uz * f);
) p>
inline Vector operator * (double f, const Vector & v)
(Return Vector (f * vx, f * vy, f * vz);
) p>
inline Vector operator/(const Vector & u, const Vector & v)
(Return Vector (ux/vx, uy/vy, uz/vz);
) p>
inline Vector operator/(const Vector & u, double f)
(Return Vector (ux/f, uy/f, uz/f);
) p>
inline Vector & Vector:: operator + = (const Vector & v)
(X + = v.x; y + = v.y; z + = v.z; return * this;
) p>
inline Vector & Vector:: operator -= (const Vector & v)
(X -= v.x; y -= v.y; z -= v.z; return * this;
) p>
inline Vector & Vector:: operator *= (const Vector & v)
(X *= v.x; y *= v.y; z *= v.z; return * this;
) p>
inline Vector & Vector:: operator *= (double v)
(X *= v; y *= v; z *= v; return * this;
) p>
inline Vector & Vector:: operator/= (double v)
(X/= v; y/= v; z/= v; return * this;
) p>
inline Vector Normalize (Vector & v) (return v /! v;) p>
Vector RndVector ();
Vector & Clip (Vector & v); p>
# endif p>
-------------------------------------------------- -------------------------- p>
// Файл vector.срр
# include
# include
# include "vector.h" p>
Vector operator ^ (const Vector & u, const Vector & v)
(Return Vector (uy * vz - uz * vy, uz * vx - ux * vz, ux * vy - uy * vx);
) p>
Vector RndVector ()
(
Vector v (rand () - 0.5 * RAND_MAX, rand () - 0.5 * RAND_MAX, rand () - 0.5 * RAND_MAX); return Normalize (v);
) p>
Vector & Clip (Vector & v)
(If (vx <0.0) vx = 0.0; else if (vx> 1.0) vx = 1.0; if (vy <0.0) vy = 0.0; else if (vy> 1.0) vy = 1.0; if (vz <0.0) vz = 0.0; else if (vz> 1.0) vz = 1.0; return v;
) p>
З цією метою створюється клас Vector, що містить у собі компонентивектора, і для цього класу перевизначаються основні знаки операцій. p>
- - унарний мінус і поелементне віднімання векторів; p>
+ - поелементне додавання векторів; p>
* - множення вектора на число; p>
* - поелементне множення векторів; p>
/- ділення вектора на число; p>
/- поелементне розподіл векторів; p>
& - скалярний добуток векторів; p>
^ - векторне твір; p>
! - Довжина вектора; p>
[] - компонента вектора. P>
При цьому стандартні пріоритети операцій зберігаються. P>
Крім цих операцій визначаються також деякі прості функції дляроботи з векторами: p>
. Normalize - нормування вектора; p>
. RndVector - отримання майже рівномірно розподіленого випадкового одиничного вектора; p>
. Clip - відсікання вектора. P>
З використанням цього класу можна в природному і зручній формізаписувати складні векторні вирази. p>
Аналогічним чином вводиться клас Matrix, що служить для представленняматриць перетворень в тривимірному просторі. Для цього класу такожпроводиться перевизначення основних знаків операцій. p>
// Файл matrix.h
# ifndef __MATRIX__
# define __MATRIX__ p>
# include "vector.h" p>
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 &);
); p>
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 (); p>
# endif p>
//--------------------------- -----------------------------------------------< br>- p>
// Файл matrix.cpp
# include
# include "matrix.h" p>
Matrix:: Matrix (double v)
(Int j; 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;
) p>
void Matrix:: Invert () p>
(
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 + +) ( p>
Out.x [i] [j]/= d; x [i] [j]/= d; p>
) p>
) 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]; p>
Out.x [j] [k] -= mulby * Out.x [i] [k]; p>
) p>
) p>
) p>
)
)
* this = Out;
) p>
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; p>
)
) p>
Matrix & Matrix:: operator + = (const Matrix & A)
(Int j; for (int i = 0; i <4; i + +) for (j = 0; j <4; j + +) x [i] [j] + = Ax [i] [j]; return * this;
) p>
Matrix & Matrix:: operator -= (const Matrix & A)
(Int j; for (int i = 0; i <4; i + +) for (j = 0; j <4; j + +) x [i] [j] -= Ax [i] [j]; return * this;
) p>
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;
) p>
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] * Ax [k] [j]; x [i] [j] = sum; p>
) return * this;
) p>
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] = Ax [i] [ j] + Bx [i] [j]; return res;
) p>
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] = Ax [i] [ j] - Bx [i] [j]; return res;
) p>
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 + = Ax [i] [k] * Bx [k] [j]; res.x [i] [j] = sum; p>
) return res;
) p>
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] = Ax [i] [ j] * v; return res;
) p>
Vector operator * (const Matrix & M, const Vector & v)
(
Vector res; res.x = vx * Mx [0] [0] + vy * Mx [1] [0] + vz * Mx [2] [0] + Mx
[3] [0]; res.y = vx * Mx [0] [1] + vy * Mx [1] [1] + vz * Mx [2] [1] + Mx
[3] [1]; res.z = vx * Mx [0] [2] + vy * Mx [1] [2] + vz * Mx [2] [2] + Mx
[3] [2]; double denom = vx * Mx [0] [3] + vy * Mx [1] [3] + vz * Mx [2] [3] + Mx [3] [3]; if ( denom! = 1.0) res/= denom; return res;
) p>
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;
); p>
Matrix Scale (const Vector & v)
(
Matrix res (1); res.x [0] [0] = vx; res.x [1] [1] = vy; res.x [2] [2] = vz; return res; < br>); p>
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;
); p>
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;
); p>
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;
); p>
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;
); p>
Matrix MirrorX ()
(
Matrix res (1); res.x [0] [0] = -1; return res;
); p>
Matrix MirrorY ()
(
Matrix res (1); res.x [1] [1] = -1; return res;
); p>
Matrix MirrorZ ()
(
Matrix res (1); res.x [2] [2] = -1; return res;
) p>
У наступній бібліотеці була реалізована робота з тривимірними об'єктами:гранню, графічним об'єктом і простором. Реалізовані наступніможливості:поворот об'єктів навколо координатних осей;дзеркальне відображення об'єктів по відношенню до координатним осях;центральне і паралельне проектування;масштабування об'єктів;видалення невидимих поверхонь;переміщення об'єктів у просторі. p>
// Файл 3dworks.h
# ifndef __3DWORKS__
# define __3DWORKS__ p>
# include
# include
# include "vector.h"
# include "matrix.h" p>
# define OneSd 0
# define TwoSds 1 p>
# define MaxPoints 10
# define MaxFacets 10
# define MaxObjects 10 p>
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 ();
); p>
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 ();
); p>
struct BSPNode
(
Polygon * Poly; double d;
BSPNode * Left;
BSPNode * Right;
); p>
class Space
(public: int ObjectNumber;
GrObject * Object [MaxObjects];
Space () (ObjectNumber = 0;);
Space (GrObject *, int); void Add (GrObject *); void Draw (const Vector &);
); p>
int IsVisible (const Polygon &, const Vector &);void DrawBSPTree (BSPNode *, const Vector &); p>
# endif p>
//---------------------- -------------------------------------------------- -
- p>
// Файл 3dworks.cpp
# include "3dworks.h" p>
// Polygon's methods p>
Polygon:: Polygon (Vector * PointArr, int PointNum, int Col, int TS)
(If (PointNum Tree -> d) (if (Tree -> Right! = NULL) DrawBSPTree (Tree -> Right, PrCntr); p>
Tree -> Poly -> Draw (PrCntr); if ( Tree -> Left! = NULL) DrawBSPTree (Tree -> Left, PrCntr);
) else (if (Tree -> Left! = NULL) DrawBSPTree (Tree -> Left, PrCntr); p>
Tree -> Poly -> Draw (PrCntr); if (Tree -> Right! = NULL) DrawBSPTree (Tree -> Right, PrCntr);
)
) p>
Далі представлена демонстраційна програма, яка виконує всіперераховані вище операції з тетраедрів. p>
// Файл 3dgame.cpp
# include
# include
# include
# include
# include
# include
# include "3dworks.h" p>
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);
) p> main ()
(
Vector Poly1 [3], Poly2 [3], Poly3 [3], Poly4 [3];
Polygon O [4];
Vector A (-50, 0, 0), p>
B (0, 0, 50), p>
C (50, 0, 0), p>
D (0, 100, 0), p>
PrCenter (0, 0, 1000); p>
Poly1 [0] = A; Poly2 [0] = B;
Poly1 [1] = D; Poly2 [1] = D;
Poly1 [2] = B; Poly2 [2] = C; p>
Poly3 [0] = C; Poly4 [0] = C;
Poly3 [1] = A; Poly4 [ 1] = D;
Poly3 [2] = B; Poly4 [2] = A; p>
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 ); p>
O [0] = * P1; O [1] = * P2;
O [2] = * P3; O [3] = * P4; p>
delete P1; delete P2; delete P3; delete P4; p>
GrObject * Obj = new GrObject (O, 4, Vector (0)); p>
double fi = 0.1, psi = 0.1, step = 0.1; int ch = 0, Page = 3; p>
int driver = DETECT, mode, res; initgraph (& driver, & mode, ""); if ((res = graphresult () )! = grOk) (printf ( "nGraphics error:% sn", grapherrormsg (res)); exit (1);
) setgraphmode (1); p>
DrawObject (Obj, PrCenter); p>
do ( p>
setactivepage (Page% 2); clearviewport (); if (kbhit ()) p>
(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; p>
); if (ch == 0) p>
(switch (ch = getch ()) (case 72: fi -= step; break; case 80: fi + = step; break; case 75: psi + = step; break; case 77: psi -= step; break; p>
); p>
); p>
); p>
Obj-> Rotate (fi, psi, 0); p>
DrawObject (Obj, PrCenter); p>
setvisualpage (Page + +% 2); if (fi == 0 & & psi == 0) while (! kbhit ()) ; p>
) while (ch! = 27); p>
delete Obj; p>
closegraph ();
) p>