Skip to content

Commit 82e7589

Browse files
committed
karm-math: Initial implementation of a matrix type.
1 parent 079e2f2 commit 82e7589

6 files changed

Lines changed: 161 additions & 29 deletions

File tree

src/libs/karm-gfx/canvas.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,19 @@ void Canvas::origin(Math::Vec2f p) {
2222
}
2323

2424
void Canvas::translate(Math::Vec2f pos) {
25-
transform(Math::Trans2f::makeTranslate(pos));
25+
transform(Math::Trans2f::translate(pos));
2626
}
2727

2828
void Canvas::scale(Math::Vec2f pos) {
29-
transform(Math::Trans2f::makeScale(pos));
29+
transform(Math::Trans2f::scale(pos));
3030
}
3131

3232
void Canvas::rotate(f64 angle) {
33-
transform(Math::Trans2f::makeRotate(angle));
33+
transform(Math::Trans2f::rotate(angle));
3434
}
3535

3636
void Canvas::skew(Math::Vec2f pos) {
37-
transform(Math::Trans2f::makeSkew(pos));
37+
transform(Math::Trans2f::skew(pos));
3838
}
3939

4040
// MARK: Path Operations ---------------------------------------------------

src/libs/karm-gfx/cpu/canvas.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ struct CpuCanvas : Canvas {
2424
Fill fill = Gfx::WHITE;
2525
Stroke stroke{};
2626
Math::Recti clip{};
27-
Math::Trans2f trans = Math::Trans2f::IDENTITY;
27+
Math::Trans2f trans = Math::Trans2f::identity();
2828
Opt<Rc<Surface>> clipMask = NONE;
2929
Math::Recti clipBound = {0, 0};
3030
};

src/libs/karm-math/mat.h

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
#pragma once
2+
3+
#include "vec.h"
4+
5+
namespace Karm::Math {
6+
7+
// Matrices types, column major, post multiply
8+
9+
template <typename T>
10+
union Mat2 {
11+
using Scalar = T;
12+
13+
struct {
14+
T m00, m01;
15+
T m10, m11;
16+
};
17+
18+
struct {
19+
Vec2<T> col0;
20+
Vec2<T> col1;
21+
};
22+
23+
Array<Vec2<T>, 2> cols;
24+
Array<T, 2 * 2> _els;
25+
26+
static constexpr Mat2 identity() {
27+
return {
28+
{1, 0},
29+
{0, 1}
30+
};
31+
}
32+
33+
Mat2() = default;
34+
35+
Mat2(T m00, T m01, T m10, T m11)
36+
: _els{m00, m01, m10, m11} {}
37+
38+
Mat2(Vec2<T> col0, Vec2<T> col1)
39+
: cols{col0, col1} {}
40+
41+
void repr(Io::Emit& e) const {
42+
e("(mat2 ");
43+
for (auto& col : cols) {
44+
e("{}", col);
45+
}
46+
e(")");
47+
}
48+
};
49+
50+
using Mat2i = Mat2<i64>;
51+
using Mat2f = Mat2<f64>;
52+
53+
template <typename T>
54+
union Mat3 {
55+
using Scalar = T;
56+
57+
struct {
58+
T m00, m01, m02;
59+
T m10, m11, m12;
60+
T m20, m21, m22;
61+
};
62+
63+
struct {
64+
Vec3<T> col0;
65+
Vec3<T> col1;
66+
Vec3<T> col2;
67+
};
68+
69+
Array<Vec3<T>, 3> cols;
70+
Array<T, 3 * 3> _els;
71+
72+
Mat3() = default;
73+
74+
Mat3(T m00, T m01, T m02, T m10, T m11, T m12, T m20, T m21, T m22)
75+
: _els{m00, m01, m02, m10, m11, m12, m20, m21, m22} {}
76+
77+
Mat3(Vec3<T> col0, Vec3<T> col1, Vec3<T> col2)
78+
: cols{col0, col1, col2} {}
79+
80+
void repr(Io::Emit& e) const {
81+
e("(mat3 ");
82+
for (auto& col : cols) {
83+
e("{}", col);
84+
}
85+
e(")");
86+
}
87+
};
88+
89+
using Mat3i = Mat3<i64>;
90+
using Mat3f = Mat3<f64>;
91+
92+
template <typename T>
93+
union Mat4 {
94+
using Scalar = T;
95+
96+
struct {
97+
T m00, m01, m02, m03;
98+
T m10, m11, m12, m13;
99+
T m20, m21, m22, m23;
100+
T m30, m31, m32, m33;
101+
};
102+
103+
struct {
104+
Vec4<T> col0;
105+
Vec4<T> col1;
106+
Vec4<T> col2;
107+
Vec4<T> col3;
108+
};
109+
110+
Array<Vec4<T>, 4> cols;
111+
Array<T, 4 * 4> _els;
112+
113+
Mat4() = default;
114+
115+
Mat4(T m00, T m01, T m02, T m03, T m10, T m11, T m12, T m13, T m20, T m21, T m22, T m23, T m30, T m31, T m32, T m33)
116+
: _els{m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33} {}
117+
118+
Mat4(Vec4<T> col0, Vec4<T> col1, Vec4<T> col2, Vec4<T> col3)
119+
: cols{col0, col1, col2, col3} {}
120+
121+
void repr(Io::Emit& e) const {
122+
e("(mat4 ");
123+
for (auto& col : cols) {
124+
e("{}", col);
125+
}
126+
e(")");
127+
}
128+
};
129+
130+
using Mat4i = Mat4<i64>;
131+
using Mat4f = Mat4<f64>;
132+
133+
} // namespace Karm::Math

