From 4721524cb5a91fd57032737c09d40d34f87f4c99 Mon Sep 17 00:00:00 2001 From: Julian Harnath Date: Tue, 10 Nov 2015 22:22:32 +0100 Subject: [PATCH] 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. --- headers/os/interface/AffineTransform.h | 41 ++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/headers/os/interface/AffineTransform.h b/headers/os/interface/AffineTransform.h index b84dee957d3..c296c00c500 100644 --- a/headers/os/interface/AffineTransform.h +++ b/headers/os/interface/AffineTransform.h @@ -82,6 +82,8 @@ class BAffineTransform : public BFlattenable { 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 @@ class BAffineTransform : public BFlattenable { 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 @@ class BAffineTransform : public BFlattenable { 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) {