#ifndef _BGC_VECTOR3_H_ #define _BGC_VECTOR3_H_ #include "utilities.h" #include "angle.h" #include // ================== Vector3 =================== // typedef struct { float x1, x2, x3; } BGC_FP32_Vector3; typedef struct { double x1, x2, x3; } BGC_FP64_Vector3; // =================== Reset ==================== // inline void bgc_fp32_vector3_reset(BGC_FP32_Vector3* vector) { vector->x1 = 0.0f; vector->x2 = 0.0f; vector->x3 = 0.0f; } inline void bgc_fp64_vector3_reset(BGC_FP64_Vector3* vector) { vector->x1 = 0.0; vector->x2 = 0.0; vector->x3 = 0.0; } // ==================== Set ===================== // inline void bgc_fp32_vector3_make(BGC_FP32_Vector3* destination, const float x1, const float x2, const float x3) { destination->x1 = x1; destination->x2 = x2; destination->x3 = x3; } inline void bgc_fp64_vector3_make(BGC_FP64_Vector3* destination, const double x1, const double x2, const double x3) { destination->x1 = x1; destination->x2 = x2; destination->x3 = x3; } // ================== Modulus =================== // inline float bgc_fp32_vector3_get_square_modulus(const BGC_FP32_Vector3* vector) { return vector->x1 * vector->x1 + vector->x2 * vector->x2 + vector->x3 * vector->x3; } inline double bgc_fp64_vector3_get_square_modulus(const BGC_FP64_Vector3* vector) { return vector->x1 * vector->x1 + vector->x2 * vector->x2 + vector->x3 * vector->x3; } inline float bgc_fp32_vector3_get_modulus(const BGC_FP32_Vector3* vector) { return sqrtf(bgc_fp32_vector3_get_square_modulus(vector)); } inline double bgc_fp64_vector3_get_modulus(const BGC_FP64_Vector3* vector) { return sqrt(bgc_fp64_vector3_get_square_modulus(vector)); } // ================= Comparison ================= // inline int bgc_fp32_vector3_is_zero(const BGC_FP32_Vector3* vector) { return bgc_fp32_vector3_get_square_modulus(vector) <= BGC_FP32_SQUARE_EPSILON; } inline int bgc_fp64_vector3_is_zero(const BGC_FP64_Vector3* vector) { return bgc_fp64_vector3_get_square_modulus(vector) <= BGC_FP64_SQUARE_EPSILON; } inline int bgc_fp32_vector3_is_unit(const BGC_FP32_Vector3* vector) { return bgc_fp32_is_square_unit(bgc_fp32_vector3_get_square_modulus(vector)); } inline int bgc_fp64_vector3_is_unit(const BGC_FP64_Vector3* vector) { return bgc_fp64_is_square_unit(bgc_fp64_vector3_get_square_modulus(vector)); } // ==================== Copy ==================== // inline void bgc_fp32_vector3_copy(BGC_FP32_Vector3* destination, const BGC_FP32_Vector3* source) { destination->x1 = source->x1; destination->x2 = source->x2; destination->x3 = source->x3; } inline void bgc_fp64_vector3_copy(BGC_FP64_Vector3* destination, const BGC_FP64_Vector3* source) { destination->x1 = source->x1; destination->x2 = source->x2; destination->x3 = source->x3; } // ==================== Swap ==================== // inline void bgc_fp32_vector3_swap(BGC_FP32_Vector3* vector1, BGC_FP32_Vector3* vector2) { const float x1 = vector2->x1; const float x2 = vector2->x2; const float x3 = vector2->x3; vector2->x1 = vector1->x1; vector2->x2 = vector1->x2; vector2->x3 = vector1->x3; vector1->x1 = x1; vector1->x2 = x2; vector1->x3 = x3; } inline void bgc_fp64_vector3_swap(BGC_FP64_Vector3* vector1, BGC_FP64_Vector3* vector2) { const double x1 = vector2->x1; const double x2 = vector2->x2; const double x3 = vector2->x3; vector2->x1 = vector1->x1; vector2->x2 = vector1->x2; vector2->x3 = vector1->x3; vector1->x1 = x1; vector1->x2 = x2; vector1->x3 = x3; } // ================== Convert =================== // inline void bgc_fp32_vector3_convert_to_fp64(BGC_FP64_Vector3* destination, const BGC_FP32_Vector3* source) { destination->x1 = source->x1; destination->x2 = source->x2; destination->x3 = source->x3; } inline void bgc_fp64_vector3_convert_to_fp32(BGC_FP32_Vector3* destination, const BGC_FP64_Vector3* source) { destination->x1 = (float)source->x1; destination->x2 = (float)source->x2; destination->x3 = (float)source->x3; } // ==================== Add ===================== // inline void bgc_fp32_vector3_add(BGC_FP32_Vector3* sum, const BGC_FP32_Vector3* vector1, const BGC_FP32_Vector3* vector2) { sum->x1 = vector1->x1 + vector2->x1; sum->x2 = vector1->x2 + vector2->x2; sum->x3 = vector1->x3 + vector2->x3; } inline void bgc_fp64_vector3_add(BGC_FP64_Vector3* sum, const BGC_FP64_Vector3* vector1, const BGC_FP64_Vector3* vector2) { sum->x1 = vector1->x1 + vector2->x1; sum->x2 = vector1->x2 + vector2->x2; sum->x3 = vector1->x3 + vector2->x3; } // ================= Add scaled ================= // inline void bgc_fp32_vector3_add_scaled(BGC_FP32_Vector3* sum, const BGC_FP32_Vector3* basic_vector, const BGC_FP32_Vector3* scalable_vector, const float scale) { sum->x1 = basic_vector->x1 + scalable_vector->x1 * scale; sum->x2 = basic_vector->x2 + scalable_vector->x2 * scale; sum->x3 = basic_vector->x3 + scalable_vector->x3 * scale; } inline void bgc_fp64_vector3_add_scaled(BGC_FP64_Vector3* sum, const BGC_FP64_Vector3* basic_vector, const BGC_FP64_Vector3* scalable_vector, const double scale) { sum->x1 = basic_vector->x1 + scalable_vector->x1 * scale; sum->x2 = basic_vector->x2 + scalable_vector->x2 * scale; sum->x3 = basic_vector->x3 + scalable_vector->x3 * scale; } // ================== Subtract ================== // inline void bgc_fp32_vector3_subtract(BGC_FP32_Vector3* difference, const BGC_FP32_Vector3* minuend, const BGC_FP32_Vector3* subtrahend) { difference->x1 = minuend->x1 - subtrahend->x1; difference->x2 = minuend->x2 - subtrahend->x2; difference->x3 = minuend->x3 - subtrahend->x3; } inline void bgc_fp64_vector3_subtract(BGC_FP64_Vector3* difference, const BGC_FP64_Vector3* minuend, const BGC_FP64_Vector3* subtrahend) { difference->x1 = minuend->x1 - subtrahend->x1; difference->x2 = minuend->x2 - subtrahend->x2; difference->x3 = minuend->x3 - subtrahend->x3; } // ================== Multiply ================== // inline void bgc_fp32_vector3_multiply(BGC_FP32_Vector3* product, const BGC_FP32_Vector3* multiplicand, const float multiplier) { product->x1 = multiplicand->x1 * multiplier; product->x2 = multiplicand->x2 * multiplier; product->x3 = multiplicand->x3 * multiplier; } inline void bgc_fp64_vector3_multiply(BGC_FP64_Vector3* product, const BGC_FP64_Vector3* multiplicand, const double multiplier) { product->x1 = multiplicand->x1 * multiplier; product->x2 = multiplicand->x2 * multiplier; product->x3 = multiplicand->x3 * multiplier; } // =================== Divide =================== // inline void bgc_fp32_vector3_divide(BGC_FP32_Vector3* quotient, const BGC_FP32_Vector3* dividend, const float divisor) { bgc_fp32_vector3_multiply(quotient, dividend, 1.0f / divisor); } inline void bgc_fp64_vector3_divide(BGC_FP64_Vector3* quotient, const BGC_FP64_Vector3* dividend, const double divisor) { bgc_fp64_vector3_multiply(quotient, dividend, 1.0 / divisor); } // ================== Average2 ================== // inline void bgc_fp32_vector3_get_mean2(BGC_FP32_Vector3* mean, const BGC_FP32_Vector3* vector1, const BGC_FP32_Vector3* vector2) { mean->x1 = (vector1->x1 + vector2->x1) * 0.5f; mean->x2 = (vector1->x2 + vector2->x2) * 0.5f; mean->x3 = (vector1->x3 + vector2->x3) * 0.5f; } inline void bgc_fp64_vector3_get_mean2(BGC_FP64_Vector3* mean, const BGC_FP64_Vector3* vector1, const BGC_FP64_Vector3* vector2) { mean->x1 = (vector1->x1 + vector2->x1) * 0.5; mean->x2 = (vector1->x2 + vector2->x2) * 0.5; mean->x3 = (vector1->x3 + vector2->x3) * 0.5; } // ================== Average3 ================== // inline void bgc_fp32_vector3_get_mean3(BGC_FP32_Vector3* mean, const BGC_FP32_Vector3* vector1, const BGC_FP32_Vector3* vector2, const BGC_FP32_Vector3* vector3) { mean->x1 = (vector1->x1 + vector2->x1 + vector3->x1) * BGC_FP32_ONE_THIRD; mean->x2 = (vector1->x2 + vector2->x2 + vector3->x2) * BGC_FP32_ONE_THIRD; mean->x3 = (vector1->x3 + vector2->x3 + vector3->x3) * BGC_FP32_ONE_THIRD; } inline void bgc_fp64_vector3_get_mean3(BGC_FP64_Vector3* mean, const BGC_FP64_Vector3* vector1, const BGC_FP64_Vector3* vector2, const BGC_FP64_Vector3* vector3) { mean->x1 = (vector1->x1 + vector2->x1 + vector3->x1) * BGC_FP64_ONE_THIRD; mean->x2 = (vector1->x2 + vector2->x2 + vector3->x2) * BGC_FP64_ONE_THIRD; mean->x3 = (vector1->x3 + vector2->x3 + vector3->x3) * BGC_FP64_ONE_THIRD; } // =================== Linear =================== // inline void bgc_fp32_vector3_interpolate(BGC_FP32_Vector3* interpolation, const BGC_FP32_Vector3* vector1, const BGC_FP32_Vector3* vector2, const float phase) { const float counter_phase = 1.0f - phase; interpolation->x1 = vector1->x1 * counter_phase + vector2->x1 * phase; interpolation->x2 = vector1->x2 * counter_phase + vector2->x2 * phase; interpolation->x3 = vector1->x3 * counter_phase + vector2->x3 * phase; } inline void bgc_fp64_vector3_interpolate(BGC_FP64_Vector3* interpolation, const BGC_FP64_Vector3* vector1, const BGC_FP64_Vector3* vector2, const double phase) { const double counter_phase = 1.0 - phase; interpolation->x1 = vector1->x1 * counter_phase + vector2->x1 * phase; interpolation->x2 = vector1->x2 * counter_phase + vector2->x2 * phase; interpolation->x3 = vector1->x3 * counter_phase + vector2->x3 * phase; } // ================== Negative ================== // inline void bgc_fp32_vector3_revert(BGC_FP32_Vector3* vector) { vector->x1 = -vector->x1; vector->x2 = -vector->x2; vector->x3 = -vector->x3; } inline void bgc_fp64_vector3_revert(BGC_FP64_Vector3* vector) { vector->x1 = -vector->x1; vector->x2 = -vector->x2; vector->x3 = -vector->x3; } inline void bgc_fp32_vector3_get_reverse(BGC_FP32_Vector3* reverse, const BGC_FP32_Vector3* vector) { reverse->x1 = -vector->x1; reverse->x2 = -vector->x2; reverse->x3 = -vector->x3; } inline void bgc_fp64_vector3_get_reverse(BGC_FP64_Vector3* reverse, const BGC_FP64_Vector3* vector) { reverse->x1 = -vector->x1; reverse->x2 = -vector->x2; reverse->x3 = -vector->x3; } // ================= Normalize ================== // inline int bgc_fp32_vector3_normalize(BGC_FP32_Vector3* vector) { const float square_modulus = bgc_fp32_vector3_get_square_modulus(vector); if (bgc_fp32_is_square_unit(square_modulus)) { return 1; } if (square_modulus <= BGC_FP32_SQUARE_EPSILON || isnan(square_modulus)) { return 0; } const float multiplier = sqrtf(1.0f / square_modulus); vector->x1 *= multiplier; vector->x2 *= multiplier; vector->x3 *= multiplier; return 1; } inline int bgc_fp64_vector3_normalize(BGC_FP64_Vector3* vector) { const double square_modulus = bgc_fp64_vector3_get_square_modulus(vector); if (bgc_fp64_is_square_unit(square_modulus)) { return 1; } if (square_modulus <= BGC_FP64_SQUARE_EPSILON || isnan(square_modulus)) { return 0; } const double multiplier = sqrt(1.0 / square_modulus); vector->x1 *= multiplier; vector->x2 *= multiplier; vector->x3 *= multiplier; return 1; } inline int bgc_fp32_vector3_get_normalized(BGC_FP32_Vector3* normalized, const BGC_FP32_Vector3* vector) { const float square_modulus = bgc_fp32_vector3_get_square_modulus(vector); if (bgc_fp32_is_square_unit(square_modulus)) { bgc_fp32_vector3_copy(normalized, vector); return 1; } if (square_modulus <= BGC_FP32_SQUARE_EPSILON || isnan(square_modulus)) { bgc_fp32_vector3_reset(normalized); return 0; } bgc_fp32_vector3_multiply(normalized, vector, sqrtf(1.0f / square_modulus)); return 1; } inline int bgc_fp64_vector3_get_normalized(BGC_FP64_Vector3* normalized, const BGC_FP64_Vector3* vector) { const double square_modulus = bgc_fp64_vector3_get_square_modulus(vector); if (bgc_fp64_is_square_unit(square_modulus)) { bgc_fp64_vector3_copy(normalized, vector); return 1; } if (square_modulus <= BGC_FP64_SQUARE_EPSILON || isnan(square_modulus)) { bgc_fp64_vector3_reset(normalized); return 0; } bgc_fp64_vector3_multiply(normalized, vector, sqrt(1.0 / square_modulus)); return 1; } // =============== Scalar Product =============== // inline float bgc_fp32_vector3_get_dot_product(const BGC_FP32_Vector3* vector1, const BGC_FP32_Vector3* vector2) { return vector1->x1 * vector2->x1 + vector1->x2 * vector2->x2 + vector1->x3 * vector2->x3; } inline double bgc_fp64_vector3_get_dot_product(const BGC_FP64_Vector3* vector1, const BGC_FP64_Vector3* vector2) { return vector1->x1 * vector2->x1 + vector1->x2 * vector2->x2 + vector1->x3 * vector2->x3; } // =============== Triple Product =============== // inline float bgc_fp32_vector3_get_triple_product(const BGC_FP32_Vector3* vector1, const BGC_FP32_Vector3* vector2, const BGC_FP32_Vector3* vector3) { return vector1->x1 * (vector2->x2 * vector3->x3 - vector2->x3 * vector3->x2) + vector1->x2 * (vector2->x3 * vector3->x1 - vector2->x1 * vector3->x3) + vector1->x3 * (vector2->x1 * vector3->x2 - vector2->x2 * vector3->x1); } inline double bgc_fp64_vector3_get_triple_product(const BGC_FP64_Vector3* vector1, const BGC_FP64_Vector3* vector2, const BGC_FP64_Vector3* vector3) { return vector1->x1 * (vector2->x2 * vector3->x3 - vector2->x3 * vector3->x2) + vector1->x2 * (vector2->x3 * vector3->x1 - vector2->x1 * vector3->x3) + vector1->x3 * (vector2->x1 * vector3->x2 - vector2->x2 * vector3->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) { const float x1 = vector1->x2 * vector2->x3 - vector1->x3 * vector2->x2; const float x2 = vector1->x3 * vector2->x1 - vector1->x1 * vector2->x3; const float x3 = vector1->x1 * vector2->x2 - vector1->x2 * vector2->x1; product->x1 = x1; product->x2 = x2; product->x3 = x3; } inline void bgc_fp64_vector3_get_cross_product(BGC_FP64_Vector3* product, const BGC_FP64_Vector3* vector1, const BGC_FP64_Vector3* vector2) { const double x1 = vector1->x2 * vector2->x3 - vector1->x3 * vector2->x2; const double x2 = vector1->x3 * vector2->x1 - vector1->x1 * vector2->x3; const double x3 = vector1->x1 * vector2->x2 - vector1->x2 * vector2->x1; product->x1 = x1; product->x2 = x2; product->x3 = x3; } // ============ Double Cross Product ============ // inline void bgc_fp32_vector3_get_double_cross(BGC_FP32_Vector3* product, const BGC_FP32_Vector3* vector1, const BGC_FP32_Vector3* vector2, const BGC_FP32_Vector3* vector3) { const float ac = bgc_fp32_vector3_get_dot_product(vector1, vector3); const float ab = bgc_fp32_vector3_get_dot_product(vector1, vector2); product->x1 = vector2->x1 * ac - vector3->x1 * ab; product->x2 = vector2->x2 * ac - vector3->x2 * ab; product->x3 = vector2->x3 * ac - vector3->x3 * ab; } inline void bgc_fp64_vector3_get_double_cross(BGC_FP64_Vector3* product, const BGC_FP64_Vector3* vector1, const BGC_FP64_Vector3* vector2, const BGC_FP64_Vector3* vector3) { const double ac = bgc_fp64_vector3_get_dot_product(vector1, vector3); const double ab = bgc_fp64_vector3_get_dot_product(vector1, vector2); product->x1 = vector2->x1 * ac - vector3->x1 * ab; product->x2 = vector2->x2 * ac - vector3->x2 * ab; product->x3 = vector2->x3 * ac - vector3->x3 * ab; } // =================== Angle ==================== // float bgc_fp32_vector3_get_angle(const BGC_FP32_Vector3* vector1, const BGC_FP32_Vector3* vector2, const int angle_unit); double bgc_fp64_vector3_get_angle(const BGC_FP64_Vector3* vector1, const BGC_FP64_Vector3* vector2, const int angle_unit); // =============== Square Distance ============== // inline float bgc_fp32_vector3_get_square_distance(const BGC_FP32_Vector3* vector1, const BGC_FP32_Vector3* vector2) { const float dx1 = (vector1->x1 - vector2->x1); const float dx2 = (vector1->x2 - vector2->x2); const float dx3 = (vector1->x3 - vector2->x3); return dx1 * dx1 + dx2 * dx2 + dx3 * dx3; } inline double bgc_fp64_vector3_get_square_distance(const BGC_FP64_Vector3* vector1, const BGC_FP64_Vector3* vector2) { const double dx1 = (vector1->x1 - vector2->x1); const double dx2 = (vector1->x2 - vector2->x2); const double dx3 = (vector1->x3 - vector2->x3); return dx1 * dx1 + dx2 * dx2 + dx3 * dx3; } // ================== Distance ================== // inline float bgc_fp32_vector3_get_distance(const BGC_FP32_Vector3* vector1, const BGC_FP32_Vector3* vector2) { return sqrtf(bgc_fp32_vector3_get_square_distance(vector1, vector2)); } inline double bgc_fp64_vector3_get_distance(const BGC_FP64_Vector3* vector1, const BGC_FP64_Vector3* vector2) { return sqrt(bgc_fp64_vector3_get_square_distance(vector1, vector2)); } // ============== Are Close Enough ============== // inline int bgc_fp32_vector3_are_close_enough(const BGC_FP32_Vector3* vector1, const BGC_FP32_Vector3* vector2, const float distance_limit) { return bgc_fp32_vector3_get_square_distance(vector1, vector2) <= distance_limit * distance_limit; } inline int bgc_fp64_vector3_are_close_enough(const BGC_FP64_Vector3* vector1, const BGC_FP64_Vector3* vector2, const double distance_limit) { return bgc_fp64_vector3_get_square_distance(vector1, vector2) <= distance_limit * distance_limit; } // ================== Are Close ================= // inline int bgc_fp32_vector3_are_close(const BGC_FP32_Vector3* vector1, const BGC_FP32_Vector3* vector2) { const float square_modulus1 = bgc_fp32_vector3_get_square_modulus(vector1); const float square_modulus2 = bgc_fp32_vector3_get_square_modulus(vector2); const float square_distance = bgc_fp32_vector3_get_square_distance(vector1, vector2); if (square_modulus1 <= BGC_FP32_EPSILON_EFFECTIVENESS_LIMIT || square_modulus2 <= BGC_FP32_EPSILON_EFFECTIVENESS_LIMIT) { return square_distance <= BGC_FP32_SQUARE_EPSILON; } return square_distance <= BGC_FP32_SQUARE_EPSILON * square_modulus1 && square_distance <= BGC_FP32_SQUARE_EPSILON * square_modulus2; } inline int bgc_fp64_vector3_are_close(const BGC_FP64_Vector3* vector1, const BGC_FP64_Vector3* vector2) { const double square_modulus1 = bgc_fp64_vector3_get_square_modulus(vector1); const double square_modulus2 = bgc_fp64_vector3_get_square_modulus(vector2); const double square_distance = bgc_fp64_vector3_get_square_distance(vector1, vector2); if (square_modulus1 <= BGC_FP64_EPSILON_EFFECTIVENESS_LIMIT || square_modulus2 <= BGC_FP64_EPSILON_EFFECTIVENESS_LIMIT) { return square_distance <= BGC_FP64_SQUARE_EPSILON; } return square_distance <= BGC_FP64_SQUARE_EPSILON * square_modulus1 && square_distance <= BGC_FP64_SQUARE_EPSILON * square_modulus2; } // ================== Parallel ================== // inline int bgc_fp32_vector3_are_parallel(const BGC_FP32_Vector3* vector1, const BGC_FP32_Vector3* vector2) { const float square_modulus1 = bgc_fp32_vector3_get_square_modulus(vector1); const float square_modulus2 = bgc_fp32_vector3_get_square_modulus(vector2); if (square_modulus1 <= BGC_FP32_SQUARE_EPSILON || square_modulus2 <= BGC_FP32_SQUARE_EPSILON) { return 1; } BGC_FP32_Vector3 product; bgc_fp32_vector3_get_cross_product(&product, vector1, vector2); return bgc_fp32_vector3_get_square_modulus(&product) <= BGC_FP32_SQUARE_EPSILON * square_modulus1 * square_modulus2; } inline int bgc_fp64_vector3_are_parallel(const BGC_FP64_Vector3* vector1, const BGC_FP64_Vector3* vector2) { const double square_modulus1 = bgc_fp64_vector3_get_square_modulus(vector1); const double square_modulus2 = bgc_fp64_vector3_get_square_modulus(vector2); if (square_modulus1 <= BGC_FP64_SQUARE_EPSILON || square_modulus2 <= BGC_FP64_SQUARE_EPSILON) { return 1; } BGC_FP64_Vector3 product; bgc_fp64_vector3_get_cross_product(&product, vector1, vector2); return bgc_fp64_vector3_get_square_modulus(&product) <= BGC_FP64_SQUARE_EPSILON * square_modulus1 * square_modulus2; } // ================= Orthogonal ================= // inline int bgc_fp32_vector3_are_orthogonal(const BGC_FP32_Vector3* vector1, const BGC_FP32_Vector3* vector2) { const float square_modulus1 = bgc_fp32_vector3_get_square_modulus(vector1); const float square_modulus2 = bgc_fp32_vector3_get_square_modulus(vector2); if (square_modulus1 <= BGC_FP32_SQUARE_EPSILON || square_modulus2 <= BGC_FP32_SQUARE_EPSILON) { return 1; } const float scalar_product = bgc_fp32_vector3_get_dot_product(vector1, vector2); return scalar_product * scalar_product <= BGC_FP32_SQUARE_EPSILON * square_modulus1 * square_modulus2; } inline int bgc_fp64_vector3_are_orthogonal(const BGC_FP64_Vector3* vector1, const BGC_FP64_Vector3* vector2) { const double square_modulus1 = bgc_fp64_vector3_get_square_modulus(vector1); const double square_modulus2 = bgc_fp64_vector3_get_square_modulus(vector2); if (square_modulus1 <= BGC_FP64_SQUARE_EPSILON || square_modulus2 <= BGC_FP64_SQUARE_EPSILON) { return 1; } const double scalar_product = bgc_fp64_vector3_get_dot_product(vector1, vector2); return scalar_product * scalar_product <= BGC_FP64_SQUARE_EPSILON * square_modulus1 * square_modulus2; } // ================== Attitude ================== // inline int bgc_fp32_vector3_get_attitude(const BGC_FP32_Vector3* vector1, const BGC_FP32_Vector3* vector2) { const float square_modulus1 = bgc_fp32_vector3_get_square_modulus(vector1); const float square_modulus2 = bgc_fp32_vector3_get_square_modulus(vector2); if (square_modulus1 <= BGC_FP32_SQUARE_EPSILON || square_modulus2 <= BGC_FP32_SQUARE_EPSILON) { return BGC_ATTITUDE_ZERO; } const float square_limit = BGC_FP32_SQUARE_EPSILON * square_modulus1 * square_modulus2; const float scalar_product = bgc_fp32_vector3_get_dot_product(vector1, vector2); if (scalar_product * scalar_product <= square_limit) { return BGC_ATTITUDE_ORTHOGONAL; } BGC_FP32_Vector3 product; bgc_fp32_vector3_get_cross_product(&product, vector1, vector2); if (bgc_fp32_vector3_get_square_modulus(&product) > square_limit) { return BGC_ATTITUDE_ANY; } return scalar_product > 0.0f ? BGC_ATTITUDE_CO_DIRECTIONAL : BGC_ATTITUDE_COUNTER_DIRECTIONAL; } inline int bgc_fp64_vector3_get_attitude(const BGC_FP64_Vector3* vector1, const BGC_FP64_Vector3* vector2) { const double square_modulus1 = bgc_fp64_vector3_get_square_modulus(vector1); const double square_modulus2 = bgc_fp64_vector3_get_square_modulus(vector2); if (square_modulus1 <= BGC_FP64_SQUARE_EPSILON || square_modulus2 <= BGC_FP64_SQUARE_EPSILON) { return BGC_ATTITUDE_ZERO; } const double square_limit = BGC_FP64_SQUARE_EPSILON * square_modulus1 * square_modulus2; const double scalar_product = bgc_fp64_vector3_get_dot_product(vector1, vector2); if (scalar_product * scalar_product <= square_limit) { return BGC_ATTITUDE_ORTHOGONAL; } BGC_FP64_Vector3 product; bgc_fp64_vector3_get_cross_product(&product, vector1, vector2); if (bgc_fp64_vector3_get_square_modulus(&product) > square_limit) { return BGC_ATTITUDE_ANY; } return scalar_product > 0.0 ? BGC_ATTITUDE_CO_DIRECTIONAL : BGC_ATTITUDE_COUNTER_DIRECTIONAL; } #endif