diff options
| -rw-r--r-- | src/2geom/affine.h | 15 | ||||
| -rw-r--r-- | src/2geom/point.cpp | 14 | ||||
| -rw-r--r-- | src/2geom/point.h | 13 | ||||
| -rw-r--r-- | src/2geom/transforms.cpp | 4 | ||||
| -rw-r--r-- | src/2geom/transforms.h | 3 | ||||
| -rw-r--r-- | src/2geom/utils.h | 17 | ||||
| -rw-r--r-- | src/seltrans.cpp | 8 |
7 files changed, 46 insertions, 28 deletions
diff --git a/src/2geom/affine.h b/src/2geom/affine.h index 9a6352f8b..277d8b4ee 100644 --- a/src/2geom/affine.h +++ b/src/2geom/affine.h @@ -16,6 +16,7 @@ #include <boost/operators.hpp> #include <2geom/forward.h> #include <2geom/point.h> +#include <2geom/utils.h> namespace Geom { @@ -57,15 +58,13 @@ namespace Geom { */ class Affine : boost::equality_comparable< Affine // generates operator!= from operator== - , boost::multipliable< Affine - , boost::multipliable< Affine, Translate - , boost::multipliable< Affine, Scale - , boost::multipliable< Affine, Rotate - , boost::multipliable< Affine, HShear - , boost::multipliable< Affine, VShear + , boost::multipliable1< Affine + , MultipliableNoncommutative< Affine, Translate + , MultipliableNoncommutative< Affine, Scale + , MultipliableNoncommutative< Affine, Rotate + , MultipliableNoncommutative< Affine, HShear + , MultipliableNoncommutative< Affine, VShear > > > > > > > - // boost::multipliable< A, B > generates operator*(A const &, B const &) - // and operator*(B const &, A const &) from A::operator*=(B const &) { Coord _c[6]; public: diff --git a/src/2geom/point.cpp b/src/2geom/point.cpp index 9df88df92..a9005ef61 100644 --- a/src/2geom/point.cpp +++ b/src/2geom/point.cpp @@ -146,8 +146,8 @@ Point unit_vector(Point const &a) } /** @brief Return the "absolute value" of the point's vector. * This is defined in terms of the default lexicographical ordering. If the point is "larger" - * that the origin (0, 0), its negation is returned. This corresponds to making the Y coordinate - * positive. You can check whether the points' vectors have the same direction (e.g. lie + * that the origin (0, 0), its negation is returned. You can check whether + * the points' vectors have the same direction (e.g. lie * on the same line passing through the origin) using * @code abs(a).normalize() == abs(b).normalize() @endcode. * To check with some margin of error, use @@ -158,8 +158,14 @@ Point unit_vector(Point const &a) * @relates Point */ Point abs(Point const &b) { - Point ret = b; - ret[Y] = fabs(ret[Y]); + Point ret; + if (b[Y] < 0.0) { + ret = -b; + } else if (b[Y] == 0.0) { + ret = b[X] < 0.0 ? -b : b; + } else { + ret = b; + } return ret; } diff --git a/src/2geom/point.h b/src/2geom/point.h index 97f5142e3..3c6e12eff 100644 --- a/src/2geom/point.h +++ b/src/2geom/point.h @@ -44,6 +44,7 @@ #include <2geom/coord.h> #include <2geom/isnan.h> //temporary fix for isnan() #include <2geom/math-utils.h> +#include <2geom/utils.h> namespace Geom { @@ -51,12 +52,12 @@ class Point : boost::additive< Point , boost::totally_ordered< Point , boost::multiplicative< Point, Coord - , boost::multiplicative< Point, Affine - , boost::multiplicative< Point, Translate - , boost::multiplicative< Point, Rotate - , boost::multiplicative< Point, Scale - , boost::multiplicative< Point, HShear - , boost::multiplicative< Point, VShear + , MultipliableNoncommutative< Point, Affine + , MultipliableNoncommutative< Point, Translate + , MultipliableNoncommutative< Point, Rotate + , MultipliableNoncommutative< Point, Scale + , MultipliableNoncommutative< Point, HShear + , MultipliableNoncommutative< Point, VShear > > > > > > > > > // this uses chaining so it looks weird, but works { Coord _pt[2]; diff --git a/src/2geom/transforms.cpp b/src/2geom/transforms.cpp index 2658719c4..3a1866c13 100644 --- a/src/2geom/transforms.cpp +++ b/src/2geom/transforms.cpp @@ -60,12 +60,12 @@ Point &Point::operator*=(Rotate const &r) } Point &Point::operator*=(HShear const &h) { - _pt[X] += h.f * _pt[X]; + _pt[X] += h.f * _pt[Y]; return *this; } Point &Point::operator*=(VShear const &v) { - _pt[Y] += v.f * _pt[Y]; + _pt[Y] += v.f * _pt[X]; return *this; } diff --git a/src/2geom/transforms.h b/src/2geom/transforms.h index b8db82f14..1c965eb9f 100644 --- a/src/2geom/transforms.h +++ b/src/2geom/transforms.h @@ -56,12 +56,9 @@ struct TransformConcept { m = t * m; p *= t; p = p * t; - p = t * p; t *= t; t = t * t; t = pow(t, 3); - p /= t; // multiplication by inverse - p = p / t; bool_ = (t == t); bool_ = (t != t); t = T::identity(); diff --git a/src/2geom/utils.h b/src/2geom/utils.h index 31468a204..ecd1b7283 100644 --- a/src/2geom/utils.h +++ b/src/2geom/utils.h @@ -33,7 +33,6 @@ * */ -#include <2geom/math-utils.h> #include <vector> namespace Geom { @@ -43,6 +42,22 @@ inline bool logical_xor (bool a, bool b) { return (a || b) && !(a && b); } void binomial_coefficients(std::vector<size_t>& bc, size_t n); +struct EmptyClass {}; + +/** + * @brief Noncommutative multiplication helper. + * Generates operator*(T, U) from operator*=(T, U). Does not generate operator*(U, T) + * like boost::multipliable does. This makes it suitable for noncommutative cases, + * such as transforms. + */ +template <class T, class U, class B = EmptyClass> +struct MultipliableNoncommutative : B +{ + friend T operator*(T const &lhs, U const &rhs) { + T nrv(lhs); nrv *= rhs; return nrv; + } +}; + } #endif diff --git a/src/seltrans.cpp b/src/seltrans.cpp index 049899e7a..848c0836a 100644 --- a/src/seltrans.cpp +++ b/src/seltrans.cpp @@ -424,7 +424,7 @@ void Inkscape::SelTrans::transform(Geom::Affine const &rel_affine, Geom::Point c g_return_if_fail(_grabbed); g_return_if_fail(!_empty); - Geom::Affine const affine( (Geom::Affine)Geom::Translate(-norm) * rel_affine * (Geom::Affine)Geom::Translate(norm) ); + Geom::Affine const affine( Geom::Translate(-norm) * rel_affine * Geom::Translate(norm) ); if (_show == SHOW_CONTENT) { // update the content @@ -1310,7 +1310,7 @@ gboolean Inkscape::SelTrans::rotateRequest(Geom::Point &pt, guint state) _relative_affine = r2 * r1.inverse(); // Update the handle position - pt = _point * (Geom::Affine)Geom::Translate(-_origin) * _relative_affine * (Geom::Affine)Geom::Translate(_origin); + pt = _point * Geom::Translate(-_origin) * _relative_affine * Geom::Translate(_origin); // Update the status text double degrees = mod360symm(Geom::rad_to_deg(radians)); @@ -1591,7 +1591,7 @@ Geom::Scale Inkscape::calcScaleFactors(Geom::Point const &initial_point, Geom::P // Only for scaling/stretching Geom::Point Inkscape::SelTrans::_calcAbsAffineDefault(Geom::Scale const default_scale) { - Geom::Affine abs_affine = (Geom::Affine)Geom::Translate(-_origin) * Geom::Affine(default_scale) * (Geom::Affine)Geom::Translate(_origin); + Geom::Affine abs_affine = Geom::Translate(-_origin) * Geom::Affine(default_scale) * Geom::Translate(_origin); Geom::Point new_bbox_min = _approximate_bbox->min() * abs_affine; Geom::Point new_bbox_max = _approximate_bbox->max() * abs_affine; @@ -1615,7 +1615,7 @@ Geom::Point Inkscape::SelTrans::_calcAbsAffineDefault(Geom::Scale const default_ Geom::Point Inkscape::SelTrans::_calcAbsAffineGeom(Geom::Scale const geom_scale) { _relative_affine = Geom::Affine(geom_scale); - _absolute_affine = (Geom::Affine)Geom::Translate(-_origin_for_specpoints) * _relative_affine * (Geom::Affine)Geom::Translate(_origin_for_specpoints); + _absolute_affine = Geom::Translate(-_origin_for_specpoints) * _relative_affine * Geom::Translate(_origin_for_specpoints); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); bool const transform_stroke = prefs->getBool("/options/transform/stroke", true); |
