Merge pull request #450 from ATMI/affine2d-post

Added 2D Post Transformations
This commit is contained in:
Recep Aslantas
2025-02-22 14:49:35 +03:00
committed by GitHub
7 changed files with 264 additions and 0 deletions

View File

@@ -0,0 +1,132 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglm_affine2d_post_h
#define cglm_affine2d_post_h
/*
Functions:
CGLM_INLINE void glm_translated2d(mat3 m, vec2 v);
CGLM_INLINE void glm_translated2d_x(mat3 m, float to);
CGLM_INLINE void glm_translated2d_y(mat3 m, float to);
CGLM_INLINE void glm_rotated2d(mat3 m, float angle);
CGLM_INLINE void glm_scaled2d(mat3 m, vec2 v);
CGLM_INLINE void glm_scaled2d_uni(mat3 m, float s);
*/
#include "vec2.h"
/*!
* @brief translate existing transform matrix by v vector
* and store result in same matrix
*
* this is POST transform, applies to existing transform as last transform
*
* @param[in, out] m affine transform
* @param[in] v translate vector [x, y]
*/
CGLM_INLINE
void
glm_translated2d(mat3 m, vec2 v) {
glm_vec2_add(m[2], v, m[2]);
}
/*!
* @brief translate existing transform matrix by x factor
*
* this is POST transform, applies to existing transform as last transform
*
* @param[in, out] m affine transform
* @param[in] x x factor
*/
CGLM_INLINE
void
glm_translated2d_x(mat3 m, float x) {
m[2][0] += x;
}
/*!
* @brief translate existing transform matrix by y factor
*
* this is POST transform, applies to existing transform as last transform
*
* @param[in, out] m affine transform
* @param[in] y y factor
*/
CGLM_INLINE
void
glm_translated2d_y(mat3 m, float y) {
m[2][1] += y;
}
/*!
* @brief rotate existing transform matrix by angle
*
* this is POST transform, applies to existing transform as last transform
*
* @param[in, out] m affine transform
* @param[in] angle angle (radians)
*/
CGLM_INLINE
void
glm_rotated2d(mat3 m, float angle) {
float c = cosf(angle),
s = sinf(angle),
m00 = m[0][0], m10 = m[1][0], m20 = m[2][0],
m01 = m[0][1], m11 = m[1][1], m21 = m[2][1];
m[0][0] = c * m00 - s * m01;
m[1][0] = c * m10 - s * m11;
m[2][0] = c * m20 - s * m21;
m[0][1] = s * m00 + c * m01;
m[1][1] = s * m10 + c * m11;
m[2][1] = s * m20 + c * m21;
}
/*!
* @brief scale existing 2d transform matrix by v vector
*
* this is POST transform, applies to existing transform as last transform
*
* @param[in, out] m affine transform
* @param[in] v scale vector [x, y]
*/
CGLM_INLINE
void
glm_scaled2d(mat3 m, vec2 v) {
m[0][0] *= v[0];
m[1][0] *= v[0];
m[2][0] *= v[0];
m[0][1] *= v[1];
m[1][1] *= v[1];
m[2][1] *= v[1];
}
/*!
* @brief applies uniform scale to existing 2d transform matrix v = [s, s]
*
* this is POST transform, applies to existing transform as last transform
*
* @param[in, out] m affine transform
* @param[in] s scale factor
*/
CGLM_INLINE
void
glm_scaled2d_uni(mat3 m, float s) {
m[0][0] *= s;
m[1][0] *= s;
m[2][0] *= s;
m[0][1] *= s;
m[1][1] *= s;
m[2][1] *= s;
}
#endif /* cglm_affine2d_post_h */

View File

@@ -43,5 +43,6 @@
#include "bezier.h"
#include "ray.h"
#include "affine2d.h"
#include "affine2d-post.h"
#endif /* cglm_h */

View File

