diff --git a/basic-geometry/dual-quaternion.h b/basic-geometry/dual-quaternion.h index 28f9e7d..4d39543 100644 --- a/basic-geometry/dual-quaternion.h +++ b/basic-geometry/dual-quaternion.h @@ -98,8 +98,8 @@ inline int bgc_fp32_dual_quaternion_invert(BGC_FP32_DualQuaternion* quaternion) BGC_FP32_Quaternion temporary; - bgc_fp32_quaternion_multiply_by_quaternion(&temporary, &quaternion->real_part, &quaternion->dual_part); - bgc_fp32_quaternion_multiply_by_quaternion(&quaternion->dual_part, &temporary, &quaternion->real_part); + _bgc_fp32_restrict_quaternion_multiply_by_quaternion(&temporary, &quaternion->real_part, &quaternion->dual_part); + _bgc_fp32_restrict_quaternion_multiply_by_quaternion(&quaternion->dual_part, &temporary, &quaternion->real_part); bgc_fp32_quaternion_revert(&quaternion->dual_part); @@ -114,8 +114,8 @@ inline int bgc_fp64_dual_quaternion_invert(BGC_FP64_DualQuaternion* quaternion) BGC_FP64_Quaternion temporary; - bgc_fp64_quaternion_multiply_by_quaternion(&temporary, &quaternion->real_part, &quaternion->dual_part); - bgc_fp64_quaternion_multiply_by_quaternion(&quaternion->dual_part, &temporary, &quaternion->real_part); + _bgc_fp64_restrict_quaternion_multiply_by_quaternion(&temporary, &quaternion->real_part, &quaternion->dual_part); + _bgc_fp64_restrict_quaternion_multiply_by_quaternion(&quaternion->dual_part, &temporary, &quaternion->real_part); bgc_fp64_quaternion_revert(&quaternion->dual_part); @@ -132,8 +132,8 @@ inline int bgc_fp32_dual_quaternion_get_inverse(BGC_FP32_DualQuaternion* inverse BGC_FP32_Quaternion temporary; - bgc_fp32_quaternion_multiply_by_quaternion(&temporary, &inverse->real_part, &quaternion->dual_part); - bgc_fp32_quaternion_multiply_by_quaternion(&inverse->dual_part, &temporary, &inverse->real_part); + _bgc_fp32_restrict_quaternion_multiply_by_quaternion(&temporary, &inverse->real_part, &quaternion->dual_part); + _bgc_fp32_restrict_quaternion_multiply_by_quaternion(&inverse->dual_part, &temporary, &inverse->real_part); bgc_fp32_quaternion_revert(&inverse->dual_part); @@ -148,8 +148,8 @@ inline int bgc_fp64_dual_quaternion_get_inverse(BGC_FP64_DualQuaternion* inverse BGC_FP64_Quaternion temporary; - bgc_fp64_quaternion_multiply_by_quaternion(&temporary, &inverse->real_part, &quaternion->dual_part); - bgc_fp64_quaternion_multiply_by_quaternion(&inverse->dual_part, &temporary, &inverse->real_part); + _bgc_fp64_restrict_quaternion_multiply_by_quaternion(&temporary, &inverse->real_part, &quaternion->dual_part); + _bgc_fp64_restrict_quaternion_multiply_by_quaternion(&inverse->dual_part, &temporary, &inverse->real_part); bgc_fp64_quaternion_revert(&inverse->dual_part); @@ -258,6 +258,38 @@ inline void bgc_fp64_dual_quaternion_get_fully_conjugate(BGC_FP64_DualQuaternion conjugate->dual_part.x3 = quaternion->dual_part.x3; } +// ================= Normalize ================== // + +void _bgc_fp32_dual_quaternion_normalize_parts(BGC_FP32_DualQuaternion* quaternion, const float square_magnitude); + +void _bgc_fp64_dual_quaternion_normalize_parts(BGC_FP64_DualQuaternion* quaternion, const double square_magnitude); + +inline void bgc_fp32_dual_quaternion_normalize(BGC_FP32_DualQuaternion* quaternion) +{ + const float square_magnitude = bgc_fp32_quaternion_get_square_magnitude(&quaternion->real_part); + + if (!bgc_fp32_is_square_unit(square_magnitude)) { + _bgc_fp32_quaternion_normalize_normalize_parts(quaternion, square_magnitude); + } + + const float dot_product = bgc_fp32_quaternion_get_dot_product(&quaternion->real_part, &quaternion->dual_part); + + bgc_fp32_quaternion_subtract_scaled(&quaternion->dual_part, &quaternion->dual_part, &quaternion->real_part, dot_product); +} + +inline void bgc_fp64_dual_quaternion_normalize(BGC_FP64_DualQuaternion* quaternion) +{ + const double square_magnitude = bgc_fp64_quaternion_get_square_magnitude(&quaternion->real_part); + + if (!bgc_fp64_is_square_unit(square_magnitude)) { + _bgc_fp64_quaternion_normalize_normalize_parts(quaternion, square_magnitude); + } + + const double dot_product = bgc_fp64_quaternion_get_dot_product(&pose->_real_part, &pose->_dual_part); + + bgc_fp64_quaternion_subtract_scaled(&pose->_dual_part, &pose->_dual_part, &pose->_real_part, dot_product); +} + // ==================== Add ===================== // inline void bgc_fp32_dual_quaternion_add(BGC_FP32_DualQuaternion* sum, const BGC_FP32_DualQuaternion* first, const BGC_FP32_DualQuaternion* second) diff --git a/basic-geometry/dual-vector3.h b/basic-geometry/dual-vector3.h index 3fee97d..e4851ea 100644 --- a/basic-geometry/dual-vector3.h +++ b/basic-geometry/dual-vector3.h @@ -358,8 +358,8 @@ inline void bgc_fp32_dual_vector3_get_cross_product(BGC_FP32_DualVector3* produc { BGC_FP32_Vector3 part1, part2; - bgc_fp32_vector3_get_cross_product(&part1, &first->dual_part, &second->real_part); - bgc_fp32_vector3_get_cross_product(&part2, &first->real_part, &second->dual_part); + _bgc_fp32_restrict_vector3_get_cross_product(&part1, &first->dual_part, &second->real_part); + _bgc_fp32_restrict_vector3_get_cross_product(&part2, &first->real_part, &second->dual_part); bgc_fp32_vector3_get_cross_product(&product->real_part, &first->real_part, &second->real_part); bgc_fp32_vector3_add(&product->dual_part, &part1, &part2); @@ -369,8 +369,8 @@ inline void bgc_fp64_dual_vector3_get_cross_product(BGC_FP64_DualVector3* produc { BGC_FP64_Vector3 part1, part2; - bgc_fp64_vector3_get_cross_product(&part1, &first->dual_part, &second->real_part); - bgc_fp64_vector3_get_cross_product(&part2, &first->real_part, &second->dual_part); + _bgc_fp64_restrict_vector3_get_cross_product(&part1, &first->dual_part, &second->real_part); + _bgc_fp64_restrict_vector3_get_cross_product(&part2, &first->real_part, &second->dual_part); bgc_fp64_vector3_get_cross_product(&product->real_part, &first->real_part, &second->real_part); bgc_fp64_vector3_add(&product->dual_part, &part1, &part2); diff --git a/basic-geometry/rigid-pose3.c b/basic-geometry/rigid-pose3.c index afae546..973e847 100644 --- a/basic-geometry/rigid-pose3.c +++ b/basic-geometry/rigid-pose3.c @@ -1,5 +1,34 @@ #include "rigid-pose3.h" +void _bgc_fp32_rigid_pose3_normalize_parts(BGC_FP32_RigidPose3* pose, const float square_magnitude) +{ + if (square_magnitude <= BGC_FP32_SQUARE_EPSILON || isnan(square_magnitude)) { + bgc_fp32_rigid_pose3_reset(pose); + return; + } + + const float multiplier = sqrtf(1.0f / square_magnitude); + + bgc_fp32_quaternion_multiply_by_real(&pose->_real_part, &pose->_real_part, multiplier); + bgc_fp32_quaternion_multiply_by_real(&pose->_dual_part, &pose->_dual_part, multiplier); +} + +void _bgc_fp64_rigid_pose3_normalize_parts(BGC_FP64_RigidPose3* pose, const double square_magnitude) +{ + if (square_magnitude <= BGC_FP64_SQUARE_EPSILON || isnan(square_magnitude)) { + bgc_fp64_rigid_pose3_reset(pose); + return; + } + + const double multiplier = sqrt(1.0 / square_magnitude); + + bgc_fp64_quaternion_multiply_by_real(&pose->_real_part, &pose->_real_part, multiplier); + bgc_fp64_quaternion_multiply_by_real(&pose->_dual_part, &pose->_dual_part, multiplier); +} + +extern inline void _bgc_fp32_rigid_pose3_normalize(BGC_FP32_RigidPose3* pose); +extern inline void _bgc_fp64_rigid_pose3_normalize(BGC_FP64_RigidPose3* pose); + extern inline void bgc_fp32_rigid_pose3_reset(BGC_FP32_RigidPose3* pose); extern inline void bgc_fp64_rigid_pose3_reset(BGC_FP64_RigidPose3* pose); @@ -14,29 +43,3 @@ extern inline void bgc_fp64_rigid_pose3_convert_to_fp32(BGC_FP32_RigidPose3* des extern inline void bgc_fp32_rigid_pose3_combine(BGC_FP32_RigidPose3* combination, const BGC_FP32_RigidPose3* first, const BGC_FP32_RigidPose3* second); extern inline void bgc_fp64_rigid_pose3_combine(BGC_FP64_RigidPose3* combination, const BGC_FP64_RigidPose3* first, const BGC_FP64_RigidPose3* second); - -void _bgc_fp32_rigid_pose3_normalize(BGC_FP32_RigidPose3* pose, const float square_magnitude) -{ - if (square_magnitude <= BGC_FP32_SQUARE_EPSILON || isnan(square_magnitude)) { - bgc_fp32_rigid_pose3_reset(pose); - return; - } - - const float multiplier = sqrtf(1.0f / square_magnitude); - - bgc_fp32_quaternion_multiply_by_real(&pose->_real_part, &pose->_real_part, multiplier); - bgc_fp32_quaternion_multiply_by_real(&pose->_dual_part, &pose->_dual_part, multiplier); -} - -void _bgc_fp64_rigid_pose3_normalize(BGC_FP64_RigidPose3* pose, const double square_magnitude) -{ - if (square_magnitude <= BGC_FP64_SQUARE_EPSILON || isnan(square_magnitude)) { - bgc_fp64_rigid_pose3_reset(pose); - return; - } - - const double multiplier = sqrt(1.0 / square_magnitude); - - bgc_fp64_quaternion_multiply_by_real(&pose->_real_part, &pose->_real_part, multiplier); - bgc_fp64_quaternion_multiply_by_real(&pose->_dual_part, &pose->_dual_part, multiplier); -} diff --git a/basic-geometry/rigid-pose3.h b/basic-geometry/rigid-pose3.h index 8e380ab..0a9b850 100644 --- a/basic-geometry/rigid-pose3.h +++ b/basic-geometry/rigid-pose3.h @@ -6,9 +6,35 @@ // ================= Normalize ================== // -void _bgc_fp32_rigid_pose3_normalize(BGC_FP32_RigidPose3* pose, const float square_magnitude); +void _bgc_fp32_rigid_pose3_normalize_parts(BGC_FP32_RigidPose3* pose, const float square_magnitude); -void _bgc_fp64_rigid_pose3_normalize(BGC_FP64_RigidPose3* pose, const double square_magnitude); +void _bgc_fp64_rigid_pose3_normalize_parts(BGC_FP64_RigidPose3* pose, const double square_magnitude); + +inline void _bgc_fp32_rigid_pose3_normalize(BGC_FP32_RigidPose3* pose) +{ + const float square_magnitude = bgc_fp32_quaternion_get_square_magnitude(&pose->_real_part); + + if (!bgc_fp32_is_square_unit(square_magnitude)) { + _bgc_fp32_rigid_pose3_normalize_parts(pose, square_magnitude); + } + + const float dot_product = bgc_fp32_quaternion_get_dot_product(&pose->_real_part, &pose->_dual_part); + + bgc_fp32_quaternion_subtract_scaled(&pose->_dual_part, &pose->_dual_part, &pose->_real_part, dot_product); +} + +inline void _bgc_fp64_rigid_pose3_normalize(BGC_FP64_RigidPose3* pose) +{ + const double square_magnitude = bgc_fp64_quaternion_get_square_magnitude(&pose->_real_part); + + if (!bgc_fp64_is_square_unit(square_magnitude)) { + _bgc_fp64_rigid_pose3_normalize_parts(pose, square_magnitude); + } + + const double dot_product = bgc_fp64_quaternion_get_dot_product(&pose->_real_part, &pose->_dual_part); + + bgc_fp64_quaternion_subtract_scaled(&pose->_dual_part, &pose->_dual_part, &pose->_real_part, dot_product); +} // ==================== Reset =================== // @@ -73,15 +99,7 @@ inline void bgc_fp32_rigid_pose3_convert_to_fp64(BGC_FP64_RigidPose3* destinatio bgc_fp32_quaternion_convert_to_fp64(&destination->_real_part, &source->_real_part); bgc_fp32_quaternion_convert_to_fp64(&destination->_dual_part, &source->_dual_part); - const double square_magnitude = bgc_fp64_quaternion_get_square_magnitude(&destination->_real_part); - - if (!bgc_fp64_is_square_unit(square_magnitude)) { - _bgc_fp64_rigid_pose3_normalize(destination, square_magnitude); - } - - const double dot_product = bgc_fp64_quaternion_get_dot_product(&destination->_real_part, &destination->_dual_part); - - bgc_fp64_quaternion_subtract_scaled(&destination->_dual_part, &destination->_dual_part, &destination->_real_part, dot_product); + _bgc_fp64_rigid_pose3_normalize(destination); } inline void bgc_fp64_rigid_pose3_convert_to_fp32(BGC_FP32_RigidPose3* destination, const BGC_FP64_RigidPose3* source) @@ -89,15 +107,7 @@ inline void bgc_fp64_rigid_pose3_convert_to_fp32(BGC_FP32_RigidPose3* destinatio bgc_fp64_quaternion_convert_to_fp32(&destination->_real_part, &source->_real_part); bgc_fp64_quaternion_convert_to_fp32(&destination->_dual_part, &source->_dual_part); - const float square_magnitude = bgc_fp32_quaternion_get_square_magnitude(&destination->_real_part); - - if (!bgc_fp32_is_square_unit(square_magnitude)) { - _bgc_fp32_rigid_pose3_normalize(destination, square_magnitude); - } - - const float dot_product = bgc_fp32_quaternion_get_dot_product(&destination->_real_part, &destination->_dual_part); - - bgc_fp32_quaternion_subtract_scaled(&destination->_dual_part, &destination->_dual_part, &destination->_real_part, dot_product); + _bgc_fp32_rigid_pose3_normalize(destination); } // ================== Combine =================== // @@ -112,15 +122,7 @@ inline void bgc_fp32_rigid_pose3_combine(BGC_FP32_RigidPose3* combination, const bgc_fp32_quaternion_multiply_by_quaternion(&combination->_real_part, &second->_real_part, &first->_real_part); bgc_fp32_quaternion_add(&combination->_dual_part, &dual_part1, &dual_part2); - const float square_magnitude = bgc_fp32_quaternion_get_square_magnitude(&combination->_real_part); - - if (!bgc_fp32_is_square_unit(square_magnitude)) { - _bgc_fp32_rigid_pose3_normalize(combination, square_magnitude); - } - - const float dot_product = bgc_fp32_quaternion_get_dot_product(&combination->_real_part, &combination->_dual_part); - - bgc_fp32_quaternion_subtract_scaled(&combination->_dual_part, &combination->_dual_part, &combination->_real_part, dot_product); + _bgc_fp32_rigid_pose3_normalize(combination); } inline void bgc_fp64_rigid_pose3_combine(BGC_FP64_RigidPose3* combination, const BGC_FP64_RigidPose3* first, const BGC_FP64_RigidPose3* second) @@ -133,15 +135,7 @@ inline void bgc_fp64_rigid_pose3_combine(BGC_FP64_RigidPose3* combination, const bgc_fp64_quaternion_multiply_by_quaternion(&combination->_real_part, &second->_real_part, &first->_real_part); bgc_fp64_quaternion_add(&combination->_dual_part, &dual_part1, &dual_part2); - const double square_magnitude = bgc_fp64_quaternion_get_square_magnitude(&combination->_real_part); - - if (!bgc_fp64_is_square_unit(square_magnitude)) { - _bgc_fp64_rigid_pose3_normalize(combination, square_magnitude); - } - - const double dot_product = bgc_fp64_quaternion_get_dot_product(&combination->_real_part, &combination->_dual_part); - - bgc_fp64_quaternion_subtract_scaled(&combination->_dual_part, &combination->_dual_part, &combination->_real_part, dot_product); + _bgc_fp64_rigid_pose3_normalize(combination); } #endif diff --git a/basic-geometry/turn3.c b/basic-geometry/turn3.c index cc3a8ea..17dbe9b 100644 --- a/basic-geometry/turn3.c +++ b/basic-geometry/turn3.c @@ -222,7 +222,7 @@ int bgc_fp32_turn3_find_direction_difference(BGC_FP32_Turn3* turn, const BGC_FP3 BGC_FP32_Vector3 axis; - bgc_fp32_vector3_get_cross_product(&axis, first, second); + _bgc_fp32_restrict_vector3_get_cross_product(&axis, first, second); const float square_product = first_square_modulus * second_square_modulus; const float dot_product = bgc_fp32_vector3_get_dot_product(first, second); @@ -266,7 +266,7 @@ int bgc_fp64_turn3_find_direction_difference(BGC_FP64_Turn3* turn, const BGC_FP6 BGC_FP64_Vector3 axis; - bgc_fp64_vector3_get_cross_product(&axis, first, second); + _bgc_fp64_restrict_vector3_get_cross_product(&axis, first, second); const double square_product = first_square_modulus * second_square_modulus; const double dot_product = bgc_fp64_vector3_get_dot_product(first, second); diff --git a/basic-geometry/vector3.c b/basic-geometry/vector3.c index 693eb04..828b6cd 100644 --- a/basic-geometry/vector3.c +++ b/basic-geometry/vector3.c @@ -77,6 +77,9 @@ extern inline double bgc_fp64_vector3_get_dot_product(const BGC_FP64_Vector3* ve extern inline float bgc_fp32_vector3_get_triple_product(const BGC_FP32_Vector3* vector1, const BGC_FP32_Vector3* vector2, const BGC_FP32_Vector3* vector3); extern inline double bgc_fp64_vector3_get_triple_product(const BGC_FP64_Vector3* vector1, const BGC_FP64_Vector3* vector2, const BGC_FP64_Vector3* vector3); + +extern inline void _bgc_fp32_restrict_vector3_get_cross_product(BGC_FP32_Vector3* restrict product, const BGC_FP32_Vector3* vector1, const BGC_FP32_Vector3* vector2); +extern inline void _bgc_fp64_restrict_vector3_get_cross_product(BGC_FP64_Vector3* restrict product, const BGC_FP64_Vector3* vector1, const BGC_FP64_Vector3* vector2); extern inline void bgc_fp32_vector3_get_cross_product(BGC_FP32_Vector3* product, const BGC_FP32_Vector3* vector1, const BGC_FP32_Vector3* vector2); extern inline void bgc_fp64_vector3_get_cross_product(BGC_FP64_Vector3* product, const BGC_FP64_Vector3* vector1, const BGC_FP64_Vector3* vector2); diff --git a/basic-geometry/vector3.h b/basic-geometry/vector3.h index 91b745d..476dbcf 100644 --- a/basic-geometry/vector3.h +++ b/basic-geometry/vector3.h @@ -479,6 +479,22 @@ inline double bgc_fp64_vector3_get_triple_product(const BGC_FP64_Vector3* vector + vector1->x3 * (vector2->x1 * vector3->x2 - vector2->x2 * vector3->x1); } +// =========== Restrict Cross Product =========== // + +inline void _bgc_fp32_restrict_vector3_get_cross_product(BGC_FP32_Vector3* restrict product, const BGC_FP32_Vector3* vector1, const BGC_FP32_Vector3* vector2) +{ + product->x1 = vector1->x2 * vector2->x3 - vector1->x3 * vector2->x2; + product->x2 = vector1->x3 * vector2->x1 - vector1->x1 * vector2->x3; + product->x3 = vector1->x1 * vector2->x2 - vector1->x2 * vector2->x1; +} + +inline void _bgc_fp64_restrict_vector3_get_cross_product(BGC_FP64_Vector3* restrict product, const BGC_FP64_Vector3* vector1, const BGC_FP64_Vector3* vector2) +{ + product->x1 = vector1->x2 * vector2->x3 - vector1->x3 * vector2->x2; + product->x2 = vector1->x3 * vector2->x1 - vector1->x1 * vector2->x3; + product->x3 = vector1->x1 * vector2->x2 - vector1->x2 * vector2->x1; +} + // =============== Cross Product ================ // inline void bgc_fp32_vector3_get_cross_product(BGC_FP32_Vector3* product, const BGC_FP32_Vector3* vector1, const BGC_FP32_Vector3* vector2) @@ -642,7 +658,7 @@ inline int bgc_fp32_vector3_are_parallel(const BGC_FP32_Vector3* vector1, const BGC_FP32_Vector3 product; - bgc_fp32_vector3_get_cross_product(&product, vector1, vector2); + _bgc_fp32_restrict_vector3_get_cross_product(&product, vector1, vector2); return bgc_fp32_vector3_get_squared_length(&product) <= BGC_FP32_SQUARE_EPSILON * square_modulus1 * square_modulus2; } @@ -658,7 +674,7 @@ inline int bgc_fp64_vector3_are_parallel(const BGC_FP64_Vector3* vector1, const BGC_FP64_Vector3 product; - bgc_fp64_vector3_get_cross_product(&product, vector1, vector2); + _bgc_fp64_restrict_vector3_get_cross_product(&product, vector1, vector2); return bgc_fp64_vector3_get_squared_length(&product) <= BGC_FP64_SQUARE_EPSILON * square_modulus1 * square_modulus2; } @@ -714,7 +730,7 @@ inline int bgc_fp32_vector3_get_attitude(const BGC_FP32_Vector3* vector1, const BGC_FP32_Vector3 product; - bgc_fp32_vector3_get_cross_product(&product, vector1, vector2); + _bgc_fp32_restrict_vector3_get_cross_product(&product, vector1, vector2); if (bgc_fp32_vector3_get_squared_length(&product) > square_limit) { return BGC_ATTITUDE_ANY; @@ -742,7 +758,7 @@ inline int bgc_fp64_vector3_get_attitude(const BGC_FP64_Vector3* vector1, const BGC_FP64_Vector3 product; - bgc_fp64_vector3_get_cross_product(&product, vector1, vector2); + _bgc_fp64_restrict_vector3_get_cross_product(&product, vector1, vector2); if (bgc_fp64_vector3_get_squared_length(&product) > square_limit) { return BGC_ATTITUDE_ANY;