diff --git a/libs/math/include/psemek/math/shear.hpp b/libs/math/include/psemek/math/shear.hpp new file mode 100644 index 00000000..d19181fc --- /dev/null +++ b/libs/math/include/psemek/math/shear.hpp @@ -0,0 +1,123 @@ +#pragma once + +#include +#include + +#include + +namespace psemek::math +{ + + // Shear in the (i,j)-plane that replaces x[i] with x[i] + x[j] * factor + // E.g. shear(0, 1, m) is the usual 2D horizontal shear + template + struct shear + { + std::size_t i, j; + T factor; + + shear(); + shear(std::size_t i, std::size_t j, T factor); + shear(shear const &) = default; + + matrix affine_matrix() const; + matrix linear_matrix() const; + vector translation_vector() const; + matrix homogeneous_matrix() const; + + affine_transform transform() const; + + vector operator()(vector const & v) const; + point operator()(point const & p) const; + + private: + template + void fill_matrix(Matrix & m) const; + }; + + template + shear::shear() + : i{0} + , j{1} + , factor{0} + { + assert(i < N); + assert(j < N); + } + + template + shear::shear(std::size_t i, std::size_t j, T factor) + : i{i} + , j{j} + , factor{factor} + { + assert(i < N); + assert(j < N); + } + + template + matrix shear::affine_matrix() const + { + auto result = matrix::identity(); + fill_matrix(result); + return result; + } + + template + matrix shear::linear_matrix() const + { + auto result = matrix::identity(); + fill_matrix(result); + return result; + } + + template + vector shear::translation_vector() const + { + return vector::zero(); + } + + template + matrix shear::homogeneous_matrix() const + { + auto result = matrix::identity(); + fill_matrix(result); + return result; + } + + template + affine_transform shear::transform() const + { + return {affine_matrix()}; + } + + template + vector shear::operator()(vector const & v) const + { + auto result = v; + result[i] += result[j] * factor; + return result; + } + + template + point shear::operator()(point const & p) const + { + auto result = p; + result[i] += result[j] * factor; + return result; + } + + template + template + void shear::fill_matrix(Matrix & m) const + { + m[i][j] = factor; + } + + template + shear inverse(shear const & r) + { + return {r.i, r.j, -r.factor}; + } + +}