From: Mikko Rasa Date: Mon, 14 Mar 2022 06:52:06 +0000 (+0200) Subject: Rename AffineTransformation to AffineTransform X-Git-Url: http://git.tdb.fi/?p=libs%2Fmath.git;a=commitdiff_plain;h=HEAD Rename AffineTransformation to AffineTransform This seems like a more appropriate term for the operation. --- diff --git a/source/geometry/affinetransform.h b/source/geometry/affinetransform.h new file mode 100644 index 0000000..1cd4011 --- /dev/null +++ b/source/geometry/affinetransform.h @@ -0,0 +1,228 @@ +#ifndef MSP_GEOMETRY_AFFINETRANSFORM_H_ +#define MSP_GEOMETRY_AFFINETRANSFORM_H_ + +#include +#include "angle.h" +#include "boundingbox.h" +#include "ray.h" + +namespace Msp { +namespace Geometry { + +template +class AffineTransform; + + +/** +Helper class to provide specialized operations for AffineTransform. +*/ +template +class AffineTransformOps +{ +protected: + AffineTransformOps() { } +}; + +template +class AffineTransformOps +{ +protected: + AffineTransformOps() { } + +public: + static AffineTransform rotation(const Angle &); +}; + +template +class AffineTransformOps +{ +protected: + AffineTransformOps() { } + +public: + static AffineTransform rotation(const Angle &, const LinAl::Vector &); +}; + + +/** +An affine transformation in D dimensions. Affine transformations preserve +straightness of lines and ratios of distances. Angles and distances themselves +may change. Internally this is represented by a square matrix of size D+1. +*/ +template +class AffineTransform: public AffineTransformOps +{ + friend class AffineTransformOps; + +private: + LinAl::Matrix matrix; + +public: + AffineTransform(); + + static AffineTransform translation(const LinAl::Vector &); + static AffineTransform scaling(const LinAl::Vector &); + static AffineTransform shear(const LinAl::Vector &, const LinAl::Vector &); + + AffineTransform &operator*=(const AffineTransform &); + AffineTransform &invert(); + + const LinAl::Matrix &get_matrix() const { return matrix; } + operator const LinAl::Matrix &() const { return matrix; } + + LinAl::Vector transform(const LinAl::Vector &) const; + LinAl::Vector transform_linear(const LinAl::Vector &) const; + Ray transform(const Ray &) const; + BoundingBox transform(const BoundingBox &) const; +}; + +template +inline AffineTransform::AffineTransform() +{ + this->matrix = LinAl::Matrix::identity(); +} + + +template +AffineTransform AffineTransform::translation(const LinAl::Vector &v) +{ + AffineTransform r; + for(unsigned i=0; i +AffineTransform AffineTransform::scaling(const LinAl::Vector &factors) +{ + AffineTransform r; + for(unsigned i=0; i +AffineTransform AffineTransform::shear(const LinAl::Vector &normal, const LinAl::Vector &shift) +{ + AffineTransform r; + for(unsigned i=0; i +AffineTransform AffineTransformOps::rotation(const Angle &angle) +{ + AffineTransform r; + T c = cos(angle); + T s = sin(angle); + r.matrix(0, 0) = c; + r.matrix(0, 1) = -s; + r.matrix(1, 0) = s; + r.matrix(1, 1) = c; + return r; +} + +template +AffineTransform AffineTransformOps::rotation(const Angle &angle, const LinAl::Vector &axis) +{ + AffineTransform r; + LinAl::Vector axn = normalize(axis); + T c = cos(angle); + T s = sin(angle); + // http://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_and_angle + r.matrix(0, 0) = c+axn.x*axn.x*(1-c); + r.matrix(0, 1) = axn.x*axn.y*(1-c)-axn.z*s; + r.matrix(0, 2) = axn.x*axn.z*(1-c)+axn.y*s; + r.matrix(1, 0) = axn.y*axn.x*(1-c)+axn.z*s; + r.matrix(1, 1) = c+axn.y*axn.y*(1-c); + r.matrix(1, 2) = axn.y*axn.z*(1-c)-axn.x*s; + r.matrix(2, 0) = axn.z*axn.x*(1-c)-axn.y*s; + r.matrix(2, 1) = axn.z*axn.y*(1-c)+axn.x*s; + r.matrix(2, 2) = c+axn.z*axn.z*(1-c); + return r; +} + +template +inline AffineTransform &AffineTransform::operator*=(const AffineTransform &other) +{ + matrix *= other.get_matrix(); + return *this; +} + +template +inline AffineTransform operator*(const AffineTransform &at1, const AffineTransform &at2) +{ + AffineTransform r = at1; + return r *= at2; +} + +template +inline AffineTransform &AffineTransform::invert() +{ + matrix.invert(); + return *this; +} + +template +inline AffineTransform invert(const AffineTransform &at) +{ + AffineTransform r = at; + return r.invert(); +} + +template +inline LinAl::Vector AffineTransform::transform(const LinAl::Vector &v) const +{ + return (matrix*compose(v, T(1))).template slice(0); +} + +template +inline LinAl::Vector AffineTransform::transform_linear(const LinAl::Vector &v) const +{ + return (matrix*compose(v, T(0))).template slice(0); +} + +template +inline Ray AffineTransform::transform(const Ray &ray) const +{ + LinAl::Vector dir = transform_linear(ray.get_direction()); + return Ray(transform(ray.get_start()), dir, ray.get_limit()*dir.norm()); +} + +template +inline BoundingBox AffineTransform::transform(const BoundingBox &bbox) const +{ + LinAl::Vector min_pt; + LinAl::Vector max_pt; + for(unsigned i=0; i<(1< point; + for(unsigned j=0; j>j)&1 ? bbox.get_maximum_coordinate(j) : bbox.get_minimum_coordinate(j)); + + point = transform(point); + + if(i==0) + { + min_pt = point; + max_pt = point; + } + else + { + for(unsigned j=0; j(min_pt, max_pt); +} + +} // namespace Geometry +} // namespace Msp + +#endif diff --git a/source/geometry/affinetransformation.h b/source/geometry/affinetransformation.h deleted file mode 100644 index e311b88..0000000 --- a/source/geometry/affinetransformation.h +++ /dev/null @@ -1,228 +0,0 @@ -#ifndef MSP_GEOMETRY_AFFINETRANSFORMATION_H_ -#define MSP_GEOMETRY_AFFINETRANSFORMATION_H_ - -#include -#include "angle.h" -#include "boundingbox.h" -#include "ray.h" - -namespace Msp { -namespace Geometry { - -template -class AffineTransformation; - - -/** -Helper class to provide specialized operations for AffineTransformation. -*/ -template -class AffineTransformationOps -{ -protected: - AffineTransformationOps() { } -}; - -template -class AffineTransformationOps -{ -protected: - AffineTransformationOps() { } - -public: - static AffineTransformation rotation(const Angle &); -}; - -template -class AffineTransformationOps -{ -protected: - AffineTransformationOps() { } - -public: - static AffineTransformation rotation(const Angle &, const LinAl::Vector &); -}; - - -/** -An affine transformation in D dimensions. Affine transformations preserve -straightness of lines and ratios of distances. Angles and distances themselves -may change. Internally this is represented by a square matrix of size D+1. -*/ -template -class AffineTransformation: public AffineTransformationOps -{ - friend class AffineTransformationOps; - -private: - LinAl::Matrix matrix; - -public: - AffineTransformation(); - - static AffineTransformation translation(const LinAl::Vector &); - static AffineTransformation scaling(const LinAl::Vector &); - static AffineTransformation shear(const LinAl::Vector &, const LinAl::Vector &); - - AffineTransformation &operator*=(const AffineTransformation &); - AffineTransformation &invert(); - - const LinAl::Matrix &get_matrix() const { return matrix; } - operator const LinAl::Matrix &() const { return matrix; } - - LinAl::Vector transform(const LinAl::Vector &) const; - LinAl::Vector transform_linear(const LinAl::Vector &) const; - Ray transform(const Ray &) const; - BoundingBox transform(const BoundingBox &) const; -}; - -template -inline AffineTransformation::AffineTransformation() -{ - this->matrix = LinAl::Matrix::identity(); -} - - -template -AffineTransformation AffineTransformation::translation(const LinAl::Vector &v) -{ - AffineTransformation r; - for(unsigned i=0; i -AffineTransformation AffineTransformation::scaling(const LinAl::Vector &factors) -{ - AffineTransformation r; - for(unsigned i=0; i -AffineTransformation AffineTransformation::shear(const LinAl::Vector &normal, const LinAl::Vector &shift) -{ - AffineTransformation r; - for(unsigned i=0; i -AffineTransformation AffineTransformationOps::rotation(const Angle &angle) -{ - AffineTransformation r; - T c = cos(angle); - T s = sin(angle); - r.matrix(0, 0) = c; - r.matrix(0, 1) = -s; - r.matrix(1, 0) = s; - r.matrix(1, 1) = c; - return r; -} - -template -AffineTransformation AffineTransformationOps::rotation(const Angle &angle, const LinAl::Vector &axis) -{ - AffineTransformation r; - LinAl::Vector axn = normalize(axis); - T c = cos(angle); - T s = sin(angle); - // http://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_and_angle - r.matrix(0, 0) = c+axn.x*axn.x*(1-c); - r.matrix(0, 1) = axn.x*axn.y*(1-c)-axn.z*s; - r.matrix(0, 2) = axn.x*axn.z*(1-c)+axn.y*s; - r.matrix(1, 0) = axn.y*axn.x*(1-c)+axn.z*s; - r.matrix(1, 1) = c+axn.y*axn.y*(1-c); - r.matrix(1, 2) = axn.y*axn.z*(1-c)-axn.x*s; - r.matrix(2, 0) = axn.z*axn.x*(1-c)-axn.y*s; - r.matrix(2, 1) = axn.z*axn.y*(1-c)+axn.x*s; - r.matrix(2, 2) = c+axn.z*axn.z*(1-c); - return r; -} - -template -inline AffineTransformation &AffineTransformation::operator*=(const AffineTransformation &other) -{ - matrix *= other.get_matrix(); - return *this; -} - -template -inline AffineTransformation operator*(const AffineTransformation &at1, const AffineTransformation &at2) -{ - AffineTransformation r = at1; - return r *= at2; -} - -template -inline AffineTransformation &AffineTransformation::invert() -{ - matrix.invert(); - return *this; -} - -template -inline AffineTransformation invert(const AffineTransformation &at) -{ - AffineTransformation r = at; - return r.invert(); -} - -template -inline LinAl::Vector AffineTransformation::transform(const LinAl::Vector &v) const -{ - return (matrix*compose(v, T(1))).template slice(0); -} - -template -inline LinAl::Vector AffineTransformation::transform_linear(const LinAl::Vector &v) const -{ - return (matrix*compose(v, T(0))).template slice(0); -} - -template -inline Ray AffineTransformation::transform(const Ray &ray) const -{ - LinAl::Vector dir = transform_linear(ray.get_direction()); - return Ray(transform(ray.get_start()), dir, ray.get_limit()*dir.norm()); -} - -template -inline BoundingBox AffineTransformation::transform(const BoundingBox &bbox) const -{ - LinAl::Vector min_pt; - LinAl::Vector max_pt; - for(unsigned i=0; i<(1< point; - for(unsigned j=0; j>j)&1 ? bbox.get_maximum_coordinate(j) : bbox.get_minimum_coordinate(j)); - - point = transform(point); - - if(i==0) - { - min_pt = point; - max_pt = point; - } - else - { - for(unsigned j=0; j(min_pt, max_pt); -} - -} // namespace Geometry -} // namespace Msp - -#endif diff --git a/source/geometry/dummy.cpp b/source/geometry/dummy.cpp index 26aad38..be685b0 100644 --- a/source/geometry/dummy.cpp +++ b/source/geometry/dummy.cpp @@ -1,4 +1,4 @@ -#include "affinetransformation.h" +#include "affinetransform.h" #include "angle.h" #include "boundingbox.h" #include "boundingsphere.h" diff --git a/source/geometry/loader.h b/source/geometry/loader.h index 2aff83f..0a9c4b5 100644 --- a/source/geometry/loader.h +++ b/source/geometry/loader.h @@ -140,7 +140,7 @@ template class TransformationLoader: public Loader { protected: - AffineTransformation transformation; + AffineTransform transformation; public: TransformationLoader(); @@ -349,7 +349,7 @@ inline void TransformationLoader::translate(const std::vector &offset) if(offset.size()!=D) throw std::invalid_argument("TransformationLoader::translate"); - transformation *= AffineTransformation::translation(LinAl::Vector(&offset[0])); + transformation *= AffineTransform::translation(LinAl::Vector(&offset[0])); } template @@ -363,10 +363,10 @@ inline void TransformationLoader::scale(const std::vector &s) LinAl::Vector us; for(unsigned i=0; i::scaling(us); + transformation *= AffineTransform::scaling(us); } else - transformation *= AffineTransformation::scaling(LinAl::Vector(&s[0])); + transformation *= AffineTransform::scaling(LinAl::Vector(&s[0])); } template @@ -375,7 +375,7 @@ inline void TransformationLoader::shear(const std::vector &s) if(s.size()!=2*D) throw std::invalid_argument("TransformationLoader::shear"); - transformation *= AffineTransformation::shear(LinAl::Vector(&s[0]), LinAl::Vector(&s[D])); + transformation *= AffineTransform::shear(LinAl::Vector(&s[0]), LinAl::Vector(&s[D])); } @@ -388,7 +388,7 @@ inline ShapeLoader >::ShapeLoader() template inline void ShapeLoader >::rotate(T a) { - TransformationLoader::transformation *= AffineTransformation::rotation(Angle::from_degrees(a)); + TransformationLoader::transformation *= AffineTransform::rotation(Angle::from_degrees(a)); } @@ -401,7 +401,7 @@ inline ShapeLoader >::ShapeLoader() template inline void ShapeLoader >::rotate(T a, T x, T y, T z) { - TransformationLoader::transformation *= AffineTransformation::rotation(Angle::from_degrees(a), LinAl::Vector(x, y, z)); + TransformationLoader::transformation *= AffineTransform::rotation(Angle::from_degrees(a), LinAl::Vector(x, y, z)); } diff --git a/source/geometry/transformedshape.h b/source/geometry/transformedshape.h index 9387123..168fbd9 100644 --- a/source/geometry/transformedshape.h +++ b/source/geometry/transformedshape.h @@ -1,7 +1,7 @@ #ifndef MSP_GEOMETRY_TRANSFORMEDSHAPE_H_ #define MSP_GEOMETRY_TRANSFORMEDSHAPE_H_ -#include "affinetransformation.h" +#include "affinetransform.h" #include "shape.h" namespace Msp { @@ -15,11 +15,11 @@ class TransformedShape: public Shape { private: Shape *shape; - AffineTransformation transformation; - AffineTransformation inverse_trans; + AffineTransform transformation; + AffineTransform inverse_trans; public: - TransformedShape(const Shape &, const AffineTransformation &); + TransformedShape(const Shape &, const AffineTransform &); TransformedShape(const TransformedShape &); TransformedShape &operator=(const TransformedShape &); ~TransformedShape(); @@ -27,7 +27,7 @@ public: virtual TransformedShape *clone() const; const Shape &get_shape() const { return *shape; } - const AffineTransformation &get_transformation() const { return transformation; } + const AffineTransform &get_transformation() const { return transformation; } virtual BoundingBox get_axis_aligned_bounding_box(unsigned = 0) const; virtual bool contains(const LinAl::Vector &) const; @@ -37,7 +37,7 @@ public: }; template -inline TransformedShape::TransformedShape(const Shape &s, const AffineTransformation &t): +inline TransformedShape::TransformedShape(const Shape &s, const AffineTransform &t): shape(s.clone()), transformation(t), inverse_trans(invert(t))