/*****
* transform.h
* Andy Hammerlindl 2002/05/22
*
* The transform datatype stores an affine transformation on the plane
* The datamembers are x, y, xx, xy, yx, and yy. A pair (x,y) is
* transformed as
* x' = t.x + t.xx * x + t.xy * y
* y' = t.y + t.yx * x + t.yy * y
*****/
#ifndef TRANSFORM_H
#define TRANSFORM_H
#include <iostream>
#include "pair.h"
namespace camp {
class transform : public gc {
double x;
double y;
double xx;
double xy;
double yx;
double yy;
inline transform rotatearound(pair z, double theta)
{
// Notice the operators are applied from right to left.
// Could be optimized.
return shift(z) * rotate(theta) * shift(-z);
}
inline transform reflectabout(pair z, pair w)
{
if (z == w)
reportError("points determining line to reflect about must be distinct");
// Also could be optimized.
transform basis = shift(z) * scale(w-z);
transform flip = yscale(-1.0);
return basis * flip * inverse(basis);
}
// Return the rotational part of t.
inline transform rotation(transform t)
{
pair z(2.0*t.getxx()*t.getyy(),t.getyx()*t.getyy()-t.getxx()*t.getxy());
if(t.getxx() < 0) z=-z;
return rotate(atan2(z.gety(),z.getx()));
}
// Remove the x and y components, so that the new transform maps zero to zero.
inline transform shiftless(transform t)
{
return transform(0, 0, t.getxx(), t.getxy(), t.getyx(), t.getyy());
}
// Return the translational component of t.
inline transform shift(transform t)
{
return transform(t.getx(), t.gety(), 1.0, 0, 0, 1.0);
}
// Return the translational pair of t.
inline pair shiftpair(transform t)
{
return pair(t.getx(), t.gety());
}