/***************************************************************************
* Copyright (C) 2007 by Abderrahman Taha *
* *
* *
* This program 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 2 of the License, or *
* (at your option) any later version. *
* *
* This program 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 this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#include <math.h>
class IsoMatrix3D {
public:
double xx, xy, xz, xo;
double yx, yy, yz, yo;
double zx, zy, zz, zo;
double wx, wy, wz, wo;
double pi;
public:
IsoMatrix3D();
inline void scale(double );
inline void scale_2(double, double, double);
inline void translate(double, double, double);
inline void yrot(double);
inline void xrot(double);
inline void zrot(double);
inline void mult(IsoMatrix3D);
inline void unit();
void transform(double*, double*, int);
void CalcProdVect(double*, double*, double*);
double prodscalaire(double*, double*);
};
inline void IsoMatrix3D::mult(IsoMatrix3D rhs) {
double lxx = xx * rhs.xx + yx * rhs.xy + zx * rhs.xz;
double lxy = xy * rhs.xx + yy * rhs.xy + zy * rhs.xz;
double lxz = xz * rhs.xx + yz * rhs.xy + zz * rhs.xz;
double lxo = xo * rhs.xx + yo * rhs.xy + zo * rhs.xz + rhs.xo;
double lyx = xx * rhs.yx + yx * rhs.yy + zx * rhs.yz;
double lyy = xy * rhs.yx + yy * rhs.yy + zy * rhs.yz;
double lyz = xz * rhs.yx + yz * rhs.yy + zz * rhs.yz;
double lyo = xo * rhs.yx + yo * rhs.yy + zo * rhs.yz + rhs.yo;
double lzx = xx * rhs.zx + yx * rhs.zy + zx * rhs.zz;
double lzy = xy * rhs.zx + yy * rhs.zy + zy * rhs.zz;
double lzz = xz * rhs.zx + yz * rhs.zy + zz * rhs.zz;
double lzo = xo * rhs.zx + yo * rhs.zy + zo * rhs.zz + rhs.zo;
xx = lxx;
xy = lxy;
xz = lxz;
xo = lxo;
yx = lyx;
yy = lyy;
yz = lyz;
yo = lyo;
zx = lzx;
zy = lzy;
zz = lzz;
zo = lzo;
}
/** Scale by f in all dimensions */
inline void IsoMatrix3D::scale(double f) {
xx *= f;
xy *= f;
xz *= f;
xo *= f;
yx *= f;
yy *= f;
yz *= f;
yo *= f;
zx *= f;
zy *= f;
zz *= f;
zo *= f;
}
/** Scale along each axis independently */
inline void IsoMatrix3D::scale_2(double xf, double yf, double zf) {
xx *= xf;
xy *= xf;
xz *= xf;
xo *= xf;
yx *= yf;
yy *= yf;
yz *= yf;
yo *= yf;
zx *= zf;
zy *= zf;
zz *= zf;
zo *= zf;
}
/** Translate the origin */
inline void IsoMatrix3D::translate(double x, double y, double z) {
xo += x;
yo += y;
zo += z;
}
/** rotate theta degrees about the y axis */
inline void IsoMatrix3D::yrot(double theta) {
theta *= (pi / 180);
double ct = cos(theta);
double st = sin(theta);
double Nxx = (double) (xx * ct + zx * st);
double Nxy = (double) (xy * ct + zy * st);
double Nxz = (double) (xz * ct + zz * st);
double Nxo = (double) (xo * ct + zo * st);
double Nzx = (double) (zx * ct - xx * st);
double Nzy = (double) (zy * ct - xy * st);
double Nzz = (double) (zz * ct - xz * st);
double Nzo = (double) (zo * ct - xo * st);
xo = Nxo;
xx = Nxx;
xy = Nxy;
xz = Nxz;
zo = Nzo;
zx = Nzx;
zy = Nzy;
zz = Nzz;
}
/** rotate theta degrees about the x axis */
inline void IsoMatrix3D::xrot(double theta) {
theta *= (pi / 180);
double ct = cos(theta);
double st = sin(theta);
double Nyx = (double) (yx * ct + zx * st);
double Nyy = (double) (yy * ct + zy * st);
double Nyz = (double) (yz * ct + zz * st);
double Nyo = (double) (yo * ct + zo * st);
double Nzx = (double) (zx * ct - yx * st);
double Nzy = (double) (zy * ct - yy * st);
double Nzz = (double) (zz * ct - yz * st);
double Nzo = (double) (zo * ct - yo * st);
yo = Nyo;
yx = Nyx;
yy = Nyy;
yz = Nyz;
zo = Nzo;
zx = Nzx;
zy = Nzy;
zz = Nzz;
}
/** rotate theta degrees about the z axis */
inline void IsoMatrix3D::zrot(double theta) {
theta *= (pi / 180);
double ct = cos(theta);
double st = sin(theta);
double Nyx = (double) (yx * ct + xx * st);
double Nyy = (double) (yy * ct + xy * st);
double Nyz = (double) (yz * ct + xz * st);
double Nyo = (double) (yo * ct + xo * st);
double Nxx = (double) (xx * ct - yx * st);
double Nxy = (double) (xy * ct - yy * st);
double Nxz = (double) (xz * ct - yz * st);
double Nxo = (double) (xo * ct - yo * st);
yo = Nyo;
yx = Nyx;
yy = Nyy;
yz = Nyz;
xo = Nxo;
xx = Nxx;
xy = Nxy;
xz = Nxz;
}
/** Multiply this matrix by a second: M = M*R */
/** Reinitialize to the unit matrix */
inline void IsoMatrix3D::unit() {
xo = 0;
xx = 1;
xy = 0;
xz = 0;
yo = 0;
yx = 0;
yy = 1;
yz = 0;
zo = 0;
zx = 0;
zy = 0;
zz = 1;
wx = 0;
wy = 0;
wz = 0;
wo = 1;
}
inline void IsoMatrix3D::transform(double* v,double* tv, int nvert) {
double lxx = xx, lxy = xy, lxz = xz, lxo = xo;
double lyx = yx, lyy = yy, lyz = yz, lyo = yo;
double lzx = zx, lzy = zy, lzz = zz, lzo = zo;
for (int i = nvert * 3; (i -= 3) >= 0;) {
double x = v[i];
double y = v[i + 1];
double z = v[i + 2];
tv[i ] = (x * lxx + y * lxy + z * lxz + lxo);
tv[i + 1] = (x * lyx + y * lyy + z * lyz + lyo);
tv[i + 2] = (x * lzx + y * lzy + z * lzz + lzo);
}
}
syntax highlighted by Code2HTML, v. 0.9.1