65 lines
1.9 KiB
C++
65 lines
1.9 KiB
C++
#pragma once
|
|
|
|
#include <pdfengine/geometry/rect.hpp>
|
|
#include <cmath>
|
|
|
|
namespace pdfengine {
|
|
namespace geometry {
|
|
|
|
// 2D Affine Transformation Matrix [a b c d e f]
|
|
// [ x' ] [ a c e ] [ x ]
|
|
// [ y' ] = [ b d f ] [ y ]
|
|
// [ 1 ] [ 0 0 1 ] [ 1 ]
|
|
struct Matrix {
|
|
float a = 1.0f; // Scale X
|
|
float b = 0.0f; // Shear Y
|
|
float c = 0.0f; // Shear X
|
|
float d = 1.0f; // Scale Y
|
|
float e = 0.0f; // Translate X
|
|
float f = 0.0f; // Translate Y
|
|
|
|
constexpr Matrix() noexcept = default;
|
|
constexpr Matrix(float aVal, float bVal, float cVal, float dVal, float eVal, float fVal) noexcept
|
|
: a(aVal), b(bVal), c(cVal), d(dVal), e(eVal), f(fVal) {}
|
|
|
|
static constexpr Matrix identity() noexcept {
|
|
return Matrix(1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f);
|
|
}
|
|
|
|
static constexpr Matrix translation(float tx, float ty) noexcept {
|
|
return Matrix(1.0f, 0.0f, 0.0f, 1.0f, tx, ty);
|
|
}
|
|
|
|
static constexpr Matrix scale(float sx, float sy) noexcept {
|
|
return Matrix(sx, 0.0f, 0.0f, sy, 0.0f, 0.0f);
|
|
}
|
|
|
|
static Matrix rotation(float radians) noexcept {
|
|
float cosA = std::cos(radians);
|
|
float sinA = std::sin(radians);
|
|
return Matrix(cosA, sinA, -sinA, cosA, 0.0f, 0.0f);
|
|
}
|
|
|
|
[[nodiscard]] Point transformPoint(const Point& pt) const noexcept {
|
|
return Point(a * pt.x + c * pt.y + e, b * pt.x + d * pt.y + f);
|
|
}
|
|
|
|
[[nodiscard]] Matrix multiply(const Matrix& other) const noexcept {
|
|
return Matrix(
|
|
a * other.a + c * other.b,
|
|
b * other.a + d * other.b,
|
|
a * other.c + c * other.d,
|
|
b * other.c + d * other.d,
|
|
a * other.e + c * other.f + e,
|
|
b * other.e + d * other.f + f
|
|
);
|
|
}
|
|
|
|
[[nodiscard]] float getRotationAngle() const noexcept {
|
|
return std::atan2(b, a);
|
|
}
|
|
};
|
|
|
|
} // namespace geometry
|
|
} // namespace pdfengine
|