//------------------------------------------------------------------------------
// emATMatrix.h
//
// Copyright (C) 2005-2008 Oliver Hamann.
//
// Homepage: http://eaglemode.sourceforge.net/
//
// This program is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License version 3 as published by the
// Free Software Foundation.
//
// 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 version 3 for
// more details.
//
// You should have received a copy of the GNU General Public License version 3
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//------------------------------------------------------------------------------
#ifndef emATMatrix_h
#define emATMatrix_h
#ifndef emStd1_h
#include <emCore/emStd1.h>
#endif
//==============================================================================
//================================= emATMatrix =================================
//==============================================================================
class emATMatrix {
public:
// Class for an affine transformation matrix. It is a 3x3 matrix with
// constant elements in the last column:
// _ _
// | a00 a01 0.0 |
// | a10 a11 0.0 |
// |_ a20 a21 1.0 _|
//
// Transforming a source coordinate (sx,sy) to a target coordinate
// (tx,ty) is:
//
// tx = a00*sx + a10*sy + a20
// ty = a01*sx + a11*sy + a21
//
// Please see the classes emIdentityATM, emInvertATM, emMultiplyATM,
// emTranslateATM, emScaleATM, emRotateATM and emShearATM more below.
// They provide lots of constructors for creating typical matrices. Here
// is an example of constructing a matrix which performs rotation first,
// then scaling and finally translation:
//
// emTranslateATM(5.0,7.0,emScaleATM(2.0,3.0,emRotateATM(90.0)))
//
// The following constructing would result equal, but a bit slower:
//
// emRotateATM(90.0) * emScaleATM(2.0,3.0) * emTranslateATM(5.0,7.0)
emATMatrix();
// Performs no initialization (this is a "primitive" type).
emATMatrix(double a00, double a01,
double a10, double a11,
double a20, double a21);
// Construct from the given elements.
emATMatrix(const emATMatrix & m);
// Construct a copied matrix.
emATMatrix & operator = (const emATMatrix & m);
// Copy a matrix.
double Get(int i, int j) const;
void Set(int i, int j, double aij);
// Get or set an element of this matrix. i is the row index and
// must be 0, 1 or 2. j is the column index and must be 0 or 1.
double TransX(double sx, double sy) const;
double TransY(double sx, double sy) const;
// Transform a point from source coordinates to target
// coordinates.
double InverseTransX(double tx, double ty) const;
double InverseTransY(double tx, double ty) const;
// Transform a point from target coordinates back to source
// coordinates. This is quite slower than TransX and TransY. For
// inverse-transforming more than about 4 points, it would be
// faster to create and use an emInvertATM.
bool operator == (const emATMatrix & m) const;
bool operator != (const emATMatrix & m) const;
// Compare matrices.
emATMatrix & operator *= (const emATMatrix & m);
// Like *this = emMultiplyATM(*this,m).
emATMatrix operator * (const emATMatrix & m) const;
// Like emMultiplyATM(*this,m).
private:
friend class emIdentityATM;
friend class emInvertATM;
friend class emMultiplyATM;
friend class emTranslateATM;
friend class emScaleATM;
friend class emRotateATM;
friend class emShearATM;
double A[3][2];
};
//==============================================================================
//=============================== emIdentityATM ================================
//==============================================================================
class emIdentityATM : public emATMatrix {
public:
emIdentityATM();
// Construct an identity matrix. This means, source coordinates
// are equal to target coordinates.
};
//==============================================================================
//================================ emInvertATM =================================
//==============================================================================
class emInvertATM : public emATMatrix {
public:
emInvertATM(const emATMatrix & m);
// Construct an inverse matrix. It performs inverse
// transformations in compare to m.
};
//==============================================================================
//=============================== emMultiplyATM ================================
//==============================================================================
class emMultiplyATM : public emATMatrix {
public:
emMultiplyATM(const emATMatrix & m1, const emATMatrix & m2);
// Construct a multiplied matrix. Transforming a point with this
// matrix gives the same result as transforming the point first
// with m1 and then with m2.
emMultiplyATM(const emATMatrix & m1, const emATMatrix & m2,
const emATMatrix & m3);
// Like emMultiplyATM(emMultiplyATM(m1,m2),m3)
emMultiplyATM(const emATMatrix & m1, const emATMatrix & m2,
const emATMatrix & m3, const emATMatrix & m4);
// Like emMultiplyATM(emMultiplyATM(m1,m2,m3),m4)
};
//==============================================================================
//=============================== emTranslateATM ===============================
//==============================================================================
class emTranslateATM : public emATMatrix {
public:
emTranslateATM(double addX, double addY);
// Construct a matrix for translating. This matrix transforms
// source coordinates (sx,sy) to target coordinates (tx,ty)
// with:
// tx = sx + addX
// ty = sy + addY
emTranslateATM(double addX, double addY, const emATMatrix & m);
// Like:
// emMultiplyATM(
// m,
// emTranslateATM(addX,addY)
// )
};
//==============================================================================
//================================= emScaleATM =================================
//==============================================================================
class emScaleATM : public emATMatrix {
public:
emScaleATM(double facX, double facY);
// Construct a matrix for scaling. This matrix transforms source
// coordinates (sx,sy) to target coordinates (tx,ty) with:
// tx = sx * facX
// ty = sy * facY
emScaleATM(double facX, double facY, const emATMatrix & m);
// Like:
// emMultiplyATM(
// m,
// emScaleATM(facX,facY)
// )
emScaleATM(double facX, double facY, double fixX, double fixY);
// Like:
// emMultiplyATM(
// emTranslateATM(-fixX,-fixY),
// emScaleATM(facX,facY),
// emTranslateATM(fixX,fixY)
// )
emScaleATM(double facX, double facY, double fixX, double fixY,
const emATMatrix & m);
// Like:
// emMultiplyATM(
// m,
// emTranslateATM(-fixX,-fixY),
// emScaleATM(facX,facY),
// emTranslateATM(fixX,fixY)
// )
};
//==============================================================================
//================================ emRotateATM =================================
//==============================================================================
class emRotateATM : public emATMatrix {
public:
emRotateATM(double angle);
// Construct a matrix for rotating. The angle is in degrees.
// This matrix transforms source coordinates (sx,sy) to target
// coordinates (tx,ty) with:
// tx = sx*cos(angle/180.0*M_PI) - sy*sin(angle/180.0*M_PI)
// ty = sy*cos(angle/180.0*M_PI) + sx*sin(angle/180.0*M_PI)
emRotateATM(double angle, const emATMatrix & m);
// Like:
// emMultiplyATM(
// m,
// emRotateATM(angle)
// )
emRotateATM(double angle, double fixX, double fixY);
// Like:
// emMultiplyATM(
// emTranslateATM(-fixX,-fixY),
// emRotateATM(angle),
// emTranslateATM(fixX,fixY)
// )
emRotateATM(double angle, double fixX, double fixY,
const emATMatrix & m);
// Like:
// emMultiplyATM(
// m,
// emTranslateATM(-fixX,-fixY),
// emRotateATM(angle),
// emTranslateATM(fixX,fixY)
// )
};
//==============================================================================
//================================= emShearATM =================================
//==============================================================================
class emShearATM : public emATMatrix {
public:
emShearATM(double shX, double shY);
// Construct a matrix for shearing. This matrix transforms
// source coordinates (sx,sy) to target coordinates (tx,ty)
// with:
// tx = sx + sy*shX
// ty = sy + sx*shY
emShearATM(double shX, double shY, const emATMatrix & m);
// Like:
// emMultiplyATM(
// m,
// emShearATM(shX,shY)
// )
emShearATM(double shX, double shY, double fixX, double fixY);
// Like:
// emMultiplyATM(
// emTranslateATM(-fixX,-fixY),
// emShearATM(shX,shY),
// emTranslateATM(fixX,fixY)
// )
emShearATM(double shX, double shY, double fixX, double fixY,
const emATMatrix & m);
// Like:
// emMultiplyATM(
// m,
// emTranslateATM(-fixX,-fixY),
// emShearATM(shX,shY),
// emTranslateATM(fixX,fixY)
// )
};
//==============================================================================
//=========================== Inline implementations ===========================
//==============================================================================
inline emATMatrix::emATMatrix()
{
}
inline double emATMatrix::Get(int i, int j) const
{
return A[i][j];
}
inline void emATMatrix::Set(int i, int j, double aij)
{
A[i][j]=aij;
}
inline double emATMatrix::TransX(double sx, double sy) const
{
return A[0][0]*sx + A[1][0]*sy + A[2][0];
}
inline double emATMatrix::TransY(double sx, double sy) const
{
return A[0][1]*sx + A[1][1]*sy + A[2][1];
}
#endif