1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop/*
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop * Class for pure transformations, such as translating, scaling, stretching, skewing, and rotating. Pure means that they cannot
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop * be combined. This is what makes them different from affine transformations. Pure transformations are being used in the selector
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop * tool and node tool
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop *
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop * Authors:
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop * Diederik van Lierop <mail@diedenrezi.nl>
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop *
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop * Copyright (C) 2015 Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop *
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop * Released under GNU GPL, read the file 'COPYING' for more information
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop */
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop#ifndef SEEN_PURE_TRANSFORM_H
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop#define SEEN_PURE_TRANSFORM_H
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop#include <glib.h> // for g_warning
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop#include "snapper.h" // for SnapConstraint
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lieropclass SnapManager;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lieropnamespace Inkscape {
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lieropclass PureTransform {
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lieropprotected:
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop virtual SnappedPoint snap(::SnapManager *sm, SnapCandidatePoint const &p, Geom::Point pt_orig, Geom::OptRect const &bbox_to_snap) const = 0;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop virtual Geom::Point getTransformedPoint(SnapCandidatePoint const &p) const = 0;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop virtual void storeTransform(SnapCandidatePoint const original_point, SnappedPoint snapped_point) = 0;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lieroppublic:
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop //PureTransform();
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop virtual ~PureTransform() {};
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop// virtual PureTransform * clone () const = 0; // https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Virtual_Constructor
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop // Snap a group of points
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop SnappedPoint best_snapped_point;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop void snap(::SnapManager *sm, std::vector<Inkscape::SnapCandidatePoint> const &points, Geom::Point const &pointer);
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop};
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop// **************************************************************************************************************
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lieropclass PureTranslate: public PureTransform {
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lieropprotected:
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop Geom::Point _vector;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop Geom::Point _vector_snapped;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop virtual SnappedPoint snap(::SnapManager *sm, SnapCandidatePoint const &p, Geom::Point pt_orig, Geom::OptRect const &bbox_to_snap) const;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop virtual Geom::Point getTransformedPoint(SnapCandidatePoint const &p) const;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop virtual void storeTransform(SnapCandidatePoint const original_point, SnappedPoint snapped_point);
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lieroppublic:
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop// PureTranslate(); // Default constructor
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop// PureTranslate(PureTranslate const &); // Copy constructor
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop virtual ~PureTranslate() {};
b1b352ba8dc52b86acfbf68071a62dfb9a9792c3Kris De Gussem PureTranslate(Geom::Point vector = Geom::Point()) : _vector(vector), _vector_snapped(vector) {}
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop Geom::Point getTranslationSnapped() {return _vector_snapped;}
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop// PureTranslate * clone () const {return new PureTranslate(*this);}
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop};
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lieropclass PureTranslateConstrained: public PureTranslate {
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lieropprotected:
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop Geom::Dim2 _direction;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop virtual SnappedPoint snap(::SnapManager *sm, SnapCandidatePoint const &p, Geom::Point pt_orig, Geom::OptRect const &bbox_to_snap) const;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lieroppublic:
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop virtual ~PureTranslateConstrained() {};
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop PureTranslateConstrained(Geom::Coord displacement, Geom::Dim2 direction):
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop PureTranslate() {
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop _vector[direction] = displacement;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop _vector[1-direction] = 0.0;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop _direction = direction;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop }
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop // PureTranslateConstrained * clone () const {return new PureTranslateConstrained(*this);}
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop};
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop// **************************************************************************************************************
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lieropclass PureScale: public PureTransform {
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lieropprotected:
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop Geom::Scale _scale;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop Geom::Scale _scale_snapped;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop Geom::Point _origin;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop bool _uniform;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop virtual SnappedPoint snap(::SnapManager *sm, SnapCandidatePoint const &p, Geom::Point pt_orig, Geom::OptRect const &bbox_to_snap) const;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop virtual Geom::Point getTransformedPoint(SnapCandidatePoint const &p) const;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop virtual void storeTransform(SnapCandidatePoint const original_point, SnappedPoint snapped_point);
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lieroppublic:
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop// PureScale(); // Default constructor
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop// PureScale(PureScale const &); // Copy constructor
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop virtual ~PureScale() {};
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
b1b352ba8dc52b86acfbf68071a62dfb9a9792c3Kris De Gussem PureScale(Geom::Scale scale, Geom::Point origin, bool uniform) :
b1b352ba8dc52b86acfbf68071a62dfb9a9792c3Kris De Gussem _scale (scale),
b1b352ba8dc52b86acfbf68071a62dfb9a9792c3Kris De Gussem _scale_snapped (scale),
b1b352ba8dc52b86acfbf68071a62dfb9a9792c3Kris De Gussem _origin (origin),
b1b352ba8dc52b86acfbf68071a62dfb9a9792c3Kris De Gussem _uniform (uniform)
b1b352ba8dc52b86acfbf68071a62dfb9a9792c3Kris De Gussem {}
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop Geom::Scale getScaleSnapped() {return _scale_snapped;}
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop// PureScale * clone () const {return new PureScale (*this);}
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop};
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lieropclass PureScaleConstrained: public PureScale {
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop//Magnitude of the scale components will be the same, but the sign could still be different ()
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lieropprotected:
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop virtual SnappedPoint snap(::SnapManager *sm, SnapCandidatePoint const &p, Geom::Point pt_orig, Geom::OptRect const &bbox_to_snap) const;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lieroppublic:
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop virtual ~PureScaleConstrained() {};
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop PureScaleConstrained(Geom::Scale scale, Geom::Point origin):
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop PureScale(scale, origin, true) {}; // Non-uniform constrained scaling is not supported
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop// PureScaleConstrained * clone () const {return new PureScaleConstrained(*this);}
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop};
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop// **************************************************************************************************************
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lieropclass PureStretchConstrained: public PureTransform {
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop// A stretch is always implicitly constrained
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lieropprotected:
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop Geom::Coord _magnitude;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop Geom::Scale _stretch_snapped;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop Geom::Point _origin;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop Geom::Dim2 _direction;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop bool _uniform;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop virtual SnappedPoint snap(::SnapManager *sm, SnapCandidatePoint const &p, Geom::Point pt_orig, Geom::OptRect const &bbox_to_snap) const;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop virtual Geom::Point getTransformedPoint(SnapCandidatePoint const &p) const;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop virtual void storeTransform(SnapCandidatePoint const original_point, SnappedPoint snapped_point);
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lieroppublic:
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop virtual ~PureStretchConstrained() {};
b1b352ba8dc52b86acfbf68071a62dfb9a9792c3Kris De Gussem PureStretchConstrained(Geom::Coord magnitude, Geom::Point origin, Geom::Dim2 direction, bool uniform) :
b1b352ba8dc52b86acfbf68071a62dfb9a9792c3Kris De Gussem _magnitude (magnitude),
b1b352ba8dc52b86acfbf68071a62dfb9a9792c3Kris De Gussem _stretch_snapped (Geom::Scale(magnitude, magnitude)),
b1b352ba8dc52b86acfbf68071a62dfb9a9792c3Kris De Gussem _origin (origin),
b1b352ba8dc52b86acfbf68071a62dfb9a9792c3Kris De Gussem _direction (direction),
b1b352ba8dc52b86acfbf68071a62dfb9a9792c3Kris De Gussem _uniform (uniform)
b1b352ba8dc52b86acfbf68071a62dfb9a9792c3Kris De Gussem {
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop if (not uniform) {
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop _stretch_snapped[1-direction] = 1.0;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop }
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop }
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop Geom::Scale getStretchSnapped() {return _stretch_snapped;}
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop Geom::Coord getMagnitude() {return _magnitude;}
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop Geom::Coord getMagnitudeSnapped() {return _stretch_snapped[_direction];}
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop// PureStretchConstrained * clone () const {return new PureStretchConstrained(*this);}
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop};
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop// **************************************************************************************************************
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lieropclass PureSkewConstrained: public PureTransform {
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop// A skew is always implicitly constrained
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lieropprotected:
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop Geom::Coord _skew;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop Geom::Coord _skew_snapped;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop Geom::Coord _scale;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop Geom::Point _origin;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop Geom::Dim2 _direction;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop virtual SnappedPoint snap(::SnapManager *sm, SnapCandidatePoint const &p, Geom::Point pt_orig, Geom::OptRect const &bbox_to_snap) const;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop Geom::Point getTransformedPoint(SnapCandidatePoint const &p) const;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop virtual void storeTransform(SnapCandidatePoint const original_point, SnappedPoint snapped_point);
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lieroppublic:
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop virtual ~PureSkewConstrained() {};
b1b352ba8dc52b86acfbf68071a62dfb9a9792c3Kris De Gussem PureSkewConstrained(Geom::Coord skew, Geom::Coord scale, Geom::Point origin, Geom::Dim2 direction) :
b1b352ba8dc52b86acfbf68071a62dfb9a9792c3Kris De Gussem _skew (skew),
b1b352ba8dc52b86acfbf68071a62dfb9a9792c3Kris De Gussem _skew_snapped (skew),
b1b352ba8dc52b86acfbf68071a62dfb9a9792c3Kris De Gussem _scale (scale),
b1b352ba8dc52b86acfbf68071a62dfb9a9792c3Kris De Gussem _origin (origin),
b1b352ba8dc52b86acfbf68071a62dfb9a9792c3Kris De Gussem _direction (direction)
b1b352ba8dc52b86acfbf68071a62dfb9a9792c3Kris De Gussem {};
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop Geom::Coord getSkewSnapped() {return _skew_snapped;}
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop// PureSkewConstrained * clone () const {return new PureSkewConstrained(*this);}
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop};
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop// **************************************************************************************************************
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lieropclass PureRotateConstrained: public PureTransform {
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop// A rotation is always implicitly constrained, so we will hide the constructor by making it protected; devs should use PureRotateConstrained instead
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop// It's _constraint member variable though will be empty
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lieropprotected:
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop double _angle; // in radians
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop double _angle_snapped;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop Geom::Point _origin;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop bool _uniform;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop virtual SnappedPoint snap(::SnapManager *sm, SnapCandidatePoint const &p, Geom::Point pt_orig, Geom::OptRect const &bbox_to_snap) const;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop virtual Geom::Point getTransformedPoint(SnapCandidatePoint const &p) const;
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop virtual void storeTransform(SnapCandidatePoint const original_point, SnappedPoint snapped_point);
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lieroppublic:
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop// PureRotate(); // Default constructor
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop// PureRotate(PureRotate const &); // Copy constructor
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop virtual ~PureRotateConstrained() {};
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
b1b352ba8dc52b86acfbf68071a62dfb9a9792c3Kris De Gussem PureRotateConstrained(double angle, Geom::Point origin) :
b1b352ba8dc52b86acfbf68071a62dfb9a9792c3Kris De Gussem _angle (angle), // in radians!
b1b352ba8dc52b86acfbf68071a62dfb9a9792c3Kris De Gussem _angle_snapped (angle),
b1b352ba8dc52b86acfbf68071a62dfb9a9792c3Kris De Gussem _origin (origin),
b1b352ba8dc52b86acfbf68071a62dfb9a9792c3Kris De Gussem _uniform (true) // We do not yet allow for simultaneous rotation and scaling
b1b352ba8dc52b86acfbf68071a62dfb9a9792c3Kris De Gussem {}
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop double getAngleSnapped() {return _angle_snapped;}
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop// PureRotate * clone () const {return new PureRotate(*this);}
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop};
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop}
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop#endif // !SEEN_PURE_TRANSFORM_H
1f1db4ce175a4f7109928377193537db929d1202Diederik van Lierop