BAffineTransform: add PreTranslate/PreScale/PreRotate

* The existing methods TranslateBy(), ScaleBy() and RotateBy()
  transform the transformation. For a transform A, a point p,
  and the temporary transform B (being applied by the methods),
  this results in p' = B*(A*p) = (B*A)*p
  This is not necessarily the desired result. Suppose A is a
  translation and B a rotation, added by RotateBy(). Then B*A
  means that the translation itself is rotated, so B moves the
  coordinate origin itself, by rotating it around the original
  origin of the coordinate system (top left view corner).

  If we want to translate and then rotate around that *new* origin,
  we need to multiply the transforms the other way around: A*B.

  Three new methods PreTranslateBy(), PreScaleBy() and PreRotateBy()
  implement this. They are later used as a base to add translatation/
  scaling/rotation methods to BView which behave in the expected
  ordering, similar to other graphic APIs.
This commit is contained in:
Julian Harnath
2015-11-10 23:34:03 +01:00
parent 1cde68c5a2
commit 4721524cb5
+41
View File
@@ -82,6 +82,8 @@ public:
inline const BAffineTransform& TranslateBy(double x, double y);
const BAffineTransform& TranslateBy(const BPoint& delta);
inline const BAffineTransform& PreTranslateBy(double x, double y);
BAffineTransform TranslateByCopy(double x, double y) const;
BAffineTransform TranslateByCopy(const BPoint& delta) const;
@@ -92,6 +94,8 @@ public:
const BAffineTransform& RotateBy(const BPoint& center,
double angle);
inline const BAffineTransform& PreRotateBy(double angleRadians);
BAffineTransform RotateByCopy(double angle) const;
BAffineTransform RotateByCopy(const BPoint& center,
double angle) const;
@@ -109,6 +113,8 @@ public:
const BAffineTransform& ScaleBy(const BPoint& center,
const BPoint& scale);
inline const BAffineTransform& PreScaleBy(double x, double y);
BAffineTransform ScaleByCopy(double scale) const;
BAffineTransform ScaleByCopy(const BPoint& center,
double scale) const;
@@ -244,6 +250,15 @@ BAffineTransform::TranslateBy(double x, double y)
}
inline const BAffineTransform&
BAffineTransform::PreTranslateBy(double x, double y)
{
tx += x * sx + y * shx;
ty += x * shy + y * sy;
return *this;
}
inline const BAffineTransform&
BAffineTransform::RotateBy(double angle)
{
@@ -262,6 +277,21 @@ BAffineTransform::RotateBy(double angle)
}
inline const BAffineTransform&
BAffineTransform::PreRotateBy(double angle)
{
double ca = cos(angle);
double sa = sin(angle);
double newSx = sx * ca + shx * sa;
double newSy = -shy * sa + sy * ca;
shy = shy * ca + sy * sa;
shx = -sx * sa + shx * ca;
sx = newSx;
sy = newSy;
return *this;
}
inline const BAffineTransform&
BAffineTransform::ScaleBy(double x, double y)
{
@@ -293,6 +323,17 @@ BAffineTransform::ScaleBy(double s)
}
inline const BAffineTransform&
BAffineTransform::PreScaleBy(double x, double y)
{
sx *= x;
shx *= y;
shy *= x;
sy *= y;
return *this;
}
inline const BAffineTransform&
BAffineTransform::ShearBy(double x, double y)
{