aboutsummaryrefslogtreecommitdiff
path: root/include/cru/platform/Matrix.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/cru/platform/Matrix.h')
-rw-r--r--include/cru/platform/Matrix.h110
1 files changed, 110 insertions, 0 deletions
diff --git a/include/cru/platform/Matrix.h b/include/cru/platform/Matrix.h
new file mode 100644
index 00000000..c9a52158
--- /dev/null
+++ b/include/cru/platform/Matrix.h
@@ -0,0 +1,110 @@
+#pragma once
+#include "GraphicsBase.h"
+
+#include <cmath>
+#include <optional>
+
+namespace cru::platform {
+struct Matrix {
+ float m11;
+ float m12;
+ float m21;
+ float m22;
+ float m31;
+ float m32;
+
+ Matrix() {}
+
+ Matrix(float m11, float m12, float m21, float m22, float m31, float m32) {
+ this->m11 = m11;
+ this->m12 = m12;
+ this->m21 = m21;
+ this->m22 = m22;
+ this->m31 = m31;
+ this->m32 = m32;
+ }
+
+ bool IsIdentity() const {
+ return m11 == 1.0f && m12 == 0.0f && m21 == 0.0f && m22 == 1.0f &&
+ m31 == 0.0f && m32 == 0.0f;
+ }
+
+ Matrix& operator*=(const Matrix& matrix) {
+ *this = Product(*this, matrix);
+ return *this;
+ }
+
+ Matrix operator*(const Matrix& matrix) const {
+ return Product(*this, matrix);
+ }
+
+ Point TransformPoint(const Point& point) const {
+ return Point{point.x * m11 + point.y * m21 + m31,
+ point.x * m12 + point.y * m22 + m32};
+ }
+
+ Rect TransformRect(const Rect& rect, bool normalize = true) const {
+ Point lefttop = TransformPoint(rect.GetLeftTop()),
+ rightbottom = TransformPoint(rect.GetRightBottom());
+ auto result =
+ Rect::FromVertices(lefttop.x, lefttop.y, rightbottom.x, rightbottom.y);
+ if (normalize) result = result.Normalize();
+ return result;
+ }
+
+ static Matrix Identity() {
+ return Matrix{1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f};
+ }
+
+ static Matrix Translation(float x, float y) {
+ return Matrix{1.0f, 0.0f, 0.0f, 1.0f, x, y};
+ }
+
+ static Matrix Translation(const Point& point) {
+ return Translation(point.x, point.y);
+ }
+
+ static Matrix Scale(float sx, float sy) {
+ return Matrix{sx, 0.0f, 0.0f, sy, 0.0f, 0.0f};
+ }
+
+ // Clockwise.
+ static Matrix Rotation(float angle) {
+ float r = AngleToRadian(angle);
+ float s = std::sin(r);
+ float c = std::cos(r);
+
+ return Matrix{c, s, -s, c, 0.0f, 0.0f};
+ }
+
+ static Matrix Skew(float sx, float sy) {
+ return Matrix{1.0f, sx, sy, 1.0f, 0.0f, 0.0f};
+ }
+
+ static Matrix Product(const Matrix& a, const Matrix& b) {
+ return Matrix{a.m11 * b.m11 + a.m12 * b.m21,
+ a.m11 * b.m12 + a.m12 * b.m22,
+ a.m21 * b.m11 + a.m22 * b.m21,
+ a.m21 * b.m12 + a.m22 * b.m22,
+ a.m31 * b.m11 + a.m32 * b.m21 + b.m31,
+ a.m31 * b.m12 + a.m32 * b.m22 + b.m32};
+ }
+
+ std::optional<Matrix> Inverted() const {
+ if (m11 * m22 == m12 * m21) return std::nullopt;
+ Matrix result;
+ result.m11 = m22 / (m11 * m22 - m12 * m21);
+ result.m12 = m12 / (m12 * m21 - m11 * m22);
+ result.m21 = m21 / (m12 * m21 - m11 * m22);
+ result.m22 = m11 / (m11 * m22 - m12 * m21);
+ result.m31 = (m21 * m32 - m22 * m31) / (m11 * m22 - m12 * m21);
+ result.m32 = (m31 * m12 - m11 * m32) / (m11 * m22 - m12 * m21);
+ return result;
+ }
+
+ private:
+ static constexpr float PI = 3.1415926535f;
+
+ static float AngleToRadian(float angle) { return angle / 180.f * PI; }
+};
+} // namespace cru::platform