diff --git a/src/matrix.cpp b/src/matrix.cpp new file mode 100644 --- /dev/null +++ b/src/matrix.cpp @@ -0,0 +1,178 @@ +/* + * + * This file is part of the Virtual Leaf. + * + * The Virtual Leaf is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Virtual Leaf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Virtual Leaf. If not, see . + * + * Copyright 2010 Roeland Merks. + * + */ + +#include +#include +#include +#include "vector.h" +#include "matrix.h" +#include "tiny.h" + +static const std::string _module_id("$Id$"); + +Matrix::Matrix(const Vector &c1, const Vector &c2, const Vector &c3) { + + Alloc(); + + mat[0][0]=c1.x; mat[0][1]=c2.x; mat[0][2]=c3.x; + mat[1][0]=c1.y; mat[1][1]=c2.y; mat[1][2]=c3.y; + mat[2][0]=c1.z; mat[2][1]=c2.z; mat[2][2]=c3.z; + + +} + +void Matrix::Alloc(void) { + + // constructor +// mat=(double **)malloc(3*sizeof(double *)); +// mat[0]=(double *)malloc(9*sizeof(double)); + mat = new double*[3]; + mat[0] = new double[9]; + for (int i=1;i<3;i++) + mat[i]=mat[i-1]+3; + +} + +Matrix::~Matrix() { + + // destructor + //free(mat[0]); + //free(mat); + delete[] mat[0]; + delete[] mat; +} + +Matrix::Matrix(void) { + + // constructor + Alloc(); + + // clear matrix + for (int i=0;i<9;i++) { + mat[0][i]=0.; + } + +} + +Matrix::Matrix(const Matrix &source) { + + // copy constructor + Alloc(); + + for (int i=0;i<9;i++) { + mat[0][i]=source.mat[0][i]; + } + +} + + +void Matrix::operator=(const Matrix &source) { + + // assignment + + // don't assign to self + if (this==&source) return; + + // copy + for (int i=0;i<9;i++) + mat[0][i]=source.mat[0][i]; + +} + + +void Matrix::print(ostream *os) { + + *os << "{ { " << mat[0][0] << "," << mat[0][1] << "," << mat[0][2] << "},{" << mat[1][0] << "," << mat[1][1] << "," << mat[1][2] << "},{" << mat[2][0] << "," << mat[2][1] << "," << mat[2][2] << "} }"; + +} + +ostream &operator<<(ostream &os, Matrix &v) { + v.print(&os); + return os; +} + + +Vector Matrix::operator*(const Vector &v) const { + + // matrix * vector + Vector result; + + result.x = mat[0][0]*v.x+mat[0][1]*v.y+mat[0][2]*v.z; + result.y = mat[1][0]*v.x+mat[1][1]*v.y+mat[1][2]*v.z; + result.z = mat[2][0]*v.x+mat[2][1]*v.y+mat[2][2]*v.z; + + return result; + + +} + + +bool Matrix::operator==(Matrix &m) const { + + for (int i=0;i<9;i++) { + if ((mat[0][i]-m.mat[0][i])>TINY) + return false; + } + return true; + +} + +double Matrix::Det(void) const { + + return + - mat[0][2]*mat[0][4]*mat[0][6] + + mat[0][1]*mat[0][5]*mat[0][6] + + mat[0][2]*mat[0][3]*mat[0][7] + - mat[0][0]*mat[0][5]*mat[0][7] + - mat[0][1]*mat[0][3]*mat[0][8] + + mat[0][0]*mat[0][4]*mat[0][8]; + +} + +Matrix Matrix::Inverse(void) const { + + // return the Inverse of this matrix + double rd=1./Det(); // Reciproce Det; + Matrix inverse; + inverse.mat[0][0]=rd*(-mat[0][5]*mat[0][7]+mat[0][4]*mat[0][8]); + inverse.mat[0][1]=rd*( mat[0][2]*mat[0][7]-mat[0][1]*mat[0][8]); + inverse.mat[0][2]=rd*(-mat[0][2]*mat[0][4]+mat[0][1]*mat[0][5]); + inverse.mat[0][3]=rd*( mat[0][5]*mat[0][6]-mat[0][3]*mat[0][8]); + inverse.mat[0][4]=rd*(-mat[0][2]*mat[0][6]+mat[0][0]*mat[0][8]); + inverse.mat[0][5]=rd*( mat[0][2]*mat[0][3]-mat[0][0]*mat[0][5]); + inverse.mat[0][6]=rd*(-mat[0][4]*mat[0][6]+mat[0][3]*mat[0][7]); + inverse.mat[0][7]=rd*( mat[0][1]*mat[0][6]-mat[0][0]*mat[0][7]); + inverse.mat[0][8]=rd*(-mat[0][1]*mat[0][3]+mat[0][0]*mat[0][4]); + + + return inverse; +} + +void Matrix::Rot2D(double theta) { + + // make this matrix a rotation matrix over theta + // see http://mathworld.wolfram.com/RotationMatrix.html + + mat[0][0] = cos(theta); mat[0][1]=sin(theta); + mat[1][0] = -sin(theta); mat[1][1]=cos(theta); + mat[0][2] = mat[1][2] = mat[2][0] = mat[2][1] = mat[2][2] = 0.; + +}