diff --git a/basic-geometry-dev/basic-geometry-dev.vcxproj b/basic-geometry-dev/basic-geometry-dev.vcxproj index ea906eb..57efd13 100644 --- a/basic-geometry-dev/basic-geometry-dev.vcxproj +++ b/basic-geometry-dev/basic-geometry-dev.vcxproj @@ -21,6 +21,8 @@ + + @@ -29,6 +31,8 @@ + + 16.0 diff --git a/basic-geometry-dev/basic-geometry-dev.vcxproj.filters b/basic-geometry-dev/basic-geometry-dev.vcxproj.filters index e073d59..5ffa2c2 100644 --- a/basic-geometry-dev/basic-geometry-dev.vcxproj.filters +++ b/basic-geometry-dev/basic-geometry-dev.vcxproj.filters @@ -21,10 +21,22 @@ Исходные файлы + + Исходные файлы + + + Исходные файлы + Файлы заголовков + + Файлы заголовков + + + Файлы заголовков + \ No newline at end of file diff --git a/basic-geometry-dev/main.c b/basic-geometry-dev/main.c index c3c1035..13ca36a 100644 --- a/basic-geometry-dev/main.c +++ b/basic-geometry-dev/main.c @@ -9,7 +9,9 @@ #include #endif // _WINDOWS_ +#include "printing_utils.h" #include "vector3_pair_difference.h" +#include "affine3.h" typedef struct { BGC_FP32_Turn3 versor1, versor2, result; @@ -132,20 +134,56 @@ int main() { } */ +void test_fp32_quaternion_set_matrix() +{ + BGC_FP32_Turn3 turn; + BGC_FP32_Matrix3x3 rotation; + BGC_FP32_Quaternion quaternion; + + bgc_fp32_turn3_set_rotation(&turn, 1.0f, 1.0f, 1.0f, 120.0f, BGC_ANGLE_UNIT_DEGREES); -#include "affine3.h" + bgc_fp32_turn3_get_rotation_matrix(&rotation, &turn); + + if (bgc_fp32_quaternion_set_rotation_matrix(&quaternion, &rotation) == BGC_FAILURE) { + printf("Failed\n"); + return; + } + + print_fp32_quaternion(&quaternion); + print_fp32_quaternion(&turn._versor); +} + +void test_fp64_quaternion_set_matrix() +{ + BGC_FP64_Turn3 turn; + BGC_FP64_Matrix3x3 rotation; + BGC_FP64_Quaternion quaternion; + + bgc_fp64_turn3_set_rotation(&turn, 1.0, 1.0, 1.0, 120.0, BGC_ANGLE_UNIT_DEGREES); + + bgc_fp64_turn3_get_rotation_matrix(&rotation, &turn); + + if (bgc_fp64_quaternion_set_rotation_matrix(&quaternion, &rotation) == BGC_FAILURE) { + printf("Failed\n"); + return; + } + + print_fp64_quaternion(&quaternion); + print_fp64_quaternion(&turn._versor); +} int main() { //test_fp32_pair_difference(); - test_fp64_pair_difference(); + //test_fp64_pair_difference(); //printf("Affine3 performance test: %f\n", test_bgc_affine3_performance(10000000, 10)); //printf("sizeof(BGC_FP32_Affine3) = %zu\n", sizeof(BGC_FP32_Affine3)); //printf("offsetof(shift) = %zu\n", offsetof(BGC_FP32_Affine3, shift)); //printf("sizeof(BGC_FP32_Matrix3x3) = %zu\n", sizeof(BGC_FP32_Matrix3x3)); + + test_fp32_quaternion_set_matrix(); return 0; } - diff --git a/basic-geometry/matrix2x2.h b/basic-geometry/matrix2x2.h index 99007c1..272fad3 100644 --- a/basic-geometry/matrix2x2.h +++ b/basic-geometry/matrix2x2.h @@ -129,28 +129,20 @@ inline int bgc_fp64_matrix2x2_is_singular(const BGC_FP64_Matrix2x2* const matrix inline int bgc_fp32_matrix2x2_is_rotation(const BGC_FP32_Matrix2x2* const matrix) { - BGC_FP32_Matrix2x2 product; + const float r1r1 = matrix->r1c1 * matrix->r1c1 + matrix->r1c2 * matrix->r1c2; + const float r1r2 = matrix->r1c1 * matrix->r2c1 + matrix->r1c2 * matrix->r2c2; + const float r2r2 = matrix->r2c1 * matrix->r2c1 + matrix->r2c2 * matrix->r2c2; - product.r1c1 = matrix->r1c1 * matrix->r1c1 + matrix->r1c2 * matrix->r2c1; - product.r1c2 = matrix->r1c1 * matrix->r1c2 + matrix->r1c2 * matrix->r2c2; - - product.r2c1 = matrix->r2c1 * matrix->r1c1 + matrix->r2c2 * matrix->r2c1; - product.r2c2 = matrix->r2c1 * matrix->r1c2 + matrix->r2c2 * matrix->r2c2; - - return bgc_fp32_matrix2x2_is_identity(&product); + return bgc_fp32_is_square_unit(r1r1) && bgc_fp32_is_square_unit(r2r2) && bgc_fp32_is_zero(r1r2); } inline int bgc_fp64_matrix2x2_is_rotation(const BGC_FP64_Matrix2x2* const matrix) { - BGC_FP64_Matrix2x2 product; + const double r1r1 = matrix->r1c1 * matrix->r1c1 + matrix->r1c2 * matrix->r1c2; + const double r1r2 = matrix->r1c1 * matrix->r2c1 + matrix->r1c2 * matrix->r2c2; + const double r2r2 = matrix->r2c1 * matrix->r2c1 + matrix->r2c2 * matrix->r2c2; - product.r1c1 = matrix->r1c1 * matrix->r1c1 + matrix->r1c2 * matrix->r2c1; - product.r1c2 = matrix->r1c1 * matrix->r1c2 + matrix->r1c2 * matrix->r2c2; - - product.r2c1 = matrix->r2c1 * matrix->r1c1 + matrix->r2c2 * matrix->r2c1; - product.r2c2 = matrix->r2c1 * matrix->r1c2 + matrix->r2c2 * matrix->r2c2; - - return bgc_fp64_matrix2x2_is_identity(&product); + return bgc_fp64_is_square_unit(r1r1) && bgc_fp64_is_square_unit(r2r2) && bgc_fp64_is_zero(r1r2); } // ==================== Copy ==================== // diff --git a/basic-geometry/matrix3x3.h b/basic-geometry/matrix3x3.h index f38bd1b..c177da4 100644 --- a/basic-geometry/matrix3x3.h +++ b/basic-geometry/matrix3x3.h @@ -294,40 +294,38 @@ inline int bgc_fp64_matrix3x3_is_singular(const BGC_FP64_Matrix3x3* const matrix inline int bgc_fp32_matrix3x3_is_rotation(const BGC_FP32_Matrix3x3* const matrix) { - BGC_FP32_Matrix3x3 product; + const float r1r1 = matrix->r1c1 * matrix->r1c1 + matrix->r1c2 * matrix->r1c2 + matrix->r1c3 * matrix->r1c3; + const float r2r2 = matrix->r2c1 * matrix->r2c1 + matrix->r2c2 * matrix->r2c2 + matrix->r2c3 * matrix->r2c3; + const float r3r3 = matrix->r3c1 * matrix->r3c1 + matrix->r3c2 * matrix->r3c2 + matrix->r3c3 * matrix->r3c3; - product.r1c1 = matrix->r1c1 * matrix->r1c1 + matrix->r1c2 * matrix->r2c1 + matrix->r1c3 * matrix->r3c1; - product.r1c2 = matrix->r1c1 * matrix->r1c2 + matrix->r1c2 * matrix->r2c2 + matrix->r1c3 * matrix->r3c2; - product.r1c3 = matrix->r1c1 * matrix->r1c3 + matrix->r1c2 * matrix->r2c3 + matrix->r1c3 * matrix->r3c3; + const float r1r2 = matrix->r1c1 * matrix->r2c1 + matrix->r1c2 * matrix->r2c2 + matrix->r1c3 * matrix->r2c3; + const float r1r3 = matrix->r1c1 * matrix->r3c1 + matrix->r1c2 * matrix->r3c2 + matrix->r1c3 * matrix->r3c3; + const float r2r3 = matrix->r2c1 * matrix->r3c1 + matrix->r2c2 * matrix->r3c2 + matrix->r2c3 * matrix->r3c3; - product.r2c1 = matrix->r2c1 * matrix->r1c1 + matrix->r2c2 * matrix->r2c1 + matrix->r2c3 * matrix->r3c1; - product.r2c2 = matrix->r2c1 * matrix->r1c2 + matrix->r2c2 * matrix->r2c2 + matrix->r2c3 * matrix->r3c2; - product.r2c3 = matrix->r2c1 * matrix->r1c3 + matrix->r2c2 * matrix->r2c3 + matrix->r2c3 * matrix->r3c3; - - product.r3c1 = matrix->r3c1 * matrix->r1c1 + matrix->r3c2 * matrix->r2c1 + matrix->r3c3 * matrix->r3c1; - product.r3c2 = matrix->r3c1 * matrix->r1c2 + matrix->r3c2 * matrix->r2c2 + matrix->r3c3 * matrix->r3c2; - product.r3c3 = matrix->r3c1 * matrix->r1c3 + matrix->r3c2 * matrix->r2c3 + matrix->r3c3 * matrix->r3c3; - - return bgc_fp32_matrix3x3_is_identity(&product); + return bgc_fp32_is_square_unit(r1r1) + && bgc_fp32_is_square_unit(r2r2) + && bgc_fp32_is_square_unit(r3r3) + && bgc_fp32_is_zero(r1r2) + && bgc_fp32_is_zero(r1r3) + && bgc_fp32_is_zero(r2r3); } inline int bgc_fp64_matrix3x3_is_rotation(const BGC_FP64_Matrix3x3* const matrix) { - BGC_FP64_Matrix3x3 product; + const double r1r1 = matrix->r1c1 * matrix->r1c1 + matrix->r1c2 * matrix->r1c2 + matrix->r1c3 * matrix->r1c3; + const double r2r2 = matrix->r2c1 * matrix->r2c1 + matrix->r2c2 * matrix->r2c2 + matrix->r2c3 * matrix->r2c3; + const double r3r3 = matrix->r3c1 * matrix->r3c1 + matrix->r3c2 * matrix->r3c2 + matrix->r3c3 * matrix->r3c3; - product.r1c1 = matrix->r1c1 * matrix->r1c1 + matrix->r1c2 * matrix->r2c1 + matrix->r1c3 * matrix->r3c1; - product.r1c2 = matrix->r1c1 * matrix->r1c2 + matrix->r1c2 * matrix->r2c2 + matrix->r1c3 * matrix->r3c2; - product.r1c3 = matrix->r1c1 * matrix->r1c3 + matrix->r1c2 * matrix->r2c3 + matrix->r1c3 * matrix->r3c3; + const double r1r2 = matrix->r1c1 * matrix->r2c1 + matrix->r1c2 * matrix->r2c2 + matrix->r1c3 * matrix->r2c3; + const double r1r3 = matrix->r1c1 * matrix->r3c1 + matrix->r1c2 * matrix->r3c2 + matrix->r1c3 * matrix->r3c3; + const double r2r3 = matrix->r2c1 * matrix->r3c1 + matrix->r2c2 * matrix->r3c2 + matrix->r2c3 * matrix->r3c3; - product.r2c1 = matrix->r2c1 * matrix->r1c1 + matrix->r2c2 * matrix->r2c1 + matrix->r2c3 * matrix->r3c1; - product.r2c2 = matrix->r2c1 * matrix->r1c2 + matrix->r2c2 * matrix->r2c2 + matrix->r2c3 * matrix->r3c2; - product.r2c3 = matrix->r2c1 * matrix->r1c3 + matrix->r2c2 * matrix->r2c3 + matrix->r2c3 * matrix->r3c3; - - product.r3c1 = matrix->r3c1 * matrix->r1c1 + matrix->r3c2 * matrix->r2c1 + matrix->r3c3 * matrix->r3c1; - product.r3c2 = matrix->r3c1 * matrix->r1c2 + matrix->r3c2 * matrix->r2c2 + matrix->r3c3 * matrix->r3c2; - product.r3c3 = matrix->r3c1 * matrix->r1c3 + matrix->r3c2 * matrix->r2c3 + matrix->r3c3 * matrix->r3c3; - - return bgc_fp64_matrix3x3_is_identity(&product); + return bgc_fp64_is_square_unit(r1r1) + && bgc_fp64_is_square_unit(r2r2) + && bgc_fp64_is_square_unit(r3r3) + && bgc_fp64_is_zero(r1r2) + && bgc_fp64_is_zero(r1r3) + && bgc_fp64_is_zero(r2r3); } // ================ Get Inverse ================= // diff --git a/basic-geometry/quaternion.c b/basic-geometry/quaternion.c index d9daa62..6dd2c3a 100644 --- a/basic-geometry/quaternion.c +++ b/basic-geometry/quaternion.c @@ -121,18 +121,6 @@ extern inline int bgc_fp64_quaternion_turn_vector(BGC_FP64_Vector3* const turned extern inline int bgc_fp32_quaternion_turn_vector_back(BGC_FP32_Vector3* const turned_vector, const BGC_FP32_Quaternion* const quaternion, const BGC_FP32_Vector3* const original_vector); extern inline int bgc_fp64_quaternion_turn_vector_back(BGC_FP64_Vector3* const turned_vector, const BGC_FP64_Quaternion* const quaternion, const BGC_FP64_Vector3* const original_vector); -extern inline void _bgc_fp32_versor_get_rotation_matrix(BGC_FP32_Matrix3x3* const matrix, const BGC_FP32_Quaternion* const versor); -extern inline void _bgc_fp64_versor_get_rotation_matrix(BGC_FP64_Matrix3x3* const matrix, const BGC_FP64_Quaternion* const versor); - -extern inline void _bgc_fp32_versor_get_reverse_matrix(BGC_FP32_Matrix3x3* const matrix, const BGC_FP32_Quaternion* const versor); -extern inline void _bgc_fp64_versor_get_reverse_matrix(BGC_FP64_Matrix3x3* const matrix, const BGC_FP64_Quaternion* const versor); - -extern inline int bgc_fp32_quaternion_get_rotation_matrix(BGC_FP32_Matrix3x3* const rotation, const BGC_FP32_Quaternion* const quaternion); -extern inline int bgc_fp64_quaternion_get_rotation_matrix(BGC_FP64_Matrix3x3* const rotation, const BGC_FP64_Quaternion* const quaternion); - -extern inline int bgc_fp32_quaternion_get_reverse_matrix(BGC_FP32_Matrix3x3* const reverse, const BGC_FP32_Quaternion* const quaternion); -extern inline int bgc_fp64_quaternion_get_reverse_matrix(BGC_FP64_Matrix3x3* const reverse, const BGC_FP64_Quaternion* const quaternion); - extern inline int bgc_fp32_quaternion_get_both_matrices(BGC_FP32_Matrix3x3* const rotation, BGC_FP32_Matrix3x3* const reverse, const BGC_FP32_Quaternion* const quaternion); extern inline int bgc_fp64_quaternion_get_both_matrices(BGC_FP64_Matrix3x3* const rotation, BGC_FP64_Matrix3x3* const reverse, const BGC_FP64_Quaternion* const quaternion); @@ -222,3 +210,341 @@ int bgc_fp64_quaternion_get_power(BGC_FP64_Quaternion* const power, const BGC_FP return BGC_SUCCESS; } + +// ============ Get Rotation Matrix ============= // + +int bgc_fp32_quaternion_get_rotation_matrix(BGC_FP32_Matrix3x3* const rotation, const BGC_FP32_Quaternion* const quaternion) +{ + const float ss = quaternion->s * quaternion->s; + const float xx = quaternion->x * quaternion->x; + const float yy = quaternion->y * quaternion->y; + const float zz = quaternion->z * quaternion->z; + + const float square_modulus = (ss + xx) + (yy + zz); + + if (square_modulus <= BGC_FP32_SQUARE_EPSILON || isnan(square_modulus)) + { + bgc_fp32_matrix3x3_make_identity(rotation); + return BGC_FAILURE; + } + + const float corrector1 = 1.0f / square_modulus; + + const float sx = quaternion->s * quaternion->x; + const float sy = quaternion->s * quaternion->y; + const float sz = quaternion->s * quaternion->z; + const float xy = quaternion->x * quaternion->y; + const float xz = quaternion->x * quaternion->z; + const float yz = quaternion->y * quaternion->z; + + const float corrector2 = 2.0f * corrector1; + + rotation->r1c1 = corrector1 * ((ss + xx) - (yy + zz)); + rotation->r2c2 = corrector1 * ((ss + yy) - (xx + zz)); + rotation->r3c3 = corrector1 * ((ss + zz) - (xx + yy)); + + rotation->r1c2 = corrector2 * (xy - sz); + rotation->r2c3 = corrector2 * (yz - sx); + rotation->r3c1 = corrector2 * (xz - sy); + + rotation->r2c1 = corrector2 * (xy + sz); + rotation->r3c2 = corrector2 * (yz + sx); + rotation->r1c3 = corrector2 * (xz + sy); + + return BGC_SUCCESS; +} + +int bgc_fp64_quaternion_get_rotation_matrix(BGC_FP64_Matrix3x3* const rotation, const BGC_FP64_Quaternion* const quaternion) +{ + const double ss = quaternion->s * quaternion->s; + const double xx = quaternion->x * quaternion->x; + const double yy = quaternion->y * quaternion->y; + const double zz = quaternion->z * quaternion->z; + + const double square_modulus = (ss + xx) + (yy + zz); + + if (square_modulus <= BGC_FP64_SQUARE_EPSILON || isnan(square_modulus)) + { + bgc_fp64_matrix3x3_make_identity(rotation); + return BGC_FAILURE; + } + + const double corrector1 = 1.0 / square_modulus; + + const double sx = quaternion->s * quaternion->x; + const double sy = quaternion->s * quaternion->y; + const double sz = quaternion->s * quaternion->z; + const double xy = quaternion->x * quaternion->y; + const double xz = quaternion->x * quaternion->z; + const double yz = quaternion->y * quaternion->z; + + const double corrector2 = 2.0 * corrector1; + + rotation->r1c1 = corrector1 * ((ss + xx) - (yy + zz)); + rotation->r2c2 = corrector1 * ((ss + yy) - (xx + zz)); + rotation->r3c3 = corrector1 * ((ss + zz) - (xx + yy)); + + rotation->r1c2 = corrector2 * (xy - sz); + rotation->r2c3 = corrector2 * (yz - sx); + rotation->r3c1 = corrector2 * (xz - sy); + + rotation->r2c1 = corrector2 * (xy + sz); + rotation->r3c2 = corrector2 * (yz + sx); + rotation->r1c3 = corrector2 * (xz + sy); + + return BGC_SUCCESS; +} + +// ============ Set Rotation Matrix ============= // + +int bgc_fp32_quaternion_set_rotation_matrix(BGC_FP32_Quaternion* const quaternion, const BGC_FP32_Matrix3x3* const matrix) +{ + if (!bgc_fp32_matrix3x3_is_rotation(matrix)) { + return BGC_FAILURE; + } + + const float ss_4 = (1 + matrix->r1c1) + (matrix->r2c2 + matrix->r3c3); + const float xx_4 = (1 + matrix->r1c1) - (matrix->r2c2 + matrix->r3c3); + const float yy_4 = (1 + matrix->r2c2) - (matrix->r1c1 + matrix->r3c3); + const float zz_4 = (1 + matrix->r3c3) - (matrix->r1c1 + matrix->r2c2); + + const float sx_4 = matrix->r3c2 - matrix->r2c3; + const float sy_4 = matrix->r1c3 - matrix->r3c1; + const float sz_4 = matrix->r2c1 - matrix->r1c2; + + const float yz_4 = matrix->r3c2 + matrix->r2c3; + const float xz_4 = matrix->r1c3 + matrix->r3c1; + const float xy_4 = matrix->r2c1 + matrix->r1c2; + + float max = ss_4; + int index = 0; + + if (xx_4 > max) { + max = xx_4; + index = 1; + } + + if (yy_4 > max) { + max = yy_4; + index = 2; + } + + if (zz_4 > max) { + max = zz_4; + index = 3; + } + + switch (index) { + case 0: + quaternion->s = ss_4; + quaternion->x = sx_4; + quaternion->y = sy_4; + quaternion->z = sz_4; + break; + + case 1: + quaternion->s = sx_4; + quaternion->x = xx_4; + quaternion->y = xy_4; + quaternion->z = xz_4; + break; + + case 2: + quaternion->s = sy_4; + quaternion->x = xy_4; + quaternion->y = yy_4; + quaternion->z = yz_4; + break; + + case 3: + quaternion->s = sz_4; + quaternion->x = xz_4; + quaternion->y = yz_4; + quaternion->z = zz_4; + break; + } + + if (quaternion->s < 0.0f) { + quaternion->s = -quaternion->s; + quaternion->x = -quaternion->x; + quaternion->y = -quaternion->y; + quaternion->z = -quaternion->z; + } + + const float multiplicator = sqrtf(1.0f / bgc_fp32_quaternion_get_square_magnitude(quaternion)); + + quaternion->s *= multiplicator; + quaternion->x *= multiplicator; + quaternion->y *= multiplicator; + quaternion->z *= multiplicator; + + return BGC_SUCCESS; +} + +int bgc_fp64_quaternion_set_rotation_matrix(BGC_FP64_Quaternion* const quaternion, const BGC_FP64_Matrix3x3* const matrix) +{ + if (!bgc_fp64_matrix3x3_is_rotation(matrix)) { + return BGC_FAILURE; + } + + const double ss_4 = (1 + matrix->r1c1) + (matrix->r2c2 + matrix->r3c3); + const double xx_4 = (1 + matrix->r1c1) - (matrix->r2c2 - matrix->r3c3); + const double yy_4 = (1 + matrix->r2c2) - (matrix->r1c1 - matrix->r3c3); + const double zz_4 = (1 + matrix->r3c3) - (matrix->r1c1 - matrix->r2c2); + + const double sx_4 = matrix->r3c2 - matrix->r2c3; + const double sy_4 = matrix->r1c3 - matrix->r3c1; + const double sz_4 = matrix->r2c1 - matrix->r1c2; + + const double yz_4 = matrix->r3c2 + matrix->r2c3; + const double xz_4 = matrix->r1c3 + matrix->r3c1; + const double xy_4 = matrix->r2c1 + matrix->r1c2; + + double max = ss_4; + int index = 0; + + if (xx_4 > max) { + max = xx_4; + index = 1; + } + + if (yy_4 > max) { + max = yy_4; + index = 2; + } + + if (zz_4 > max) { + max = zz_4; + index = 3; + } + + switch (index) { + case 0: + quaternion->s = ss_4; + quaternion->x = sx_4; + quaternion->y = sy_4; + quaternion->z = sz_4; + break; + + case 1: + quaternion->s = sx_4; + quaternion->x = xx_4; + quaternion->y = xy_4; + quaternion->z = xz_4; + break; + + case 2: + quaternion->s = sy_4; + quaternion->x = xy_4; + quaternion->y = yy_4; + quaternion->z = yz_4; + break; + + case 3: + quaternion->s = sz_4; + quaternion->x = xz_4; + quaternion->y = yz_4; + quaternion->z = zz_4; + break; + } + + if (quaternion->s < 0.0) { + quaternion->s = -quaternion->s; + quaternion->x = -quaternion->x; + quaternion->y = -quaternion->y; + quaternion->z = -quaternion->z; + } + + const double multiplicator = sqrt(1.0 / bgc_fp64_quaternion_get_square_magnitude(quaternion)); + + quaternion->s *= multiplicator; + quaternion->x *= multiplicator; + quaternion->y *= multiplicator; + quaternion->z *= multiplicator; + + return BGC_SUCCESS; +} + +// ============= Get Reverse Matrix ============= // + +int bgc_fp32_quaternion_get_reverse_matrix(BGC_FP32_Matrix3x3* const reverse, const BGC_FP32_Quaternion* const quaternion) +{ + const float ss = quaternion->s * quaternion->s; + const float xx = quaternion->x * quaternion->x; + const float yy = quaternion->y * quaternion->y; + const float zz = quaternion->z * quaternion->z; + + const float square_modulus = (ss + xx) + (yy + zz); + + if (square_modulus <= BGC_FP32_SQUARE_EPSILON || isnan(square_modulus)) + { + bgc_fp32_matrix3x3_make_identity(reverse); + return BGC_FAILURE; + } + + const float corrector1 = 1.0f / square_modulus; + + const float sx = quaternion->s * quaternion->x; + const float sy = quaternion->s * quaternion->y; + const float sz = quaternion->s * quaternion->z; + const float xy = quaternion->x * quaternion->y; + const float xz = quaternion->x * quaternion->z; + const float yz = quaternion->y * quaternion->z; + + const float corrector2 = 2.0f * corrector1; + + reverse->r1c1 = corrector1 * ((ss + xx) - (yy + zz)); + reverse->r2c2 = corrector1 * ((ss + yy) - (xx + zz)); + reverse->r3c3 = corrector1 * ((ss + zz) - (xx + yy)); + + reverse->r1c2 = corrector2 * (xy + sz); + reverse->r2c3 = corrector2 * (yz + sx); + reverse->r3c1 = corrector2 * (xz + sy); + + reverse->r2c1 = corrector2 * (xy - sz); + reverse->r3c2 = corrector2 * (yz - sx); + reverse->r1c3 = corrector2 * (xz - sy); + + return BGC_SUCCESS; +} + +int bgc_fp64_quaternion_get_reverse_matrix(BGC_FP64_Matrix3x3* const reverse, const BGC_FP64_Quaternion* const quaternion) +{ + const double ss = quaternion->s * quaternion->s; + const double xx = quaternion->x * quaternion->x; + const double yy = quaternion->y * quaternion->y; + const double zz = quaternion->z * quaternion->z; + + const double square_modulus = (ss + xx) + (yy + zz); + + if (square_modulus <= BGC_FP64_SQUARE_EPSILON || isnan(square_modulus)) + { + bgc_fp64_matrix3x3_make_identity(reverse); + return BGC_FAILURE; + } + + const double corrector1 = 1.0 / square_modulus; + + const double sx = quaternion->s * quaternion->x; + const double sy = quaternion->s * quaternion->y; + const double sz = quaternion->s * quaternion->z; + const double xy = quaternion->x * quaternion->y; + const double xz = quaternion->x * quaternion->z; + const double yz = quaternion->y * quaternion->z; + + const double corrector2 = 2.0 * corrector1; + + reverse->r1c1 = corrector1 * ((ss + xx) - (yy + zz)); + reverse->r2c2 = corrector1 * ((ss + yy) - (xx + zz)); + reverse->r3c3 = corrector1 * ((ss + zz) - (xx + yy)); + + reverse->r1c2 = corrector2 * (xy + sz); + reverse->r2c3 = corrector2 * (yz + sx); + reverse->r3c1 = corrector2 * (xz + sy); + + reverse->r2c1 = corrector2 * (xy - sz); + reverse->r3c2 = corrector2 * (yz - sx); + reverse->r1c3 = corrector2 * (xz - sy); + + return BGC_SUCCESS; +} diff --git a/basic-geometry/quaternion.h b/basic-geometry/quaternion.h index eeaf1e2..2928b47 100644 --- a/basic-geometry/quaternion.h +++ b/basic-geometry/quaternion.h @@ -968,293 +968,20 @@ inline int bgc_fp64_quaternion_turn_vector_back(BGC_FP64_Vector3* const turned_v return BGC_SUCCESS; } -// ========= Get Versor Rotation Matrix ========= // - -inline void _bgc_fp32_versor_get_rotation_matrix(BGC_FP32_Matrix3x3* const matrix, const BGC_FP32_Quaternion* const versor) -{ - const float ss = versor->s * versor->s; - const float xx = versor->x * versor->x; - const float yy = versor->y * versor->y; - const float zz = versor->z * versor->z; - - const float sx = versor->s * versor->x; - const float sy = versor->s * versor->y; - const float sz = versor->s * versor->z; - - const float xy = versor->x * versor->y; - const float xz = versor->x * versor->z; - - const float yz = versor->y * versor->z; - - matrix->r1c1 = ((ss + xx) - (yy + zz)); - matrix->r2c2 = ((ss + yy) - (xx + zz)); - matrix->r3c3 = ((ss + zz) - (xx + yy)); - - matrix->r1c2 = 2.0f * (xy - sz); - matrix->r2c3 = 2.0f * (yz - sx); - matrix->r3c1 = 2.0f * (xz - sy); - - matrix->r2c1 = 2.0f * (xy + sz); - matrix->r3c2 = 2.0f * (yz + sx); - matrix->r1c3 = 2.0f * (xz + sy); -} - -inline void _bgc_fp64_versor_get_rotation_matrix(BGC_FP64_Matrix3x3* const matrix, const BGC_FP64_Quaternion* const versor) -{ - const double ss = versor->s * versor->s; - const double xx = versor->x * versor->x; - const double yy = versor->y * versor->y; - const double zz = versor->z * versor->z; - - const double sx = versor->s * versor->x; - const double sy = versor->s * versor->y; - const double sz = versor->s * versor->z; - - const double xy = versor->x * versor->y; - const double xz = versor->x * versor->z; - - const double yz = versor->y * versor->z; - - matrix->r1c1 = ((ss + xx) - (yy + zz)); - matrix->r2c2 = ((ss + yy) - (xx + zz)); - matrix->r3c3 = ((ss + zz) - (xx + yy)); - - matrix->r1c2 = 2.0 * (xy - sz); - matrix->r2c3 = 2.0 * (yz - sx); - matrix->r3c1 = 2.0 * (xz - sy); - - matrix->r2c1 = 2.0 * (xy + sz); - matrix->r3c2 = 2.0 * (yz + sx); - matrix->r1c3 = 2.0 * (xz + sy); -} - -// ========= Get Versor Reverse Matrix ========== // - -inline void _bgc_fp32_versor_get_reverse_matrix(BGC_FP32_Matrix3x3* const matrix, const BGC_FP32_Quaternion* const versor) -{ - const float ss = versor->s * versor->s; - const float xx = versor->x * versor->x; - const float yy = versor->y * versor->y; - const float zz = versor->z * versor->z; - - const float sx = versor->s * versor->x; - const float sy = versor->s * versor->y; - const float sz = versor->s * versor->z; - - const float xy = versor->x * versor->y; - const float xz = versor->x * versor->z; - - const float yz = versor->y * versor->z; - - matrix->r1c1 = ((ss + xx) - (yy + zz)); - matrix->r2c2 = ((ss + yy) - (xx + zz)); - matrix->r3c3 = ((ss + zz) - (xx + yy)); - - matrix->r1c2 = 2.0f * (xy + sz); - matrix->r2c3 = 2.0f * (yz + sx); - matrix->r3c1 = 2.0f * (xz + sy); - - matrix->r2c1 = 2.0f * (xy - sz); - matrix->r3c2 = 2.0f * (yz - sx); - matrix->r1c3 = 2.0f * (xz - sy); -} - -inline void _bgc_fp64_versor_get_reverse_matrix(BGC_FP64_Matrix3x3* const matrix, const BGC_FP64_Quaternion* const versor) -{ - const double ss = versor->s * versor->s; - const double xx = versor->x * versor->x; - const double yy = versor->y * versor->y; - const double zz = versor->z * versor->z; - - const double sx = versor->s * versor->x; - const double sy = versor->s * versor->y; - const double sz = versor->s * versor->z; - - const double xy = versor->x * versor->y; - const double xz = versor->x * versor->z; - - const double yz = versor->y * versor->z; - - matrix->r1c1 = ((ss + xx) - (yy + zz)); - matrix->r2c2 = ((ss + yy) - (xx + zz)); - matrix->r3c3 = ((ss + zz) - (xx + yy)); - - matrix->r1c2 = 2.0 * (xy + sz); - matrix->r2c3 = 2.0 * (yz + sx); - matrix->r3c1 = 2.0 * (xz + sy); - - matrix->r2c1 = 2.0 * (xy - sz); - matrix->r3c2 = 2.0 * (yz - sx); - matrix->r1c3 = 2.0 * (xz - sy); -} - // ============ Get Rotation Matrix ============= // -inline int bgc_fp32_quaternion_get_rotation_matrix(BGC_FP32_Matrix3x3* const rotation, const BGC_FP32_Quaternion* const quaternion) -{ - const float ss = quaternion->s * quaternion->s; - const float xx = quaternion->x * quaternion->x; - const float yy = quaternion->y * quaternion->y; - const float zz = quaternion->z * quaternion->z; +int bgc_fp32_quaternion_get_rotation_matrix(BGC_FP32_Matrix3x3* const rotation, const BGC_FP32_Quaternion* const quaternion); +int bgc_fp64_quaternion_get_rotation_matrix(BGC_FP64_Matrix3x3* const rotation, const BGC_FP64_Quaternion* const quaternion); - const float square_modulus = (ss + xx) + (yy + zz); +// ============ Set Rotation Matrix ============= // - if (square_modulus <= BGC_FP32_SQUARE_EPSILON || isnan(square_modulus)) - { - bgc_fp32_matrix3x3_make_identity(rotation); - return BGC_FAILURE; - } - - const float corrector1 = 1.0f / square_modulus; - - const float sx = quaternion->s * quaternion->x; - const float sy = quaternion->s * quaternion->y; - const float sz = quaternion->s * quaternion->z; - const float xy = quaternion->x * quaternion->y; - const float xz = quaternion->x * quaternion->z; - const float yz = quaternion->y * quaternion->z; - - const float corrector2 = 2.0f * corrector1; - - rotation->r1c1 = corrector1 * ((ss + xx) - (yy + zz)); - rotation->r2c2 = corrector1 * ((ss + yy) - (xx + zz)); - rotation->r3c3 = corrector1 * ((ss + zz) - (xx + yy)); - - rotation->r1c2 = corrector2 * (xy - sz); - rotation->r2c3 = corrector2 * (yz - sx); - rotation->r3c1 = corrector2 * (xz - sy); - - rotation->r2c1 = corrector2 * (xy + sz); - rotation->r3c2 = corrector2 * (yz + sx); - rotation->r1c3 = corrector2 * (xz + sy); - - return BGC_SUCCESS; -} - -inline int bgc_fp64_quaternion_get_rotation_matrix(BGC_FP64_Matrix3x3* const rotation, const BGC_FP64_Quaternion* const quaternion) -{ - const double ss = quaternion->s * quaternion->s; - const double xx = quaternion->x * quaternion->x; - const double yy = quaternion->y * quaternion->y; - const double zz = quaternion->z * quaternion->z; - - const double square_modulus = (ss + xx) + (yy + zz); - - if (square_modulus <= BGC_FP64_SQUARE_EPSILON || isnan(square_modulus)) - { - bgc_fp64_matrix3x3_make_identity(rotation); - return BGC_FAILURE; - } - - const double corrector1 = 1.0f / square_modulus; - - const double sx = quaternion->s * quaternion->x; - const double sy = quaternion->s * quaternion->y; - const double sz = quaternion->s * quaternion->z; - const double xy = quaternion->x * quaternion->y; - const double xz = quaternion->x * quaternion->z; - const double yz = quaternion->y * quaternion->z; - - const double corrector2 = 2.0f * corrector1; - - rotation->r1c1 = corrector1 * ((ss + xx) - (yy + zz)); - rotation->r2c2 = corrector1 * ((ss + yy) - (xx + zz)); - rotation->r3c3 = corrector1 * ((ss + zz) - (xx + yy)); - - rotation->r1c2 = corrector2 * (xy - sz); - rotation->r2c3 = corrector2 * (yz - sx); - rotation->r3c1 = corrector2 * (xz - sy); - - rotation->r2c1 = corrector2 * (xy + sz); - rotation->r3c2 = corrector2 * (yz + sx); - rotation->r1c3 = corrector2 * (xz + sy); - - return BGC_SUCCESS; -} +int bgc_fp32_quaternion_set_rotation_matrix(BGC_FP32_Quaternion* const quaternion, const BGC_FP32_Matrix3x3* const matrix); +int bgc_fp64_quaternion_set_rotation_matrix(BGC_FP64_Quaternion* const quaternion, const BGC_FP64_Matrix3x3* const matrix); // ============= Get Reverse Matrix ============= // -inline int bgc_fp32_quaternion_get_reverse_matrix(BGC_FP32_Matrix3x3* const reverse, const BGC_FP32_Quaternion* const quaternion) -{ - const float ss = quaternion->s * quaternion->s; - const float xx = quaternion->x * quaternion->x; - const float yy = quaternion->y * quaternion->y; - const float zz = quaternion->z * quaternion->z; - - const float square_modulus = (ss + xx) + (yy + zz); - - if (square_modulus <= BGC_FP32_SQUARE_EPSILON || isnan(square_modulus)) - { - bgc_fp32_matrix3x3_make_identity(reverse); - return BGC_FAILURE; - } - - const float corrector1 = 1.0f / square_modulus; - - const float sx = quaternion->s * quaternion->x; - const float sy = quaternion->s * quaternion->y; - const float sz = quaternion->s * quaternion->z; - const float xy = quaternion->x * quaternion->y; - const float xz = quaternion->x * quaternion->z; - const float yz = quaternion->y * quaternion->z; - - const float corrector2 = 2.0f * corrector1; - - reverse->r1c1 = corrector1 * ((ss + xx) - (yy + zz)); - reverse->r2c2 = corrector1 * ((ss + yy) - (xx + zz)); - reverse->r3c3 = corrector1 * ((ss + zz) - (xx + yy)); - - reverse->r1c2 = corrector2 * (xy + sz); - reverse->r2c3 = corrector2 * (yz + sx); - reverse->r3c1 = corrector2 * (xz + sy); - - reverse->r2c1 = corrector2 * (xy - sz); - reverse->r3c2 = corrector2 * (yz - sx); - reverse->r1c3 = corrector2 * (xz - sy); - - return BGC_SUCCESS; -} - -inline int bgc_fp64_quaternion_get_reverse_matrix(BGC_FP64_Matrix3x3* const reverse, const BGC_FP64_Quaternion* const quaternion) -{ - const double ss = quaternion->s * quaternion->s; - const double xx = quaternion->x * quaternion->x; - const double yy = quaternion->y * quaternion->y; - const double zz = quaternion->z * quaternion->z; - - const double square_modulus = (ss + xx) + (yy + zz); - - if (square_modulus <= BGC_FP64_SQUARE_EPSILON || isnan(square_modulus)) - { - bgc_fp64_matrix3x3_make_identity(reverse); - return BGC_FAILURE; - } - - const double corrector1 = 1.0f / square_modulus; - - const double sx = quaternion->s * quaternion->x; - const double sy = quaternion->s * quaternion->y; - const double sz = quaternion->s * quaternion->z; - const double xy = quaternion->x * quaternion->y; - const double xz = quaternion->x * quaternion->z; - const double yz = quaternion->y * quaternion->z; - - const double corrector2 = 2.0f * corrector1; - - reverse->r1c1 = corrector1 * ((ss + xx) - (yy + zz)); - reverse->r2c2 = corrector1 * ((ss + yy) - (xx + zz)); - reverse->r3c3 = corrector1 * ((ss + zz) - (xx + yy)); - - reverse->r1c2 = corrector2 * (xy + sz); - reverse->r2c3 = corrector2 * (yz + sx); - reverse->r3c1 = corrector2 * (xz + sy); - - reverse->r2c1 = corrector2 * (xy - sz); - reverse->r3c2 = corrector2 * (yz - sx); - reverse->r1c3 = corrector2 * (xz - sy); - - return BGC_SUCCESS; -} +int bgc_fp32_quaternion_get_reverse_matrix(BGC_FP32_Matrix3x3* const reverse, const BGC_FP32_Quaternion* const quaternion); +int bgc_fp64_quaternion_get_reverse_matrix(BGC_FP64_Matrix3x3* const reverse, const BGC_FP64_Quaternion* const quaternion); // ============= Get Both Matrixes ============== // diff --git a/basic-geometry/rigid-pose3.h b/basic-geometry/rigid-pose3.h index a7cb296..7486eaf 100644 --- a/basic-geometry/rigid-pose3.h +++ b/basic-geometry/rigid-pose3.h @@ -324,24 +324,24 @@ inline void bgc_fp64_rigid_pose3_exclude(BGC_FP64_RigidPose3* const difference, inline void bgc_fp32_rigid_pose3_get_matrix(BGC_FP32_Matrix3x3* const matrix, const BGC_FP32_RigidPose3* const pose) { - _bgc_fp32_versor_get_rotation_matrix(matrix, &pose->_versor.real_part); + bgc_fp32_quaternion_get_rotation_matrix(matrix, &pose->_versor.real_part); } inline void bgc_fp64_rigid_pose3_get_matrix(BGC_FP64_Matrix3x3* const matrix, const BGC_FP64_RigidPose3* const pose) { - _bgc_fp64_versor_get_rotation_matrix(matrix, &pose->_versor.real_part); + bgc_fp64_quaternion_get_rotation_matrix(matrix, &pose->_versor.real_part); } // ============= Get Reverse Matrix ============= // inline void bgc_fp32_rigid_pose3_get_reverse_matrix(BGC_FP32_Matrix3x3* const matrix, const BGC_FP32_RigidPose3* const pose) { - _bgc_fp32_versor_get_reverse_matrix(matrix, &pose->_versor.real_part); + bgc_fp32_quaternion_get_reverse_matrix(matrix, &pose->_versor.real_part); } inline void bgc_fp64_rigid_pose3_get_reverse_matrix(BGC_FP64_Matrix3x3* const matrix, const BGC_FP64_RigidPose3* const pose) { - _bgc_fp64_versor_get_reverse_matrix(matrix, &pose->_versor.real_part); + bgc_fp64_quaternion_get_reverse_matrix(matrix, &pose->_versor.real_part); } // ================= Get Shift ================== // @@ -392,13 +392,13 @@ inline void bgc_fp64_rigid_pose3_get_reverse_shift(BGC_FP64_Vector3* const shift inline void bgc_fp32_rigid_pose3_get_affine(BGC_FP32_Affine3* const affine_map, const BGC_FP32_RigidPose3* const pose) { - _bgc_fp32_versor_get_rotation_matrix(&affine_map->distortion, &pose->_versor.real_part); + bgc_fp32_quaternion_get_rotation_matrix(&affine_map->distortion, &pose->_versor.real_part); bgc_fp32_rigid_pose3_get_shift(&affine_map->shift, pose); } inline void bgc_fp64_rigid_pose3_get_affine(BGC_FP64_Affine3* const affine_map, const BGC_FP64_RigidPose3* const pose) { - _bgc_fp64_versor_get_rotation_matrix(&affine_map->distortion, &pose->_versor.real_part); + bgc_fp64_quaternion_get_rotation_matrix(&affine_map->distortion, &pose->_versor.real_part); bgc_fp64_rigid_pose3_get_shift(&affine_map->shift, pose); } @@ -406,13 +406,13 @@ inline void bgc_fp64_rigid_pose3_get_affine(BGC_FP64_Affine3* const affine_map, inline void bgc_fp32_rigid_pose3_get_reverse_affine(BGC_FP32_Affine3* const affine_map, const BGC_FP32_RigidPose3* const pose) { - _bgc_fp32_versor_get_reverse_matrix(&affine_map->distortion, &pose->_versor.real_part); + bgc_fp32_quaternion_get_reverse_matrix(&affine_map->distortion, &pose->_versor.real_part); bgc_fp32_rigid_pose3_get_reverse_shift(&affine_map->shift, pose); } inline void bgc_fp64_rigid_pose3_get_reverse_affine(BGC_FP64_Affine3* const affine_map, const BGC_FP64_RigidPose3* const pose) { - _bgc_fp64_versor_get_reverse_matrix(&affine_map->distortion, &pose->_versor.real_part); + bgc_fp64_quaternion_get_reverse_matrix(&affine_map->distortion, &pose->_versor.real_part); bgc_fp64_rigid_pose3_get_reverse_shift(&affine_map->shift, pose); } diff --git a/basic-geometry/turn3.h b/basic-geometry/turn3.h index fb8d0ef..d8c0599 100644 --- a/basic-geometry/turn3.h +++ b/basic-geometry/turn3.h @@ -385,37 +385,37 @@ void bgc_fp64_turn3_spherically_interpolate(BGC_FP64_Turn3* const interpolation, inline void bgc_fp32_turn3_get_rotation_matrix(BGC_FP32_Matrix3x3* const matrix, const BGC_FP32_Turn3* const turn) { - _bgc_fp32_versor_get_rotation_matrix(matrix, &turn->_versor); + bgc_fp32_quaternion_get_rotation_matrix(matrix, &turn->_versor); } inline void bgc_fp64_turn3_get_rotation_matrix(BGC_FP64_Matrix3x3* const matrix, const BGC_FP64_Turn3* const turn) { - _bgc_fp64_versor_get_rotation_matrix(matrix, &turn->_versor); + bgc_fp64_quaternion_get_rotation_matrix(matrix, &turn->_versor); } // ============= Get Reverse Matrix ============= // inline void bgc_fp32_turn3_get_reverse_matrix(BGC_FP32_Matrix3x3* const matrix, const BGC_FP32_Turn3* const turn) { - _bgc_fp32_versor_get_reverse_matrix(matrix, &turn->_versor); + bgc_fp32_quaternion_get_reverse_matrix(matrix, &turn->_versor); } inline void bgc_fp64_turn3_get_reverse_matrix(BGC_FP64_Matrix3x3* const matrix, const BGC_FP64_Turn3* const turn) { - _bgc_fp64_versor_get_reverse_matrix(matrix, &turn->_versor); + bgc_fp64_quaternion_get_reverse_matrix(matrix, &turn->_versor); } // ============= Get Both Matrixes ============== // inline void bgc_fp32_turn3_get_both_matrices(BGC_FP32_Matrix3x3* const rotation, BGC_FP32_Matrix3x3* const reverse, const BGC_FP32_Turn3* const turn) { - _bgc_fp32_versor_get_reverse_matrix(reverse, &turn->_versor); + bgc_fp32_quaternion_get_reverse_matrix(reverse, &turn->_versor); bgc_fp32_matrix3x3_get_transposed(rotation, reverse); } inline void bgc_fp64_turn3_get_both_matrices(BGC_FP64_Matrix3x3* const rotation, BGC_FP64_Matrix3x3* const reverse, const BGC_FP64_Turn3* const turn) { - _bgc_fp64_versor_get_reverse_matrix(reverse, &turn->_versor); + bgc_fp64_quaternion_get_reverse_matrix(reverse, &turn->_versor); bgc_fp64_matrix3x3_get_transposed(rotation, reverse); }