@@ -0,0 +1,104 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#include "test_common.h"
TEST_IMPL(GLM_PREFIX, translated2d) {
mat3 m1, m2, tmp;
vec2 v = { 1.2f, 3.4f };
test_rand_transform2d(m1);
glm_mat3_copy(m1, m2);
GLM(translated2d)(m2, v);
glm_translate2d_make(tmp, v);
glm_mat3_mul(tmp, m1, m1);
test_assert_mat3_eq(m1, m2);
TEST_SUCCESS
}
TEST_IMPL(GLM_PREFIX, translated2d_x) {
mat3 m1, m2, tmp;
float x = test_rand();
test_rand_transform2d(m1);
glm_mat3_copy(m1, m2);
GLM(translated2d_x)(m2, x);
glm_translate2d_make(tmp, (vec2) { x, 0.0f });
glm_mat3_mul(tmp, m1, m1);
test_assert_mat3_eq(m1, m2);
TEST_SUCCESS
}
TEST_IMPL(GLM_PREFIX, translated2d_y) {
mat3 m1, m2, tmp;
float y = test_rand();
test_rand_transform2d(m1);
glm_mat3_copy(m1, m2);
GLM(translated2d_y)(m2, y);
glm_translate2d_make(tmp, (vec2) { 0.0f, y });
glm_mat3_mul(tmp, m1, m1);
test_assert_mat3_eq(m1, m2);
TEST_SUCCESS
}
TEST_IMPL(GLM_PREFIX, rotated2d) {
mat3 m1, m2, tmp;
float a = test_rand();
test_rand_transform2d(m1);
glm_mat3_copy(m1, m2);
GLM(rotated2d)(m2, a);
glm_rotate2d_make(tmp, a);
glm_mat3_mul(tmp, m1, m1);
test_assert_mat3_eq(m1, m2);
TEST_SUCCESS
}
TEST_IMPL(GLM_PREFIX, scaled2d) {
mat3 m1, m2, tmp;
vec2 v = { test_rand(), test_rand() };
test_rand_transform2d(m1);
glm_mat3_copy(m1, m2);
GLM(scaled2d)(m2, v);
glm_scale2d_make(tmp, v);
glm_mat3_mul(tmp, m1, m1);
test_assert_mat3_eq(m1, m2);
TEST_SUCCESS
}
TEST_IMPL(GLM_PREFIX, scaled2d_uni) {
mat3 m1, m2, tmp;
float s = test_rand();
test_rand_transform2d(m1);
glm_mat3_copy(m1, m2);
GLM(scaled2d_uni)(m2, s);
glm_scale2d_make(tmp, (vec2) { s, s });
glm_mat3_mul(tmp, m1, m1);
test_assert_mat3_eq(m1, m2);
TEST_SUCCESS
}

View File

@@ -123,6 +123,13 @@ test_rand_mat2x4(mat2x4 dest) {
dest[1][3] = drand48();
}
void
test_rand_transform2d(mat3 dest) {
glm_translate2d_make(dest, (vec2) { drand48(), drand48() });
glm_rotate2d(dest, drand48());
glm_scale2d(dest, (vec2) { drand48(), drand48() });
}
void
test_rand_vec3(vec3 dest) {
dest[0] = drand48();

View File

@@ -41,6 +41,9 @@ test_rand_mat2x3(mat2x3 dest);
void
test_rand_mat2x4(mat2x4 dest);
void
test_rand_transform2d(mat3 dest);
test_status_t
test_assert_eqf(float a, float b);

View File

@@ -33,6 +33,7 @@
#include "test_noise.h"
#include "test_affine.h"
#include "test_affine2d.h"
#include "test_affine2d_post.h"
#include "test_affine_mat.h"
#include "test_aabb2d.h"
#include "test_ray.h"

View File

@@ -97,6 +97,14 @@ TEST_DECLARE(glmc_rotate2d_make)
TEST_DECLARE(glmc_rotate2d)
TEST_DECLARE(glmc_rotate2d_to)
/* affine 2d post */
TEST_DECLARE(glm_translated2d)
TEST_DECLARE(glm_translated2d_x)
TEST_DECLARE(glm_translated2d_y)
TEST_DECLARE(glm_rotated2d)
TEST_DECLARE(glm_scaled2d)
TEST_DECLARE(glm_scaled2d_uni)
/* aabb2d */
TEST_DECLARE(glm_aabb2d_sizev)
@@ -1308,6 +1316,14 @@ TEST_LIST {
TEST_ENTRY(glmc_rotate2d)
TEST_ENTRY(glmc_rotate2d_to)
/* affine 2d post */
TEST_ENTRY(glm_translated2d)
TEST_ENTRY(glm_translated2d_x)
TEST_ENTRY(glm_translated2d_y)
TEST_ENTRY(glm_rotated2d)
TEST_ENTRY(glm_scaled2d)
TEST_ENTRY(glm_scaled2d_uni)
/* aabb2d */
TEST_ENTRY(glm_aabb2d_sizev)