#include #include "quaternion.h" extern inline void bgc_fp32_quaternion_reset(BGC_FP32_Quaternion* quaternion); extern inline void bgc_fp64_quaternion_reset(BGC_FP64_Quaternion* quaternion); extern inline void bgc_fp32_quaternion_make_unit(BGC_FP32_Quaternion* quaternion); extern inline void bgc_fp64_quaternion_make_unit(BGC_FP64_Quaternion* quaternion); extern inline void bgc_fp32_quaternion_make(BGC_FP32_Quaternion* quaternion, const float s0, const float x1, const float x2, const float x3); extern inline void bgc_fp64_quaternion_make(BGC_FP64_Quaternion* quaternion, const double s0, const double x1, const double x2, const double x3); extern inline float bgc_fp32_quaternion_get_square_modulus(const BGC_FP32_Quaternion* quaternion); extern inline double bgc_fp64_quaternion_get_square_modulus(const BGC_FP64_Quaternion* quaternion); extern inline float bgc_fp32_quaternion_get_modulus(const BGC_FP32_Quaternion* quaternion); extern inline double bgc_fp64_quaternion_get_modulus(const BGC_FP64_Quaternion* quaternion); extern inline int bgc_fp32_quaternion_is_zero(const BGC_FP32_Quaternion* quaternion); extern inline int bgc_fp64_quaternion_is_zero(const BGC_FP64_Quaternion* quaternion); extern inline int bgc_fp32_quaternion_is_unit(const BGC_FP32_Quaternion* quaternion); extern inline int bgc_fp64_quaternion_is_unit(const BGC_FP64_Quaternion* quaternion); extern inline void bgc_fp32_quaternion_copy(BGC_FP32_Quaternion* destination, const BGC_FP32_Quaternion* source); extern inline void bgc_fp64_quaternion_copy(BGC_FP64_Quaternion* destination, const BGC_FP64_Quaternion* source); extern inline void bgc_fp32_quaternion_swap(BGC_FP32_Quaternion* quarternion1, BGC_FP32_Quaternion* quarternion2); extern inline void bgc_fp64_quaternion_swap(BGC_FP64_Quaternion* quarternion1, BGC_FP64_Quaternion* quarternion2); extern inline void bgc_fp32_quaternion_convert_to_fp64(BGC_FP64_Quaternion* destination, const BGC_FP32_Quaternion* source); extern inline void bgc_fp64_quaternion_convert_to_fp32(BGC_FP32_Quaternion* destination, const BGC_FP64_Quaternion* source); extern inline void bgc_fp32_quaternion_add(BGC_FP32_Quaternion* sum, const BGC_FP32_Quaternion* quaternion1, const BGC_FP32_Quaternion* quaternion2); extern inline void bgc_fp64_quaternion_add(BGC_FP64_Quaternion* sum, const BGC_FP64_Quaternion* quaternion1, const BGC_FP64_Quaternion* quaternion2); extern inline void bgc_fp32_quaternion_add_scaled(BGC_FP32_Quaternion* sum, const BGC_FP32_Quaternion* basic_quaternion, const BGC_FP32_Quaternion* scalable_quaternion, const float scale); extern inline void bgc_fp64_quaternion_add_scaled(BGC_FP64_Quaternion* sum, const BGC_FP64_Quaternion* basic_quaternion, const BGC_FP64_Quaternion* scalable_quaternion, const double scale); extern inline void bgc_fp32_quaternion_subtract(BGC_FP32_Quaternion* difference, const BGC_FP32_Quaternion* minuend, const BGC_FP32_Quaternion* subtrahend); extern inline void bgc_fp64_quaternion_subtract(BGC_FP64_Quaternion* difference, const BGC_FP64_Quaternion* minuend, const BGC_FP64_Quaternion* subtrahend); extern inline void bgc_fp32_quaternion_get_product(BGC_FP32_Quaternion* product, const BGC_FP32_Quaternion* left, const BGC_FP32_Quaternion* right); extern inline void bgc_fp64_quaternion_get_product(BGC_FP64_Quaternion* product, const BGC_FP64_Quaternion* left, const BGC_FP64_Quaternion* right); extern inline void bgc_fp32_quaternion_get_product_by_conjugate(BGC_FP32_Quaternion* product, const BGC_FP32_Quaternion* left, const BGC_FP32_Quaternion* right); extern inline void bgc_fp64_quaternion_get_product_by_conjugate(BGC_FP64_Quaternion* product, const BGC_FP64_Quaternion* left, const BGC_FP64_Quaternion* right); extern inline void bgc_fp32_quaternion_multiply(BGC_FP32_Quaternion* product, const BGC_FP32_Quaternion* multiplicand, const float multipier); extern inline void bgc_fp64_quaternion_multiply(BGC_FP64_Quaternion* product, const BGC_FP64_Quaternion* multiplicand, const double multipier); extern inline int bgc_fp32_quaternion_get_ratio(BGC_FP32_Quaternion* quotient, const BGC_FP32_Quaternion* divident, const BGC_FP32_Quaternion* divisor); extern inline int bgc_fp64_quaternion_get_ratio(BGC_FP64_Quaternion* quotient, const BGC_FP64_Quaternion* divident, const BGC_FP64_Quaternion* divisor); extern inline void bgc_fp32_quaternion_divide(BGC_FP32_Quaternion* quotient, const BGC_FP32_Quaternion* dividend, const float divisor); extern inline void bgc_fp64_quaternion_divide(BGC_FP64_Quaternion* quotient, const BGC_FP64_Quaternion* dividend, const double divisor); extern inline void bgc_fp32_quaternion_get_mean2(BGC_FP32_Quaternion* mean, const BGC_FP32_Quaternion* quaternion1, const BGC_FP32_Quaternion* quaternion2); extern inline void bgc_fp64_quaternion_get_mean2(BGC_FP64_Quaternion* mean, const BGC_FP64_Quaternion* quaternion1, const BGC_FP64_Quaternion* quaternion2); extern inline void bgc_fp32_quaternion_get_mean3(BGC_FP32_Quaternion* mean, const BGC_FP32_Quaternion* quaternion1, const BGC_FP32_Quaternion* quaternion2, const BGC_FP32_Quaternion* quaternion3); extern inline void bgc_fp64_quaternion_get_mean3(BGC_FP64_Quaternion* mean, const BGC_FP64_Quaternion* quaternion1, const BGC_FP64_Quaternion* quaternion2, const BGC_FP64_Quaternion* quaternion3); extern inline void bgc_fp32_quaternion_interpolate(BGC_FP32_Quaternion* interpolation, const BGC_FP32_Quaternion* quaternion1, const BGC_FP32_Quaternion* quaternion2, const float phase); extern inline void bgc_fp64_quaternion_interpolate(BGC_FP64_Quaternion* interpolation, const BGC_FP64_Quaternion* quaternion1, const BGC_FP64_Quaternion* quaternion2, const double phase); extern inline void bgc_fp32_quaternion_conjugate(BGC_FP32_Quaternion* quaternion); extern inline void bgc_fp64_quaternion_conjugate(BGC_FP64_Quaternion* quaternion); extern inline void bgc_fp32_quaternion_get_conjugate(BGC_FP32_Quaternion* conjugate, const BGC_FP32_Quaternion* quaternion); extern inline void bgc_fp64_quaternion_get_conjugate(BGC_FP64_Quaternion* conjugate, const BGC_FP64_Quaternion* quaternion); extern inline void bgc_fp32_quaternion_revert(BGC_FP32_Quaternion* quaternion); extern inline void bgc_fp64_quaternion_revert(BGC_FP64_Quaternion* quaternion); extern inline void bgc_fp32_quaternion_get_reverse(BGC_FP32_Quaternion* reverse, const BGC_FP32_Quaternion* quaternion); extern inline void bgc_fp64_quaternion_get_reverse(BGC_FP64_Quaternion* reverse, const BGC_FP64_Quaternion* quaternion); extern inline int bgc_fp32_quaternion_invert(BGC_FP32_Quaternion* quaternion); extern inline int bgc_fp64_quaternion_invert(BGC_FP64_Quaternion* quaternion); extern inline int bgc_fp32_quaternion_get_inverse(BGC_FP32_Quaternion* inverse, const BGC_FP32_Quaternion* quaternion); extern inline int bgc_fp64_quaternion_get_inverse(BGC_FP64_Quaternion* inverse, const BGC_FP64_Quaternion* quaternion); extern inline int bgc_fp32_quaternion_normalize(BGC_FP32_Quaternion* quaternion); extern inline int bgc_fp64_quaternion_normalize(BGC_FP64_Quaternion* quaternion); extern inline int bgc_fp32_quaternion_get_normalized(BGC_FP32_Quaternion* normalized, const BGC_FP32_Quaternion* quaternion); extern inline int bgc_fp64_quaternion_get_normalized(BGC_FP64_Quaternion* normalized, const BGC_FP64_Quaternion* quaternion); extern inline int bgc_fp32_quaternion_get_rotation_matrix(BGC_FP32_Matrix3x3* rotation, const BGC_FP32_Quaternion* quaternion); extern inline int bgc_fp64_quaternion_get_rotation_matrix(BGC_FP64_Matrix3x3* rotation, const BGC_FP64_Quaternion* quaternion); extern inline int bgc_fp32_quaternion_get_reverse_matrix(BGC_FP32_Matrix3x3* reverse, const BGC_FP32_Quaternion* quaternion); extern inline int bgc_fp64_quaternion_get_reverse_matrix(BGC_FP64_Matrix3x3* reverse, const BGC_FP64_Quaternion* quaternion); extern inline int bgc_fp32_quaternion_get_both_matrices(BGC_FP32_Matrix3x3* rotation, BGC_FP32_Matrix3x3* reverse, const BGC_FP32_Quaternion* quaternion); extern inline int bgc_fp64_quaternion_get_both_matrices(BGC_FP64_Matrix3x3* rotation, BGC_FP64_Matrix3x3* reverse, const BGC_FP64_Quaternion* quaternion); extern inline int bgc_fp32_quaternion_are_close(const BGC_FP32_Quaternion* quaternion1, const BGC_FP32_Quaternion* quaternion2); extern inline int bgc_fp64_quaternion_are_close(const BGC_FP64_Quaternion* quaternion1, const BGC_FP64_Quaternion* quaternion2); // =============== Get Exponation =============== // int bgc_fp32_quaternion_get_exponation(BGC_FP32_Quaternion* power, const BGC_FP32_Quaternion* base, const float exponent) { const float s0s0 = base->s0 * base->s0; const float x1x1 = base->x1 * base->x1; const float x2x2 = base->x2 * base->x2; const float x3x3 = base->x3 * base->x3; const float square_vector = x1x1 + (x2x2 + x3x3); const float square_modulus = (s0s0 + x1x1) + (x2x2 + x3x3); // isnan(square_modulus) means checking for NaN value at square_modulus if (isnan(square_modulus)) { return 0; } if (square_vector <= BGC_FP32_SQUARE_EPSILON) { if (base->s0 < 0.0f) { return 0; } power->s0 = powf(base->s0, exponent); power->x1 = 0.0f; power->x2 = 0.0f; power->x3 = 0.0f; return 1; } const float vector_modulus = sqrtf(square_vector); const float power_angle = atan2f(vector_modulus, base->s0) * exponent; const float power_modulus = powf(square_modulus, 0.5f * exponent); const float multiplier = power_modulus * sinf(power_angle) / vector_modulus; power->s0 = power_modulus * cosf(power_angle); power->x1 = base->x1 * multiplier; power->x2 = base->x2 * multiplier; power->x3 = base->x3 * multiplier; return 1; } int bgc_fp64_quaternion_get_exponation(BGC_FP64_Quaternion* power, const BGC_FP64_Quaternion* base, const double exponent) { const double s0s0 = base->s0 * base->s0; const double x1x1 = base->x1 * base->x1; const double x2x2 = base->x2 * base->x2; const double x3x3 = base->x3 * base->x3; const double square_vector = x1x1 + (x2x2 + x3x3); const double square_modulus = (s0s0 + x1x1) + (x2x2 + x3x3); // isnan(square_modulus) means checking for NaN value at square_modulus if (isnan(square_modulus)) { return 0; } if (square_vector <= BGC_FP64_SQUARE_EPSILON) { if (base->s0 < 0.0) { return 0; } power->s0 = pow(base->s0, exponent); power->x1 = 0.0; power->x2 = 0.0; power->x3 = 0.0; return 1; } const double vector_modulus = sqrt(square_vector); const double power_angle = atan2(vector_modulus, base->s0) * exponent; const double power_modulus = pow(square_modulus, 0.5 * exponent); const double multiplier = power_modulus * sin(power_angle) / vector_modulus; power->s0 = power_modulus * cos(power_angle); power->x1 = base->x1 * multiplier; power->x2 = base->x2 * multiplier; power->x3 = base->x3 * multiplier; return 1; }