Уменшение количества внутренних методов за счёт методов получения матрицы поворота для веросора; исправления в методах проверки матрицы поворота; добавление методов вычисления поворота (turn3) по матрице поворота 3x3

This commit is contained in:
Andrey Pokidov 2026-04-03 02:22:11 +07:00
parent abf99a7126
commit 54c762da14
9 changed files with 448 additions and 351 deletions

View file

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