1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
|
#ifndef _global_h
# include "global.h"
#endif
#ifndef _mat2_h
# include "mat2.h"
#endif
const Mat2 &Mat2::operator*=(const Mat2 &m)
{
Real h11=r11;
Real h12=r12;
Real h21=r21;
Real h22=r22;
r11 = h11*m.r11 + h12*m.r21;
r21 = h21*m.r11 + h22*m.r21;
r12 = h11*m.r12 + h12*m.r22;
r22 = h21*m.r12 + h22*m.r22;
tx += h11*m.tx + h12*m.ty;
ty += h21*m.tx + h22*m.ty;
return *this;
}
void Mat2::Invert(Mat2 *m) const
{
Real detA = r11*r22-r12*r21;
m->r11 = r22/detA;
m->r12 = -r12/detA;
m->r21 = -r21/detA;
m->r22 = r11/detA;
m->tx = -m->r11*tx -m->r12*ty;
m->ty = -m->r21*tx -m->r22*ty;
}
void Mat2::Split(Real *sh_p, Real *sx_p, Real *sy_p, Real *angle_p, Real *tx_p, Real *ty_p) const
{
Real cosa; // Rotation
if (r21) {
Real r1121 = r11/r21;
cosa = r1121 / sqrt(1+r1121*r1121);
*angle_p = acos(cosa);
*sx_p = r11/cosa;
*sy_p = (r11*r22/r21-r12)/(sin(*angle_p/180*M_PI)+r11*cosa/r21);
*sh_p = (r22-cosa**sy_p)/r21;
}
else {
if (r11) {
*sx_p = r11;
*angle_p = 0.0;
cosa = 1.0;
*sh_p = r12/r11;
*sy_p = r22;
}
else {
*sx_p = 0;
*sh_p = 0; // sowieso egal
Real r2212 = r22/r12;
cosa = -r2212 / sqrt(1+r2212*r2212);
*angle_p = acos(cosa);
*sy_p = r22/cosa;
}
}
// wenn beide Skalierungen negativ: Punktspiegelung
if (*sx_p<0 && *sy_p<0) {
*sx_p = *sx_p * -1;
*sy_p = *sy_p * -1;
if (*angle_p>0) *angle_p-=180.0;
else *angle_p+=180.0;
}
if (fabs(*sx_p-1)<EPS) *sx_p=1.0;
if (fabs(*sy_p-1)<EPS) *sy_p=1.0;
if (fabs(*sx_p-*sy_p)<EPS) *sy_p=*sx_p;
if (fabs(*sh_p)<EPS) *sh_p=0.0;
if (fabs(*angle_p)<EPS) *angle_p=0.0;
*tx_p = (fabs(tx)>EPS)?tx:0;
*ty_p = (fabs(ty)>EPS)?ty:0;
}
// void Mat2::Print() const
// {
// cout << "Matrix r11, r12, tx " <<r11<<" "<<r12<<" "<<tx<< endl;
// cout << " r21, r22, ty " <<r21<<" "<<r22<<" "<<ty<< endl;
// }
|