Трехмерная графикаРефераты >> Программирование и компьютеры >> Трехмерная графика
{
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 <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 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 ();
Matrix MirrorZ ();
#endif
//---------------------------------------------------------------------------
// Файл matrix.cpp
#include <math.h>
#include "matrix.h"
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;
}
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 )