#ifndef _BGC_VECTOR3_H_INCLUDED_ #define _BGC_VECTOR3_H_INCLUDED_ #include #include "./utilities.h" #include "./types.h" #include "./angle.h" // =================== Reset ==================== // inline void bgc_fp32_vector3_reset(BGC_FP32_Vector3* const vector) { vector->x = 0.0f; vector->y = 0.0f; vector->z = 0.0f; } inline void bgc_fp64_vector3_reset(BGC_FP64_Vector3* const vector) { vector->x = 0.0; vector->y = 0.0; vector->z = 0.0; } // ==================== Set ===================== // inline void bgc_fp32_vector3_set_values(BGC_FP32_Vector3* const destination, const float x, const float y, const float z) { destination->x = x; destination->y = y; destination->z = z; } inline void bgc_fp64_vector3_set_values(BGC_FP64_Vector3* const destination, const double x, const double y, const double z) { destination->x = x; destination->y = y; destination->z = z; } // ================== Modulus =================== // inline float bgc_fp32_vector3_get_squared_length(const BGC_FP32_Vector3* const vector) { return vector->x * vector->x + vector->y * vector->y + vector->z * vector->z; } inline double bgc_fp64_vector3_get_squared_length(const BGC_FP64_Vector3* const vector) { return vector->x * vector->x + vector->y * vector->y + vector->z * vector->z; } inline float bgc_fp32_vector3_get_length(const BGC_FP32_Vector3* const vector) { return sqrtf(bgc_fp32_vector3_get_squared_length(vector)); } inline double bgc_fp64_vector3_get_length(const BGC_FP64_Vector3* const vector) { return sqrt(bgc_fp64_vector3_get_squared_length(vector)); } // ================= Comparison ================= // inline int bgc_fp32_vector3_is_zero(const BGC_FP32_Vector3* const vector) { return bgc_fp32_vector3_get_squared_length(vector) <= BGC_FP32_SQUARE_EPSILON; } inline int bgc_fp64_vector3_is_zero(const BGC_FP64_Vector3* const vector) { return bgc_fp64_vector3_get_squared_length(vector) <= BGC_FP64_SQUARE_EPSILON; } inline int bgc_fp32_vector3_is_unit(const BGC_FP32_Vector3* const vector) { return bgc_fp32_is_square_unit(bgc_fp32_vector3_get_squared_length(vector)); } inline int bgc_fp64_vector3_is_unit(const BGC_FP64_Vector3* const vector) { return bgc_fp64_is_square_unit(bgc_fp64_vector3_get_squared_length(vector)); } // ==================== Copy ==================== // inline void bgc_fp32_vector3_copy(BGC_FP32_Vector3* const destination, const BGC_FP32_Vector3* const source) { destination->x = source->x; destination->y = source->y; destination->z = source->z; } inline void bgc_fp64_vector3_copy(BGC_FP64_Vector3* const destination, const BGC_FP64_Vector3* const source) { destination->x = source->x; destination->y = source->y; destination->z = source->z; } // ==================== Swap ==================== // inline void bgc_fp32_vector3_swap(BGC_FP32_Vector3* const vector1, BGC_FP32_Vector3* const vector2) { const float x = vector2->x; const float y = vector2->y; const float z = vector2->z; vector2->x = vector1->x; vector2->y = vector1->y; vector2->z = vector1->z; vector1->x = x; vector1->y = y; vector1->z = z; } inline void bgc_fp64_vector3_swap(BGC_FP64_Vector3* const vector1, BGC_FP64_Vector3* const vector2) { const double x = vector2->x; const double y = vector2->y; const double z = vector2->z; vector2->x = vector1->x; vector2->y = vector1->y; vector2->z = vector1->z; vector1->x = x; vector1->y = y; vector1->z = z; } // ================== Convert =================== // inline void bgc_fp32_vector3_convert_to_fp64(BGC_FP64_Vector3* const destination, const BGC_FP32_Vector3* const source) { destination->x = source->x; destination->y = source->y; destination->z = source->z; } inline void bgc_fp64_vector3_convert_to_fp32(BGC_FP32_Vector3* const destination, const BGC_FP64_Vector3* const source) { destination->x = (float)source->x; destination->y = (float)source->y; destination->z = (float)source->z; } // ==================== Add ===================== // inline void bgc_fp32_vector3_add(BGC_FP32_Vector3* const sum, const BGC_FP32_Vector3* const vector1, const BGC_FP32_Vector3* const vector2) { sum->x = vector1->x + vector2->x; sum->y = vector1->y + vector2->y; sum->z = vector1->z + vector2->z; } inline void bgc_fp64_vector3_add(BGC_FP64_Vector3* const sum, const BGC_FP64_Vector3* const vector1, const BGC_FP64_Vector3* const vector2) { sum->x = vector1->x + vector2->x; sum->y = vector1->y + vector2->y; sum->z = vector1->z + vector2->z; } // ================= Add scaled ================= // inline void bgc_fp32_vector3_add_scaled(BGC_FP32_Vector3* const sum, const BGC_FP32_Vector3* const basic_vector, const BGC_FP32_Vector3* const scalable_vector, const float scale) { sum->x = basic_vector->x + scalable_vector->x * scale; sum->y = basic_vector->y + scalable_vector->y * scale; sum->z = basic_vector->z + scalable_vector->z * scale; } inline void bgc_fp64_vector3_add_scaled(BGC_FP64_Vector3* const sum, const BGC_FP64_Vector3* const basic_vector, const BGC_FP64_Vector3* const scalable_vector, const double scale) { sum->x = basic_vector->x + scalable_vector->x * scale; sum->y = basic_vector->y + scalable_vector->y * scale; sum->z = basic_vector->z + scalable_vector->z * scale; } // ================== Subtract ================== // inline void bgc_fp32_vector3_subtract(BGC_FP32_Vector3* const difference, const BGC_FP32_Vector3* const minuend, const BGC_FP32_Vector3* const subtrahend) { difference->x = minuend->x - subtrahend->x; difference->y = minuend->y - subtrahend->y; difference->z = minuend->z - subtrahend->z; } inline void bgc_fp64_vector3_subtract(BGC_FP64_Vector3* const difference, const BGC_FP64_Vector3* const minuend, const BGC_FP64_Vector3* const subtrahend) { difference->x = minuend->x - subtrahend->x; difference->y = minuend->y - subtrahend->y; difference->z = minuend->z - subtrahend->z; } // ============== Subtract Scaled =============== // inline void bgc_fp32_vector3_subtract_scaled(BGC_FP32_Vector3* const difference, const BGC_FP32_Vector3* const basic_vector, const BGC_FP32_Vector3* const scalable_vector, const float scale) { difference->x = basic_vector->x - scalable_vector->x * scale; difference->y = basic_vector->y - scalable_vector->y * scale; difference->z = basic_vector->z - scalable_vector->z * scale; } inline void bgc_fp64_vector3_subtract_scaled(BGC_FP64_Vector3* const difference, const BGC_FP64_Vector3* const basic_vector, const BGC_FP64_Vector3* const scalable_vector, const double scale) { difference->x = basic_vector->x - scalable_vector->x * scale; difference->y = basic_vector->y - scalable_vector->y * scale; difference->z = basic_vector->z - scalable_vector->z * scale; } // ================== Multiply ================== // inline void bgc_fp32_vector3_multiply_by_real_number(BGC_FP32_Vector3* const product, const BGC_FP32_Vector3* const multiplicand, const float multiplier) { product->x = multiplicand->x * multiplier; product->y = multiplicand->y * multiplier; product->z = multiplicand->z * multiplier; } inline void bgc_fp64_vector3_multiply_by_real_number(BGC_FP64_Vector3* const product, const BGC_FP64_Vector3* const multiplicand, const double multiplier) { product->x = multiplicand->x * multiplier; product->y = multiplicand->y * multiplier; product->z = multiplicand->z * multiplier; } // ========== Multiply by Dual Number =========== // inline void bgc_fp32_vector3_multiply_by_dual_number(BGC_FP32_DualVector3* const product, const BGC_FP32_Vector3* const multiplicand, const BGC_FP32_DualNumber* const multiplier) { const float real_x = multiplicand->x * multiplier->real_part; const float real_y = multiplicand->y * multiplier->real_part; const float real_z = multiplicand->z * multiplier->real_part; const float dual_x = multiplicand->x * multiplier->dual_part; const float dual_y = multiplicand->y * multiplier->dual_part; const float dual_z = multiplicand->z * multiplier->dual_part; product->real_part.x = real_x; product->real_part.y = real_y; product->real_part.z = real_z; product->dual_part.x = dual_x; product->dual_part.y = dual_y; product->dual_part.z = dual_z; } inline void bgc_fp64_vector3_multiply_by_dual_number(BGC_FP64_DualVector3* const product, const BGC_FP64_Vector3* const multiplicand, const BGC_FP64_DualNumber* const multiplier) { const double real_x = multiplicand->x * multiplier->real_part; const double real_y = multiplicand->y * multiplier->real_part; const double real_z = multiplicand->z * multiplier->real_part; const double dual_x = multiplicand->x * multiplier->dual_part; const double dual_y = multiplicand->y * multiplier->dual_part; const double dual_z = multiplicand->z * multiplier->dual_part; product->real_part.x = real_x; product->real_part.y = real_y; product->real_part.z = real_z; product->dual_part.x = dual_x; product->dual_part.y = dual_y; product->dual_part.z = dual_z; } // ====== Restrict Multiply by Dual Number ====== // inline void _bgc_fp32_restrict_vector3_multiply_by_dual_number(BGC_FP32_DualVector3* restrict const product, const BGC_FP32_Vector3* const multiplicand, const BGC_FP32_DualNumber* const multiplier) { product->real_part.x = multiplicand->x * multiplier->real_part; product->real_part.y = multiplicand->y * multiplier->real_part; product->real_part.z = multiplicand->z * multiplier->real_part; product->dual_part.x = multiplicand->x * multiplier->dual_part; product->dual_part.y = multiplicand->y * multiplier->dual_part; product->dual_part.z = multiplicand->z * multiplier->dual_part; } inline void _bgc_fp64_restrict_vector3_multiply_by_dual_number(BGC_FP64_DualVector3* restrict const product, const BGC_FP64_Vector3* const multiplicand, const BGC_FP64_DualNumber* const multiplier) { product->real_part.x = multiplicand->x * multiplier->real_part; product->real_part.y = multiplicand->y * multiplier->real_part; product->real_part.z = multiplicand->z * multiplier->real_part; product->dual_part.x = multiplicand->x * multiplier->dual_part; product->dual_part.y = multiplicand->y * multiplier->dual_part; product->dual_part.z = multiplicand->z * multiplier->dual_part; } // ============ Left Vector Product ============= // inline void bgc_fp32_vector3_multiply_by_matrix2x3(BGC_FP32_Vector2* const product, const BGC_FP32_Vector3* const vector, const BGC_FP32_Matrix2x3* const matrix) { product->x = vector->x * matrix->r1c1 + vector->y * matrix->r2c1 + vector->z * matrix->r3c1; product->y = vector->x * matrix->r1c2 + vector->y * matrix->r2c2 + vector->z * matrix->r3c2; } inline void bgc_fp64_vector3_multiply_by_matrix2x3(BGC_FP64_Vector2* const product, const BGC_FP64_Vector3* const vector, const BGC_FP64_Matrix2x3* const matrix) { product->x = vector->x * matrix->r1c1 + vector->y * matrix->r2c1 + vector->z * matrix->r3c1; product->y = vector->x * matrix->r1c2 + vector->y * matrix->r2c2 + vector->z * matrix->r3c2; } // ============ Left Vector Product ============= // inline void bgc_fp32_vector3_multiply_by_matrix3x3(BGC_FP32_Vector3* const product, const BGC_FP32_Vector3* const vector, const BGC_FP32_Matrix3x3* const matrix) { const float x = vector->x * matrix->r1c1 + vector->y * matrix->r2c1 + vector->z * matrix->r3c1; const float y = vector->x * matrix->r1c2 + vector->y * matrix->r2c2 + vector->z * matrix->r3c2; const float z = vector->x * matrix->r1c3 + vector->y * matrix->r2c3 + vector->z * matrix->r3c3; product->x = x; product->y = y; product->z = z; } inline void bgc_fp64_vector3_multiply_by_matrix3x3(BGC_FP64_Vector3* const product, const BGC_FP64_Vector3* const vector, const BGC_FP64_Matrix3x3* const matrix) { const double x = vector->x * matrix->r1c1 + vector->y * matrix->r2c1 + vector->z * matrix->r3c1; const double y = vector->x * matrix->r1c2 + vector->y * matrix->r2c2 + vector->z * matrix->r3c2; const double z = vector->x * matrix->r1c3 + vector->y * matrix->r2c3 + vector->z * matrix->r3c3; product->x = x; product->y = y; product->z = z; } // =================== Divide =================== // inline int bgc_fp32_vector3_divide_by_real_number(BGC_FP32_Vector3* const quotient, const BGC_FP32_Vector3* const dividend, const float divisor) { if (bgc_fp32_is_zero(divisor) || isnan(divisor)) { return BGC_FAILURE; } bgc_fp32_vector3_multiply_by_real_number(quotient, dividend, 1.0f / divisor); return BGC_SUCCESS; } inline int bgc_fp64_vector3_divide_by_real_number(BGC_FP64_Vector3* const quotient, const BGC_FP64_Vector3* const dividend, const double divisor) { if (bgc_fp64_is_zero(divisor) || isnan(divisor)) { return BGC_FAILURE; } bgc_fp64_vector3_multiply_by_real_number(quotient, dividend, 1.0 / divisor); return BGC_SUCCESS; } // ================== Average2 ================== // inline void bgc_fp32_vector3_get_mean2(BGC_FP32_Vector3* const mean, const BGC_FP32_Vector3* const vector1, const BGC_FP32_Vector3* const vector2) { mean->x = (vector1->x + vector2->x) * 0.5f; mean->y = (vector1->y + vector2->y) * 0.5f; mean->z = (vector1->z + vector2->z) * 0.5f; } inline void bgc_fp64_vector3_get_mean2(BGC_FP64_Vector3* const mean, const BGC_FP64_Vector3* const vector1, const BGC_FP64_Vector3* const vector2) { mean->x = (vector1->x + vector2->x) * 0.5; mean->y = (vector1->y + vector2->y) * 0.5; mean->z = (vector1->z + vector2->z) * 0.5; } // ================== Average3 ================== // inline void bgc_fp32_vector3_get_mean3(BGC_FP32_Vector3* const mean, const BGC_FP32_Vector3* const vector1, const BGC_FP32_Vector3* const vector2, const BGC_FP32_Vector3* const vector3) { mean->x = (vector1->x + vector2->x + vector3->x) * BGC_FP32_ONE_THIRD; mean->y = (vector1->y + vector2->y + vector3->y) * BGC_FP32_ONE_THIRD; mean->z = (vector1->z + vector2->z + vector3->z) * BGC_FP32_ONE_THIRD; } inline void bgc_fp64_vector3_get_mean3(BGC_FP64_Vector3* const mean, const BGC_FP64_Vector3* const vector1, const BGC_FP64_Vector3* const vector2, const BGC_FP64_Vector3* const vector3) { mean->x = (vector1->x + vector2->x + vector3->x) * BGC_FP64_ONE_THIRD; mean->y = (vector1->y + vector2->y + vector3->y) * BGC_FP64_ONE_THIRD; mean->z = (vector1->z + vector2->z + vector3->z) * BGC_FP64_ONE_THIRD; } // =================== Linear =================== // inline void bgc_fp32_vector3_interpolate(BGC_FP32_Vector3* const interpolation, const BGC_FP32_Vector3* const first, const BGC_FP32_Vector3* const second, const float phase) { const float counter_phase = 1.0f - phase; interpolation->x = first->x * counter_phase + second->x * phase; interpolation->y = first->y * counter_phase + second->y * phase; interpolation->z = first->z * counter_phase + second->z * phase; } inline void bgc_fp64_vector3_interpolate(BGC_FP64_Vector3* const interpolation, const BGC_FP64_Vector3* const first, const BGC_FP64_Vector3* const second, const double phase) { const double counter_phase = 1.0 - phase; interpolation->x = first->x * counter_phase + second->x * phase; interpolation->y = first->y * counter_phase + second->y * phase; interpolation->z = first->z * counter_phase + second->z * phase; } // ================== Negative ================== // inline void bgc_fp32_vector3_revert(BGC_FP32_Vector3* const vector) { vector->x = -vector->x; vector->y = -vector->y; vector->z = -vector->z; } inline void bgc_fp64_vector3_revert(BGC_FP64_Vector3* const vector) { vector->x = -vector->x; vector->y = -vector->y; vector->z = -vector->z; } inline void bgc_fp32_vector3_get_reverse(BGC_FP32_Vector3* const reverse, const BGC_FP32_Vector3* const vector) { reverse->x = -vector->x; reverse->y = -vector->y; reverse->z = -vector->z; } inline void bgc_fp64_vector3_get_reverse(BGC_FP64_Vector3* const reverse, const BGC_FP64_Vector3* const vector) { reverse->x = -vector->x; reverse->y = -vector->y; reverse->z = -vector->z; } // ================= Normalize ================== // inline int bgc_fp32_vector3_normalize(BGC_FP32_Vector3* const vector) { const float square_modulus = bgc_fp32_vector3_get_squared_length(vector); if (square_modulus <= BGC_FP32_SQUARE_EPSILON || isnan(square_modulus)) { return BGC_FAILURE; } if (bgc_fp32_is_square_unit(square_modulus)) { return BGC_SUCCESS; } const float multiplier = sqrtf(1.0f / square_modulus); vector->x *= multiplier; vector->y *= multiplier; vector->z *= multiplier; return BGC_SUCCESS; } inline int bgc_fp64_vector3_normalize(BGC_FP64_Vector3* const vector) { const double square_modulus = bgc_fp64_vector3_get_squared_length(vector); if (square_modulus <= BGC_FP64_SQUARE_EPSILON || isnan(square_modulus)) { return BGC_FAILURE; } if (bgc_fp64_is_square_unit(square_modulus)) { return BGC_SUCCESS; } const double multiplier = sqrt(1.0 / square_modulus); vector->x *= multiplier; vector->y *= multiplier; vector->z *= multiplier; return BGC_SUCCESS; } inline int bgc_fp32_vector3_get_normalized(BGC_FP32_Vector3* const normalized, const BGC_FP32_Vector3* const vector) { const float square_modulus = bgc_fp32_vector3_get_squared_length(vector); if (square_modulus <= BGC_FP32_SQUARE_EPSILON || isnan(square_modulus)) { bgc_fp32_vector3_reset(normalized); return BGC_FAILURE; } if (bgc_fp32_is_square_unit(square_modulus)) { bgc_fp32_vector3_copy(normalized, vector); return BGC_SUCCESS; } bgc_fp32_vector3_multiply_by_real_number(normalized, vector, sqrtf(1.0f / square_modulus)); return BGC_SUCCESS; } inline int bgc_fp64_vector3_get_normalized(BGC_FP64_Vector3* const normalized, const BGC_FP64_Vector3* const vector) { const double square_modulus = bgc_fp64_vector3_get_squared_length(vector); if (square_modulus <= BGC_FP64_SQUARE_EPSILON || isnan(square_modulus)) { bgc_fp64_vector3_reset(normalized); return BGC_FAILURE; } if (bgc_fp64_is_square_unit(square_modulus)) { bgc_fp64_vector3_copy(normalized, vector); return BGC_SUCCESS; } bgc_fp64_vector3_multiply_by_real_number(normalized, vector, sqrt(1.0 / square_modulus)); return BGC_SUCCESS; } // =============== Scalar Product =============== // inline float bgc_fp32_vector3_get_dot_product(const BGC_FP32_Vector3* const vector1, const BGC_FP32_Vector3* const vector2) { return vector1->x * vector2->x + vector1->y * vector2->y + vector1->z * vector2->z; } inline double bgc_fp64_vector3_get_dot_product(const BGC_FP64_Vector3* const vector1, const BGC_FP64_Vector3* const vector2) { return vector1->x * vector2->x + vector1->y * vector2->y + vector1->z * vector2->z; } // =============== Triple Product =============== // inline float bgc_fp32_vector3_get_triple_product(const BGC_FP32_Vector3* const vector1, const BGC_FP32_Vector3* const vector2, const BGC_FP32_Vector3* const vector3) { return vector1->x * (vector2->y * vector3->z - vector2->z * vector3->y) + vector1->y * (vector2->z * vector3->x - vector2->x * vector3->z) + vector1->z * (vector2->x * vector3->y - vector2->y * vector3->x); } inline double bgc_fp64_vector3_get_triple_product(const BGC_FP64_Vector3* const vector1, const BGC_FP64_Vector3* const vector2, const BGC_FP64_Vector3* const vector3) { return vector1->x * (vector2->y * vector3->z - vector2->z * vector3->y) + vector1->y * (vector2->z * vector3->x - vector2->x * vector3->z) + vector1->z * (vector2->x * vector3->y - vector2->y * vector3->x); } // =========== Restrict Cross Product =========== // inline void _bgc_fp32_restrict_vector3_get_cross_product(BGC_FP32_Vector3* restrict const product, const BGC_FP32_Vector3* const vector1, const BGC_FP32_Vector3* const vector2) { product->x = vector1->y * vector2->z - vector1->z * vector2->y; product->y = vector1->z * vector2->x - vector1->x * vector2->z; product->z = vector1->x * vector2->y - vector1->y * vector2->x; } inline void _bgc_fp64_restrict_vector3_get_cross_product(BGC_FP64_Vector3* restrict const product, const BGC_FP64_Vector3* const vector1, const BGC_FP64_Vector3* const vector2) { product->x = vector1->y * vector2->z - vector1->z * vector2->y; product->y = vector1->z * vector2->x - vector1->x * vector2->z; product->z = vector1->x * vector2->y - vector1->y * vector2->x; } // =============== Cross Product ================ // inline void bgc_fp32_vector3_get_cross_product(BGC_FP32_Vector3* const product, const BGC_FP32_Vector3* const vector1, const BGC_FP32_Vector3* const vector2) { const float x = vector1->y * vector2->z - vector1->z * vector2->y; const float y = vector1->z * vector2->x - vector1->x * vector2->z; const float z = vector1->x * vector2->y - vector1->y * vector2->x; product->x = x; product->y = y; product->z = z; } inline void bgc_fp64_vector3_get_cross_product(BGC_FP64_Vector3* const product, const BGC_FP64_Vector3* const vector1, const BGC_FP64_Vector3* const vector2) { const double x = vector1->y * vector2->z - vector1->z * vector2->y; const double y = vector1->z * vector2->x - vector1->x * vector2->z; const double z = vector1->x * vector2->y - vector1->y * vector2->x; product->x = x; product->y = y; product->z = z; } // ============ Double Cross Product ============ // // [a x [b x c]] = b * (a, c) - c * (a, b) inline void bgc_fp32_vector3_get_double_cross(BGC_FP32_Vector3* const product, const BGC_FP32_Vector3* const vector1, const BGC_FP32_Vector3* const vector2, const BGC_FP32_Vector3* const vector3) { const float ac = bgc_fp32_vector3_get_dot_product(vector1, vector3); const float ab = bgc_fp32_vector3_get_dot_product(vector1, vector2); product->x = vector2->x * ac - vector3->x * ab; product->y = vector2->y * ac - vector3->y * ab; product->z = vector2->z * ac - vector3->z * ab; } // [a x [b x c]] = b * (a, c) - c * (a, b) inline void bgc_fp64_vector3_get_double_cross(BGC_FP64_Vector3* const product, const BGC_FP64_Vector3* const vector1, const BGC_FP64_Vector3* const vector2, const BGC_FP64_Vector3* const vector3) { const double ac = bgc_fp64_vector3_get_dot_product(vector1, vector3); const double ab = bgc_fp64_vector3_get_dot_product(vector1, vector2); product->x = vector2->x * ac - vector3->x * ab; product->y = vector2->y * ac - vector3->y * ab; product->z = vector2->z * ac - vector3->z * ab; } // ====== Alternative Double Cross Product ====== // // [[a x b] x c] = - [c x [a x b]] = -(a * (c, b) - b * (c, a)) = b * (a, c) - a * (b, c) inline void bgc_fp32_vector3_get_alternative_double_cross(BGC_FP32_Vector3* const product, const BGC_FP32_Vector3* const vector1, const BGC_FP32_Vector3* const vector2, const BGC_FP32_Vector3* const vector3) { const float ac = bgc_fp32_vector3_get_dot_product(vector1, vector3); const float bc = bgc_fp32_vector3_get_dot_product(vector2, vector3); product->x = vector2->x * ac - vector1->x * bc; product->y = vector2->y * ac - vector1->y * bc; product->z = vector2->z * ac - vector1->z * bc; } // [[a x b] x c] = - [c x [a x b]] = -(a * (b, c) - b * (a, c)) = b * (a, c) - a * (b, c) inline void bgc_fp64_vector3_get_alternative_double_cross(BGC_FP64_Vector3* const product, const BGC_FP64_Vector3* const vector1, const BGC_FP64_Vector3* const vector2, const BGC_FP64_Vector3* const vector3) { const double ac = bgc_fp64_vector3_get_dot_product(vector1, vector3); const double bc = bgc_fp64_vector3_get_dot_product(vector2, vector3); product->x = vector2->x * ac - vector1->x * bc; product->y = vector2->y * ac - vector1->y * bc; product->z = vector2->z * ac - vector1->z * bc; } // =================== Angle ==================== // float bgc_fp32_vector3_get_angle(const BGC_FP32_Vector3* const vector1, const BGC_FP32_Vector3* const vector2, const int angle_unit); double bgc_fp64_vector3_get_angle(const BGC_FP64_Vector3* const vector1, const BGC_FP64_Vector3* const vector2, const int angle_unit); // =============== Square Distance ============== // inline float bgc_fp32_vector3_get_square_distance(const BGC_FP32_Vector3* const vector1, const BGC_FP32_Vector3* const vector2) { const float dx = (vector1->x - vector2->x); const float dy = (vector1->y - vector2->y); const float dz = (vector1->z - vector2->z); return dx * dx + dy * dy + dz * dz; } inline double bgc_fp64_vector3_get_square_distance(const BGC_FP64_Vector3* const vector1, const BGC_FP64_Vector3* const vector2) { const double dx = (vector1->x - vector2->x); const double dy = (vector1->y - vector2->y); const double dz = (vector1->z - vector2->z); return dx * dx + dy * dy + dz * dz; } // ================== Distance ================== // inline float bgc_fp32_vector3_get_distance(const BGC_FP32_Vector3* const vector1, const BGC_FP32_Vector3* const vector2) { return sqrtf(bgc_fp32_vector3_get_square_distance(vector1, vector2)); } inline double bgc_fp64_vector3_get_distance(const BGC_FP64_Vector3* const vector1, const BGC_FP64_Vector3* const 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* const vector1, const BGC_FP32_Vector3* const 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* const vector1, const BGC_FP64_Vector3* const 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* const vector1, const BGC_FP32_Vector3* const vector2) { const float square_modulus1 = bgc_fp32_vector3_get_squared_length(vector1); const float square_modulus2 = bgc_fp32_vector3_get_squared_length(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* const vector1, const BGC_FP64_Vector3* const vector2) { const double square_modulus1 = bgc_fp64_vector3_get_squared_length(vector1); const double square_modulus2 = bgc_fp64_vector3_get_squared_length(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* const vector1, const BGC_FP32_Vector3* const vector2) { const float square_modulus1 = bgc_fp32_vector3_get_squared_length(vector1); const float square_modulus2 = bgc_fp32_vector3_get_squared_length(vector2); if (square_modulus1 <= BGC_FP32_SQUARE_EPSILON || square_modulus2 <= BGC_FP32_SQUARE_EPSILON) { return 1; } BGC_FP32_Vector3 product; _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; } inline int bgc_fp64_vector3_are_parallel(const BGC_FP64_Vector3* const vector1, const BGC_FP64_Vector3* const vector2) { const double square_modulus1 = bgc_fp64_vector3_get_squared_length(vector1); const double square_modulus2 = bgc_fp64_vector3_get_squared_length(vector2); if (square_modulus1 <= BGC_FP64_SQUARE_EPSILON || square_modulus2 <= BGC_FP64_SQUARE_EPSILON) { return 1; } BGC_FP64_Vector3 product; _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; } // ================= Orthogonal ================= // inline int bgc_fp32_vector3_are_orthogonal(const BGC_FP32_Vector3* const vector1, const BGC_FP32_Vector3* const vector2) { const float square_modulus1 = bgc_fp32_vector3_get_squared_length(vector1); const float square_modulus2 = bgc_fp32_vector3_get_squared_length(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* const vector1, const BGC_FP64_Vector3* const vector2) { const double square_modulus1 = bgc_fp64_vector3_get_squared_length(vector1); const double square_modulus2 = bgc_fp64_vector3_get_squared_length(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 ================== // int bgc_fp32_vector3_get_attitude(const BGC_FP32_Vector3* const vector1, const BGC_FP32_Vector3* const vector2); int bgc_fp64_vector3_get_attitude(const BGC_FP64_Vector3* const vector1, const BGC_FP64_Vector3* const vector2); #endif