~cpp // Header #ifndef _3D_INSU_LIB_ #define _3D_INSU_LIB_ #include <cmath> #include <vector> #include <iostream> using namespace std; const float PI = (float)(atan(1.0) * 4.0); float GetRadian(float Angle); class Vector; class Matrix { private: int _nRow; int _nCol; vector< vector<float> > _mat; void Init(int nRow, int nCol); public: Matrix(); Matrix(int nRow, int nCol); Matrix(const Matrix& m); Matrix(float n1, float n2, float n3, float n4, float n5, float n6, float n7, float n8, float n9, float n10, float n11, float n12, float n13, float n14, float n15, float n16); void ToIdenty(); Matrix operator + (const Matrix& m) const; Matrix operator - (const Matrix& m) const; Matrix operator - () const; Matrix operator * (const Matrix& m) const; Vector operator * (const Vector& v) const; Matrix operator * (float n) const; static Matrix GetRotationX (float Angle); static Matrix GetRotationY (float Angle); static Matrix GetRotationZ (float Angle); friend ostream& operator << (ostream& os, const Matrix& m); friend Matrix operator * (float n, const Matrix& m); }; class Vector { private: vector<float> _vec; void Init(); public: Vector(float n1, float n2, float n3); Vector(const Vector& v); Vector(); float operator * (const Vector& v) const; Vector operator * (float n) const; Vector operator ^ (const Vector& v) const; Vector operator - () const; Vector operator + (const Vector& v) const; Vector operator - (const Vector& v) const; Vector Normalize() const; float GetMag() const; friend ostream& operator << (ostream& os, const Vector& v); friend Vector operator * (float n, const Vector& v); vector<float> GetMem() const { return _vec; } void SetMem(int pivot, float n) { _vec[pivot] = n; } }; #endif // Source #include "3d.h" //////// 60분법으로 주어진 각을 라디안으로 바꾼다. //////// float GetRadian(float Angle) { return Angle * PI / 180; } ////////////////////////// Matrix ////////////////////////// ///////// 생성자 ///////// void Matrix::Init(int nRow, int nCol) { _nRow = nRow; _nCol = nCol; _mat.resize(_nRow); for(int i = 0 ; i < _nRow ; ++i) { _mat[i].resize(_nCol); } } Matrix::Matrix() { Init(4,4); } Matrix::Matrix(float n1, float n2, float n3, float n4, float n5, float n6, float n7, float n8, float n9, float n10, float n11, float n12, float n13, float n14, float n15, float n16) { Init(4,4); _mat[0][0] = n1; _mat[0][1] = n2; _mat[0][2] = n3; _mat[0][3] = n4; _mat[1][0] = n5; _mat[1][1] = n6; _mat[1][2] = n7; _mat[1][3] = n8; _mat[2][0] = n9; _mat[2][1] = n10; _mat[2][2] = n11; _mat[2][3] = n12; _mat[3][0] = n13; _mat[3][1] = n14; _mat[3][2] = n15; _mat[3][3] = n16; } Matrix::Matrix(int nRow, int nCol) { Init(nRow,nCol); } Matrix::Matrix(const Matrix& m) { Init(m._nRow, m._nCol); for(int i = 0 ; i < _nRow ; ++i) { for(int j = 0 ; j < _nCol ; ++j) { _mat[i][j] = m._mat[i][j]; } } } //////// 단위행렬 만들기 //////// void Matrix::ToIdenty() { for(int i = 0 ; i < _nRow ; ++i) { for(int j = 0 ; j < _nCol ; ++j) { if(i == j) _mat[i][j] = 1; else _mat[i][j] = 0; } } } //////// 행렬 출력하기 ///////// ostream& operator << (ostream& os, const Matrix& m) { for(int i = 0 ; i < m._nRow ; ++i) { for(int j = 0 ; j < m._nCol ; ++j) { os << m._mat[i][j] << " "; } os << endl; } os << endl; return os; } ///////// 행렬과 행렬의 합 //////////// Matrix Matrix::operator + (const Matrix& m) const { if(_nRow != m._nRow || _nCol != m._nCol) exit(0); Matrix ret(_nRow, _nCol); for(int i = 0 ; i < _nRow ; ++i) { for(int j = 0 ; j < _nCol ; ++j) { ret._mat[i][j] = _mat[i][j] + m._mat[i][j]; } } return ret; } ///////////// 행렬 - 행렬 ///////////// Matrix Matrix::operator - (const Matrix& m) const { return (*this).operator + (-m); } /////////// -행렬 ////////////// Matrix Matrix::operator - () const { Matrix ret(_nRow, _nCol); for(int i = 0 ; i < _nRow ; ++i) { for(int j = 0 ; j < _nCol ; ++j) { ret._mat[i][j] = -_mat[i][j]; } } return ret; } //////////// 행렬 * 행렬 ///////////// Matrix Matrix::operator * (const Matrix& m) const { if(_nCol != m._nRow) exit(0); Matrix ret(_nRow, m._nCol); for(int i = 0 ; i < ret._nRow ; ++i) { for(int j = 0 ; j < ret._nCol ; ++j) { for(int k = 0 ; k < ret._nRow ; ++k) { ret._mat[i][j] += _mat[i][k] * m._mat[k][j]; } } } return ret; } ///////////// 행렬 * 실수 ////////////// Matrix Matrix::operator * (float n) const { Matrix ret(_nRow, _nCol); for(int i = 0 ; i < _nRow ; ++i) { for(int j = 0 ; j < _nCol ; ++j) { ret._mat[i][j] = _mat[i][j] * n; } } return ret; } //////////// 실수 * 행렬 //////////////// Matrix operator*(float n, const Matrix& m) { return m * n; } //////////// x축으로 돌리는 회전행렬 구하기 ////////// Matrix Matrix::GetRotationX(float Angle) { float Rad = GetRadian(Angle); Matrix RotX(1, 0, 0, 0, 0, (float)cos(Rad), -(float)sin(Rad), 0, 0, (float)sin(Rad), (float)cos(Rad), 0, 0, 0, 0, 1); return RotX; } //////////// y축으로 돌리는 회전행렬 구하기 ////////// Matrix Matrix::GetRotationY(float Angle) { float Rad = GetRadian(Angle); Matrix RotY((float)cos(Rad), 0, (float)sin(Rad), 0, 0, 1, 0, 0, -(float)sin(Rad), 0, (float)cos(Rad), 0, 0, 0, 0, 1); return RotY; } //////////// z축으로 돌리는 회전행렬 구하기 ////////// Matrix Matrix::GetRotationZ(float Angle) { float Rad = GetRadian(Angle); Matrix RotZ((float)cos(Rad), (float)-sin(Rad), 0, 0, (float)sin(Rad), (float)cos(Rad), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); return RotZ; } //////////// 행렬 * 벡터(3차원 점) ///////////// Vector Matrix::operator * (const Vector& v) const { Vector ret(0, 0, 0); for(int i = 0 ; i < _nRow ; ++i) { float temp = 0; for(int j = 0 ; j < _nCol ; ++j) { temp += _mat[i][j] * v.GetMem()[j]; } ret.SetMem(i, temp); } return ret; } ////////////////////////////////// Vector /////////////////////////////// //////////// 생성자 ///////////// Vector::Vector() { Init(); } void Vector::Init() { _vec.resize(4); } Vector::Vector(const Vector& v) { Init(); for(int i = 0 ; i < 4 ; ++i) { _vec[i] = v._vec[i]; } } Vector::Vector(float n1, float n2, float n3) { Init(); _vec[0] = n1; _vec[1] = n2; _vec[2] = n3; _vec[3] = 1; } ///////////// 벡터의 내적 ////////////// float Vector::operator * (const Vector& v) const { return _vec[0] * v._vec[0] + _vec[1] * v._vec[1] + _vec[2] * v._vec[2]; } ///////////// 벡터 * 실수 //////////////// Vector Vector::operator * (float n) const { return Vector( _vec[0] * n , _vec[1] * n , _vec[2] * n ); } ////////////// 벡터 출력 //////////////// ostream& operator << (ostream& os, const Vector& v) { for(int i = 0 ; i < 4 ; ++i) { os << v._vec[i] << endl; } os << endl; return os; } ///////////// 실수 * 벡터 //////////////// Vector operator * (float n, const Vector& v) { return v * n; } //////////// 벡터 외적 //////////////// Vector Vector::operator ^ (const Vector& v) const { return Vector( _vec[1] * v._vec[2] - _vec[2] * v._vec[1], _vec[2] * v._vec[0] - _vec[0] * v._vec[2], _vec[0] * v._vec[1] - _vec[1] * v._vec[0] ); } //////////// 벡터 + 벡터 ///////////////// Vector Vector::operator + (const Vector& v) const { return Vector( _vec[0] + v._vec[0], _vec[1] + v._vec[1], _vec[2] + v._vec[2] ); } ///////////// 벡터 - 벡터 /////////////// Vector Vector::operator - (const Vector& v) const { return (*this).operator + (-v); } //////////// -벡터 //////////////// Vector Vector::operator - () const { return Vector( -_vec[0], -_vec[1], -_vec[2] ); } /////////// 절대값 1 짜리 벡터 ////////// Vector Vector::Normalize() const { return Vector(_vec[0] / GetMag() , _vec[1] / GetMag() , _vec[2] / GetMag()); } /////////// 절대값 구하기 ///////////// float Vector::GetMag() const { return (float)sqrt(_vec[0] * _vec[0] + _vec[1] * _vec[1] + _vec[2] * _vec[2]); }