Kale
Loading...
Searching...
No Matches
Transform.cpp
Go to the documentation of this file.
1/*
2 Copyright 2022 Rishi Challa
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17#include "Transform.hpp"
18
20
21#include <cmath>
22
23using namespace Kale;
24
29 1.0f, 0.0f, 0.0f,
30 0.0f, 1.0f, 0.0f,
31 0.0f, 0.0f, 1.0f
32}) {
33 // Empty Body
34}
35
40Transform::Transform(const Matrix3f& matrix) : Matrix3f(matrix) {
41 // Empty Body
42}
43
49 // Empty Body
50}
51
56Transform::Transform(const std::array<float, 9>& arr) : Matrix3f(arr) {
57 // Empty Body
58}
59
64Transform::Transform(std::array<float, 9>&& arr) : Matrix3f(arr) {
65 // Empty Body
66}
67
75Transform::Transform(const Vector2f& translation, float rotation, const Vector2f& scaleFactor, AngleUnit unit) : Matrix3f({
76 cos(unit == AngleUnit::Degree ? degToRad(rotation) : rotation) * scaleFactor.x, -sin(unit == AngleUnit::Degree ? degToRad(rotation) : rotation) * scaleFactor.y, translation.x,
77 sin(unit == AngleUnit::Degree ? degToRad(rotation) : rotation) * scaleFactor.x, cos(unit == AngleUnit::Degree ? degToRad(rotation) : rotation) * scaleFactor.y, translation.y,
78 0.0f, 0.0f, 1.0f
79}) {
80 // Empty Body
81}
82
92Transform::Transform(float translateX, float translateY, float rotation, float scaleX, float scaleY, AngleUnit unit) : Matrix3f({
93 cos(unit == AngleUnit::Degree ? degToRad(rotation) : rotation) * scaleX, -sin(unit == AngleUnit::Degree ? degToRad(rotation) : rotation) * scaleY, translateX,
94 sin(unit == AngleUnit::Degree ? degToRad(rotation) : rotation) * scaleX, cos(unit == AngleUnit::Degree ? degToRad(rotation) : rotation) * scaleY, translateY,
95 0.0f, 0.0f, 1.0f
96}) {
97 // Empty Body
98}
99
104 data = {
105 1.0f, 0.0f, 0.0f,
106 0.0f, 1.0f, 0.0f,
107 0.0f, 0.0f, 1.0f
108 };
109}
110
115void Transform::scale(const Vector2f& vec) {
117 vec.x, 0.0f, 0.0f,
118 0.0f, vec.y, 0.0f,
119 0.0f, 0.0f, 1.0f
120 })).data;
121}
122
128void Transform::scale(float x, float y) {
130 x, 0.0f, 0.0f,
131 0.0f, y, 0.0f,
132 0.0f, 0.0f, 1.0f
133 })).data;
134}
135
140void Transform::scale(float factor) {
142 factor, 0.0f, 0.0f,
143 0.0f, factor, 0.0f,
144 0.0f, 0.0f, 1.0f
145 })).data;
146}
147
153void Transform::scale(float factor, const Vector2f& origin) {
154 translate(origin);
155 scale(factor);
156 translate(-origin);
157}
158
165void Transform::scale(float x, float y, const Vector2f& origin) {
166 translate(origin);
167 scale(x, y);
168 translate(-origin);
169}
170
177 1.0f, 0.0f, vec.x,
178 0.0f, 1.0f, vec.y,
179 0.0f, 0.0f, 1.0f
180 })).data;
181}
182
188void Transform::translate(float x, float y) {
190 1.0f, 0.0f, x,
191 0.0f, 1.0f, y,
192 0.0f, 0.0f, 1.0f
193 })).data;
194}
195
201void Transform::rotate(float angle, AngleUnit unit) {
202 float c = cos(unit == AngleUnit::Degree ? degToRad(angle) : angle);
203 float s = sin(unit == AngleUnit::Degree ? degToRad(angle) : angle);
205 c, -s, 0.0f,
206 s, c, 0.0f,
207 0.0f, 0.0f, 1.0f
208 })).data;
209}
210
217void Transform::rotate(float angle, AngleUnit unit, const Vector2f& origin) {
218 translate(origin);
219 rotate(angle, unit);
220 translate(-origin);
221}
222
228void Transform::setTranslation(float x, float y) {
229 data[2] = x;
230 data[5] = y;
231}
232
238 data[2] = vec.x;
239 data[5] = vec.y;
240}
241
247 return {data[2], data[5]};
248}
249
255void Transform::setRotation(float angle, AngleUnit unit) {
256 if (unit == AngleUnit::Degree) angle = degToRad(angle);
258 float c = cos(angle);
259 float s = sin(angle);
260 data[0] = scale.x * c;
261 data[1] = scale.y * -s;
262 data[3] = scale.x * s;
263 data[4] = scale.y * c;
264}
265
272 float angle = atan2(data[3], data[4]);
273 if (unit == AngleUnit::Degree) angle = radToDeg(angle);
274 return angle;
275}
276
282void Transform::setScale(float scaleX, float scaleY) {
283 float c = cos(getRotation(AngleUnit::Radian));
284 data[0] = scaleX * c;
285 data[4] = scaleY * c;
286}
287
292void Transform::setScale(float scale) {
293 float c = cos(getRotation(AngleUnit::Radian));
294 data[0] = scale * c;
295 data[4] = scale * c;
296}
297
303 return {
304 sqrt(data[3] * data[3] + data[4] * data[4]),
305 sqrt(data[0] * data[0] + data[1] * data[1])
306 };
307}
308
315 return {vec.x * data[0] + vec.y * data[1] + data[2], vec.x * data[3] + vec.y * data[4] + data[5]};
316}
317
323 vec.x = vec.x * data[0] + vec.y * data[1] + data[2];
324 vec.y = vec.x * data[3] + vec.y * data[4] + data[5];
325}
326
334 float den = data[0] * data[4] - data[1] * data[3];
335 return {
336 (data[1] * data[5] - data[1] * vec.y - data[2] * data[4] + data[4] * vec.x) / den,
337 (-data[0] * data[5] + data[0] * vec.y + data[2] * data[3] - data[3] * vec.x) / den
338 };
339 // Below system of equations represents transformation where k, j = vec.x, vec.y
340 // x * n0 + y * n1 + n2 = k
341 // x * n3 + y * n4 + n5 = j
342 // Solve the above for x & y ->
343 // x = (n1*n5 - n1*j - n2*n4 + n4*k) / (n0*n4 - n1*n3)
344 // y = (-n0*n5 + n0*j + n2*n3 - n3*k) / (n0*n4 - n1*n3)
345}
346
353 float den = data[0] * data[4] - data[1] * data[3];
354 vec.x = (data[1] * data[5] - data[1] * vec.y - data[2] * data[4] + data[4] * vec.x) / den;
355 vec.y = (-data[0] * data[5] + data[0] * vec.y + data[2] * data[3] - data[3] * vec.x) / den;
356}
357
364 return {
365 transform(rect.point1),
366 transform(rect.point2),
367 transform(rect.point3),
368 transform(rect.point4)
369 };
370}
371
379 return {
384 };
385}
386
393 return {
394 transform(rect.topLeft),
395 transform(rect.topRight()),
397 transform(rect.bottomLeft())
398 };
399}
400
408 return {
413 };
414}
415
421Ray Transform::transform(const Ray& ray) const {
422 Ray newRay;
423 newRay.origin = transform(ray.origin);
424 newRay.direction = transform(ray.direction + ray.origin) - newRay.origin;
425 newRay.direction /= newRay.direction.magnitude();
426 return newRay;
427}
428
436 Ray newRay;
437 newRay.origin = inverseTransform(ray.origin);
438 newRay.direction = inverseTransform(ray.direction + ray.origin) - newRay.origin;
439 newRay.direction /= newRay.direction.magnitude();
440 return newRay;
441}
442
448Line Transform::transform(const Line& line) const {
449 return {transform(line.point1), transform(line.point2)};
450}
451
459 return {inverseTransform(line.point1), inverseTransform(line.point2)};
460}
461
467Circle Transform::transform(const Circle& circle) const {
468 Circle newCircle;
469 newCircle.center = transform(circle.center);
470 newCircle.radius = transform({circle.radius, 0.0f}).magnitude();
471 return newCircle;
472}
473
481 Circle newCircle;
482 newCircle.center = inverseTransform(circle.center);
483 newCircle.radius = inverseTransform({circle.radius, 0.0f}).magnitude();
484 return newCircle;
485}
Matrix< w, h, T > operator*(T scalar) const
Definition Matrix.hpp:267
std::array< T, w *h > data
Definition Matrix.hpp:55
float getRotation(AngleUnit unit) const
void scale(const Vector2f &vec)
void inverseTransformInplace(Vector2f &vec) const
void transformInplace(Vector2f &vec) const
void setRotation(float angle, AngleUnit unit)
void setScale(float scaleX, float scaleY)
void rotate(float angle, AngleUnit unit)
void setTranslation(float x, float y)
Vector2f getScale() const
void translate(const Vector2f &vec)
Vector2f inverseTransform(const Vector2f &vec) const
Vector2f getTranslation() const
Vector2f transform(const Vector2f &vec) const
std::enable_if< std::is_floating_point< A >::value, T >::type magnitude() const
Definition Vector.hpp:123
AngleUnit
Definition Utils.hpp:30
constexpr float radToDeg(float rad)
Definition Utils.hpp:48
Matrix< 3, 3, float > Matrix3f
Definition Matrix.hpp:507
constexpr float degToRad(float deg)
Definition Utils.hpp:39
Vector2f center
Definition Circle.hpp:31
float radius
Definition Circle.hpp:36
Vector2f point2
Definition Line.hpp:36
Vector2f point1
Definition Line.hpp:31
Vector2f direction
Definition Ray.hpp:38
Vector2f origin
Definition Ray.hpp:33
Vector2f bottomRight
Definition Rect.hpp:36
Vector2f topRight() const
Definition Rect.cpp:56
Vector2f bottomLeft() const
Definition Rect.cpp:64
Vector2f topLeft
Definition Rect.hpp:31