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);
}