src/libs/karm-math/tests/test-trans.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ test$("transform-inverse") {
1010
return m.multiply(m.inverse());
1111
};
1212

13-
expect$(makeIdentity(Trans2f::makeRotate(10)).isIdentity());
14-
expect$(makeIdentity(Trans2f::makeSkew(transVec)).isIdentity());
15-
expect$(makeIdentity(Trans2f::makeScale(transVec)).isIdentity());
16-
expect$(makeIdentity(Trans2f::makeTranslate(transVec)).isIdentity());
13+
expect$(makeIdentity(Trans2f::rotate(10)).isIdentity());
14+
expect$(makeIdentity(Trans2f::skew(transVec)).isIdentity());
15+
expect$(makeIdentity(Trans2f::scale(transVec)).isIdentity());
16+
expect$(makeIdentity(Trans2f::translate(transVec)).isIdentity());
1717

1818
return Ok();
1919
}

src/libs/karm-math/trans.h

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,17 @@ union Trans2 {
3030
Vec2<T> o;
3131
};
3232

33-
static Trans2 const IDENTITY;
33+
Array<T, 6> _els{};
3434

35-
static constexpr Trans2 makeRotate(T angle) {
35+
static constexpr Trans2 identity() {
36+
return {
37+
1, 0,
38+
0, 1,
39+
0, 0
40+
};
41+
}
42+
43+
static constexpr Trans2 rotate(T angle) {
3644
T c = cos(angle);
3745
T s = sin(angle);
3846
return {
@@ -42,32 +50,30 @@ union Trans2 {
4250
};
4351
}
4452

45-
static constexpr Trans2 makeSkew(Vec2<T> v) {
53+
static constexpr Trans2 skew(Vec2<T> v) {
4654
return {
4755
1, v.x,
4856
v.y, 1,
4957
0, 0
5058
};
5159
}
5260

53-
static constexpr Trans2 makeScale(Vec2<T> v) {
61+
static constexpr Trans2 scale(Vec2<T> v) {
5462
return {
5563
v.x, 0,
5664
0, v.y,
5765
0, 0
5866
};
5967
}
6068

61-
static constexpr Trans2 makeTranslate(Vec2<T> v) {
69+
static constexpr Trans2 translate(Vec2<T> v) {
6270
return {
6371
1, 0,
6472
0, 1,
6573
v.x, v.y
6674
};
6775
}
6876

69-
Array<T, 6> _els{};
70-
7177
bool rotated() const {
7278
return xx * yy - xy * yx < 0;
7379
}
@@ -165,19 +171,19 @@ union Trans2 {
165171
}
166172

167173
constexpr Trans2 rotated(T angle) {
168-
return multiply(makeRotate(angle));
174+
return multiply(rotate(angle));
169175
}
170176

171177
constexpr Trans2 skewed(Vec2<T> v) {
172-
return multiply(makeSkew(v));
178+
return multiply(skew(v));
173179
}
174180

175181
constexpr Trans2 scaled(Vec2<T> v) {
176-
return multiply(makeScale(v));
182+
return multiply(scale(v));
177183
}
178184

179185
constexpr Trans2 translated(Vec2<T> v) {
180-
return multiply(makeTranslate(v));
186+
return multiply(translate(v));
181187
}
182188

183189
constexpr Trans2 inverse() const {
@@ -212,14 +218,7 @@ union Trans2 {
212218
}
213219
};
214220

215-
template <typename T>
216-
Trans2<T> const Trans2<T>::IDENTITY = {
217-
1, 0,
218-
0, 1,
219-
0, 0
220-
};
221-
222-
using Trans2i = Trans2<isize>;
221+
using Trans2i = Trans2<i64>;
223222

224223
using Trans2f = Trans2<f64>;
225224

src/web/vaev-driver/print.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ export Generator<Print::Page> print(Gc::Ref<Dom::Document> dom, Print::Settings
223223
Layout::paint(fragment, *pageStack);
224224
pageStack->prepare();
225225

226-
co_yield Print::Page(settings.paper, makeRc<Scene::Transform>(pageStack, Math::Trans2f::makeScale(media.resolution.toDppx())));
226+
co_yield Print::Page(settings.paper, makeRc<Scene::Transform>(pageStack, Math::Trans2f::scale(media.resolution.toDppx())));
227227

228228
if (outReal.completelyLaidOut)
229229
break;

0 commit comments

Comments
 (0)