Переименование tangent pair в числа Котса, выделение комплексных чисел из двумерных векторов, добавление возведения в спебень для веросорв и чисел Котса

This commit is contained in:
Andrey Pokidov 2025-02-26 16:27:33 +07:00
parent 34ee460873
commit 74be89f1f8
17 changed files with 1233 additions and 646 deletions

View file

@ -48,6 +48,14 @@
</Unit>
<Unit filename="angle.h" />
<Unit filename="basic-geometry.h" />
<Unit filename="complex.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="complex.h" />
<Unit filename="cotes-number.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="cotes-number.h" />
<Unit filename="matrix2x2.c">
<Option compilerVar="CC" />
</Unit>
@ -76,10 +84,6 @@
<Option compilerVar="CC" />
</Unit>
<Unit filename="rotation3.h" />
<Unit filename="tangent-pair.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="tangent-pair.h" />
<Unit filename="utilities.c">
<Option compilerVar="CC" />
</Unit>

View file

@ -1,24 +1,25 @@
#ifndef _BGC_H_
#define _BGC_H_
#include "utilities.h"
#include "./utilities.h"
#include "angle.h"
#include "./angle.h"
#include "vector2.h"
#include "vector3.h"
#include "./vector2.h"
#include "./vector3.h"
#include "matrixes.h"
#include "matrix2x2.h"
#include "matrix2x3.h"
#include "matrix3x2.h"
#include "matrix3x3.h"
#include "./matrixes.h"
#include "./matrix2x2.h"
#include "./matrix2x3.h"
#include "./matrix3x2.h"
#include "./matrix3x3.h"
#include "./complex.h"
#include "./cotes-number.h"
#include "tangent-pair.h"
#include "./rotation3.h"
#include "rotation3.h"
#include "quaternion.h"
#include "versor.h"
#include "./quaternion.h"
#include "./versor.h"
#endif

View file

@ -21,6 +21,8 @@
<ItemGroup>
<ClInclude Include="angle.h" />
<ClInclude Include="basic-geometry.h" />
<ClInclude Include="complex.h" />
<ClInclude Include="cotes-number.h" />
<ClInclude Include="matrix2x2.h" />
<ClInclude Include="matrix2x3.h" />
<ClInclude Include="matrix3x2.h" />
@ -28,7 +30,6 @@
<ClInclude Include="matrixes.h" />
<ClInclude Include="quaternion.h" />
<ClInclude Include="rotation3.h" />
<ClInclude Include="tangent-pair.h" />
<ClInclude Include="utilities.h" />
<ClInclude Include="versor.h" />
<ClInclude Include="vector2.h" />
@ -36,6 +37,8 @@
</ItemGroup>
<ItemGroup>
<ClCompile Include="angle.c" />
<ClInclude Include="complex.c" />
<ClInclude Include="cotes-number.c" />
<ClCompile Include="utilities.c" />
<ClCompile Include="matrix2x2.c" />
<ClCompile Include="matrix2x3.c" />
@ -44,7 +47,7 @@
<ClCompile Include="matrixes.c" />
<ClCompile Include="quaternion.c" />
<ClCompile Include="rotation3.c" />
<ClCompile Include="tangent-pair.c" />
<ClCompile Include="cotes-number.c" />
<ClCompile Include="versor.c" />
<ClCompile Include="vector2.c" />
<ClCompile Include="vector3.c" />

View file

@ -18,6 +18,12 @@
<ClInclude Include="angle.h">
<Filter>Файлы заголовков</Filter>
</ClInclude>
<ClInclude Include="complex.h">
<Filter>Файлы заголовков</Filter>
</ClInclude>
<ClInclude Include="cotes-number.h">
<Filter>Файлы заголовков</Filter>
</ClInclude>
<ClInclude Include="utilities.h">
<Filter>Файлы заголовков</Filter>
</ClInclude>
@ -54,14 +60,17 @@
<ClInclude Include="matrixes.h">
<Filter>Файлы заголовков</Filter>
</ClInclude>
<ClInclude Include="tangent-pair.h">
<Filter>Файлы заголовков</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="angle.c">
<Filter>Исходные файлы</Filter>
</ClCompile>
<ClCompile Include="complex.c">
<Filter>Исходные файлы</Filter>
</ClCompile>
<ClCompile Include="cotes-number.c">
<Filter>Исходные файлы</Filter>
</ClCompile>
<ClCompile Include="utilities.c">
<Filter>Исходные файлы</Filter>
</ClCompile>
@ -95,8 +104,5 @@
<ClCompile Include="matrix3x2.c">
<Filter>Исходные файлы</Filter>
</ClCompile>
<ClCompile Include="tangent-pair.c">
<Filter>Исходные файлы</Filter>
</ClCompile>
</ItemGroup>
</Project>

124
basic-geometry/complex.c Normal file
View file

@ -0,0 +1,124 @@
#include "./complex.h"
extern inline void bgc_complex_reset_fp32(BgcComplexFP32* complex);
extern inline void bgc_complex_reset_fp64(BgcComplexFP64* complex);
extern inline void bgc_complex_set_values_fp32(const float real, const float imaginary, BgcComplexFP32* destination);
extern inline void bgc_complex_set_values_fp64(const double real, const double imaginary, BgcComplexFP64* destination);
extern inline float bgc_complex_get_square_modulus_fp32(const BgcComplexFP32* number);
extern inline double bgc_complex_get_square_modulus_fp64(const BgcComplexFP64* number);
extern inline float bgc_complex_get_modulus_fp32(const BgcComplexFP32* number);
extern inline double bgc_complex_get_modulus_fp64(const BgcComplexFP64* number);
extern inline int bgc_complex_is_zero_fp32(const BgcComplexFP32* number);
extern inline int bgc_complex_is_zero_fp64(const BgcComplexFP64* number);
extern inline int bgc_complex_is_unit_fp32(const BgcComplexFP32* number);
extern inline int bgc_complex_is_unit_fp64(const BgcComplexFP64* number);
extern inline void bgc_complex_copy_fp32(const BgcComplexFP32* source, BgcComplexFP32* destination);
extern inline void bgc_complex_copy_fp64(const BgcComplexFP64* source, BgcComplexFP64* destination);
extern inline void bgc_complex_swap_fp32(BgcComplexFP32* number1, BgcComplexFP32* number2);
extern inline void bgc_complex_swap_fp64(BgcComplexFP64* number1, BgcComplexFP64* number2);
extern inline void bgc_complex_convert_fp64_to_fp32(const BgcComplexFP64* source, BgcComplexFP32* destination);
extern inline void bgc_complex_convert_fp32_to_fp64(const BgcComplexFP32* source, BgcComplexFP64* destination);
extern inline void bgc_complex_reverse_fp32(const BgcComplexFP32* number, BgcComplexFP32* reverse);
extern inline void bgc_complex_reverse_fp64(const BgcComplexFP64* number, BgcComplexFP64* reverse);
extern inline int bgc_complex_normalize_fp32(const BgcComplexFP32* number, BgcComplexFP32* normalized);
extern inline int bgc_complex_normalize_fp64(const BgcComplexFP64* number, BgcComplexFP64* normalized);
extern inline void bgc_complex_conjugate_fp32(const BgcComplexFP32* number, BgcComplexFP32* conjugate);
extern inline void bgc_complex_conjugate_fp64(const BgcComplexFP64* number, BgcComplexFP64* conjugate);
extern inline int bgc_complex_invert_fp32(const BgcComplexFP32* number, BgcComplexFP32* inverted);
extern inline int bgc_complex_invert_fp64(const BgcComplexFP64* number, BgcComplexFP64* inverted);
extern inline void bgc_complex_get_product_fp32(const BgcComplexFP32* number1, const BgcComplexFP32* number2, BgcComplexFP32* result);
extern inline void bgc_complex_get_product_fp64(const BgcComplexFP64* number1, const BgcComplexFP64* number2, BgcComplexFP64* result);
extern inline int bgc_complex_get_ratio_fp32(const BgcComplexFP32* divident, const BgcComplexFP32* divisor, BgcComplexFP32* quotient);
extern inline int bgc_complex_get_ratio_fp64(const BgcComplexFP64* divident, const BgcComplexFP64* divisor, BgcComplexFP64* quotient);
extern inline void bgc_complex_add_fp32(const BgcComplexFP32* number1, const BgcComplexFP32* number2, BgcComplexFP32* sum);
extern inline void bgc_complex_add_fp64(const BgcComplexFP64* number1, const BgcComplexFP64* number2, BgcComplexFP64* sum);
extern inline void bgc_complex_add_scaled_fp32(const BgcComplexFP32* basic_number, const BgcComplexFP32* scalable_number, const float scale, BgcComplexFP32* sum);
extern inline void bgc_complex_add_scaled_fp64(const BgcComplexFP64* basic_number, const BgcComplexFP64* scalable_number, const double scale, BgcComplexFP64* sum);
extern inline void bgc_complex_subtract_fp32(const BgcComplexFP32* minuend, const BgcComplexFP32* subtrahend, BgcComplexFP32* difference);
extern inline void bgc_complex_subtract_fp64(const BgcComplexFP64* minuend, const BgcComplexFP64* subtrahend, BgcComplexFP64* difference);
extern inline void bgc_complex_subtract_scaled_fp32(const BgcComplexFP32* basic_number, const BgcComplexFP32* scalable_number, const float scale, BgcComplexFP32* difference);
extern inline void bgc_complex_subtract_scaled_fp64(const BgcComplexFP64* basic_number, const BgcComplexFP64* scalable_number, const double scale, BgcComplexFP64* difference);
extern inline void bgc_complex_multiply_fp32(const BgcComplexFP32* multiplicand, const float multiplier, BgcComplexFP32* product);
extern inline void bgc_complex_multiply_fp64(const BgcComplexFP64* multiplicand, const double multiplier, BgcComplexFP64* product);
extern inline void bgc_complex_divide_fp32(const BgcComplexFP32* dividend, const float divisor, BgcComplexFP32* quotient);
extern inline void bgc_complex_divide_fp64(const BgcComplexFP64* dividend, const double divisor, BgcComplexFP64* quotient);
extern inline void bgc_complex_get_mean_of_two_fp32(const BgcComplexFP32* number1, const BgcComplexFP32* number2, BgcComplexFP32* mean);
extern inline void bgc_complex_get_mean_of_two_fp64(const BgcComplexFP64* number1, const BgcComplexFP64* number2, BgcComplexFP64* mean);
extern inline void bgc_complex_get_mean_of_three_fp32(const BgcComplexFP32* number1, const BgcComplexFP32* number2, const BgcComplexFP32* number3, BgcComplexFP32* mean);
extern inline void bgc_complex_get_mean_of_three_fp64(const BgcComplexFP64* number1, const BgcComplexFP64* number2, const BgcComplexFP64* number3, BgcComplexFP64* mean);
extern inline void bgc_complex_get_linear_interpolation_fp32(const BgcComplexFP32* number1, const BgcComplexFP32* number2, const float phase, BgcComplexFP32* interpolation);
extern inline void bgc_complex_get_linear_interpolation_fp64(const BgcComplexFP64* number1, const BgcComplexFP64* number2, const double phase, BgcComplexFP64* interpolation);
extern inline void bgc_complex_minimize_fp32(const BgcComplexFP32* number, BgcComplexFP32* minimal);
extern inline void bgc_complex_minimize_fp64(const BgcComplexFP64* number, BgcComplexFP64* minimal);
extern inline void bgc_complex_maximize_fp32(const BgcComplexFP32* number, BgcComplexFP32* maximal);
extern inline void bgc_complex_maximize_fp64(const BgcComplexFP64* number, BgcComplexFP64* maximal);
extern inline int bgc_complex_are_close_fp32(const BgcComplexFP32* number1, const BgcComplexFP32* number2);
extern inline int bgc_complex_are_close_fp64(const BgcComplexFP64* number1, const BgcComplexFP64* number2);
// =============== Get Exponation =============== //
void bgc_complex_get_exponation_fp32(const BgcComplexFP32* base, const float real_exponent, const float imaginary_exponent, BgcComplexFP32* power)
{
const float square_modulus = bgc_complex_get_square_modulus_fp32(base);
if (square_modulus <= BGC_SQUARE_EPSYLON_FP32) {
power->real = 0.0f;
power->imaginary = 0.0f;
return;
}
const float log_modulus = logf(square_modulus) * 0.5f;
const float angle = atan2f(base->imaginary, base->real);
const float power_modulus = expf(real_exponent * log_modulus - imaginary_exponent * angle);
const float power_angle = real_exponent * angle + imaginary_exponent * log_modulus;
power->real = power_modulus * cosf(power_angle);
power->imaginary = power_modulus * sinf(power_angle);
}
void bgc_complex_get_exponation_fp64(const BgcComplexFP64* base, const double real_exponent, const double imaginary_exponent, BgcComplexFP64* power)
{
const double square_modulus = bgc_complex_get_square_modulus_fp64(base);
if (square_modulus <= BGC_SQUARE_EPSYLON_FP64) {
power->real = 0.0;
power->imaginary = 0.0;
return;
}
const double log_modulus = log(square_modulus) * 0.5;
const double angle = atan2(base->imaginary, base->real);
const double power_modulus = exp(real_exponent * log_modulus - imaginary_exponent * angle);
const double power_angle = real_exponent * angle + imaginary_exponent * log_modulus;
power->real = power_modulus * cos(power_angle);
power->imaginary = power_modulus * sin(power_angle);
}

531
basic-geometry/complex.h Normal file
View file

@ -0,0 +1,531 @@
#ifndef _BGC_COMPLEX_H_
#define _BGC_COMPLEX_H_
#include "utilities.h"
#include "angle.h"
#include <math.h>
typedef struct
{
float real, imaginary;
} BgcComplexFP32;
typedef struct
{
double real, imaginary;
} BgcComplexFP64;
// =================== Reset ==================== //
inline void bgc_complex_reset_fp32(BgcComplexFP32* complex)
{
complex->real = 0.0f;
complex->imaginary = 0.0f;
}
inline void bgc_complex_reset_fp64(BgcComplexFP64* complex)
{
complex->real = 0.0;
complex->imaginary = 0.0;
}
// ==================== Set ===================== //
inline void bgc_complex_set_values_fp32(const float real, const float imaginary, BgcComplexFP32* destination)
{
destination->real = real;
destination->imaginary = imaginary;
}
inline void bgc_complex_set_values_fp64(const double real, const double imaginary, BgcComplexFP64* destination)
{
destination->real = real;
destination->imaginary = imaginary;
}
// ================== Modulus =================== //
inline float bgc_complex_get_square_modulus_fp32(const BgcComplexFP32* number)
{
return number->real * number->real + number->imaginary * number->imaginary;
}
inline double bgc_complex_get_square_modulus_fp64(const BgcComplexFP64* number)
{
return number->real * number->real + number->imaginary * number->imaginary;
}
inline float bgc_complex_get_modulus_fp32(const BgcComplexFP32* number)
{
return sqrtf(bgc_complex_get_square_modulus_fp32(number));
}
inline double bgc_complex_get_modulus_fp64(const BgcComplexFP64* number)
{
return sqrt(bgc_complex_get_square_modulus_fp64(number));
}
// ================= Comparison ================= //
inline int bgc_complex_is_zero_fp32(const BgcComplexFP32* number)
{
return bgc_complex_get_square_modulus_fp32(number) <= BGC_SQUARE_EPSYLON_FP32;
}
inline int bgc_complex_is_zero_fp64(const BgcComplexFP64* number)
{
return bgc_complex_get_square_modulus_fp64(number) <= BGC_SQUARE_EPSYLON_FP64;
}
inline int bgc_complex_is_unit_fp32(const BgcComplexFP32* number)
{
return bgc_is_sqare_unit_fp32(bgc_complex_get_square_modulus_fp32(number));
}
inline int bgc_complex_is_unit_fp64(const BgcComplexFP64* number)
{
return bgc_is_sqare_unit_fp64(bgc_complex_get_square_modulus_fp64(number));
}
// ==================== Copy ==================== //
inline void bgc_complex_copy_fp32(const BgcComplexFP32* source, BgcComplexFP32* destination)
{
destination->real = source->real;
destination->imaginary = source->imaginary;
}
inline void bgc_complex_copy_fp64(const BgcComplexFP64* source, BgcComplexFP64* destination)
{
destination->real = source->real;
destination->imaginary = source->imaginary;
}
// ==================== Swap ==================== //
inline void bgc_complex_swap_fp32(BgcComplexFP32* number1, BgcComplexFP32* number2)
{
const float real = number2->real;
const float imaginary = number2->imaginary;
number2->real = number1->real;
number2->imaginary = number1->imaginary;
number1->real = real;
number1->imaginary = imaginary;
}
inline void bgc_complex_swap_fp64(BgcComplexFP64* number1, BgcComplexFP64* number2)
{
const double real = number2->real;
const double imaginary = number2->imaginary;
number2->real = number1->real;
number2->imaginary = number1->imaginary;
number1->real = real;
number1->imaginary = imaginary;
}
// ================== Convert =================== //
inline void bgc_complex_convert_fp64_to_fp32(const BgcComplexFP64* source, BgcComplexFP32* destination)
{
destination->real = (float)source->real;
destination->imaginary = (float)source->imaginary;
}
inline void bgc_complex_convert_fp32_to_fp64(const BgcComplexFP32* source, BgcComplexFP64* destination)
{
destination->real = source->real;
destination->imaginary = source->imaginary;
}
// ================== Reverse =================== //
inline void bgc_complex_reverse_fp32(const BgcComplexFP32* number, BgcComplexFP32* reverse)
{
reverse->real = -number->real;
reverse->imaginary = -number->imaginary;
}
inline void bgc_complex_reverse_fp64(const BgcComplexFP64* number, BgcComplexFP64* reverse)
{
reverse->real = -number->real;
reverse->imaginary = -number->imaginary;
}
// ================= Normalize ================== //
inline int bgc_complex_normalize_fp32(const BgcComplexFP32* number, BgcComplexFP32* normalized)
{
const float square_modulus = bgc_complex_get_square_modulus_fp32(number);
if (bgc_is_sqare_unit_fp32(square_modulus)) {
normalized->real = number->real;
normalized->imaginary = number->imaginary;
return 1;
}
if (square_modulus <= BGC_SQUARE_EPSYLON_FP32 || square_modulus != square_modulus) {
return 0;
}
const float multiplicand = sqrtf(1.0f / square_modulus);
normalized->real = number->real * multiplicand;
normalized->imaginary = number->imaginary * multiplicand;
return 1;
}
inline int bgc_complex_normalize_fp64(const BgcComplexFP64* number, BgcComplexFP64* normalized)
{
const double square_modulus = bgc_complex_get_square_modulus_fp64(number);
if (bgc_is_sqare_unit_fp64(square_modulus)) {
normalized->real = number->real;
normalized->imaginary = number->imaginary;
return 1;
}
if (square_modulus <= BGC_SQUARE_EPSYLON_FP64 || square_modulus != square_modulus) {
return 0;
}
const double multiplicand = sqrt(1.0 / square_modulus);
normalized->real = number->real * multiplicand;
normalized->imaginary = number->imaginary * multiplicand;
return 1;
}
// ================= Conjugate ================== //
inline void bgc_complex_conjugate_fp32(const BgcComplexFP32* number, BgcComplexFP32* conjugate)
{
conjugate->real = number->real;
conjugate->imaginary = -number->imaginary;
}
inline void bgc_complex_conjugate_fp64(const BgcComplexFP64* number, BgcComplexFP64* conjugate)
{
conjugate->real = number->real;
conjugate->imaginary = -number->imaginary;
}
// =================== Invert =================== //
inline int bgc_complex_invert_fp32(const BgcComplexFP32* number, BgcComplexFP32* inverted)
{
const float square_modulus = bgc_complex_get_square_modulus_fp32(number);
if (square_modulus <= BGC_SQUARE_EPSYLON_FP32 || square_modulus != square_modulus) {
return 0;
}
const float multiplicand = 1.0f / square_modulus;
inverted->real = number->real * multiplicand;
inverted->imaginary = -number->imaginary * multiplicand;
return 1;
}
inline int bgc_complex_invert_fp64(const BgcComplexFP64* number, BgcComplexFP64* inverted)
{
const double square_modulus = bgc_complex_get_square_modulus_fp64(number);
if (square_modulus <= BGC_SQUARE_EPSYLON_FP64 || square_modulus != square_modulus) {
return 0;
}
const double multiplicand = 1.0 / square_modulus;
inverted->real = number->real * multiplicand;
inverted->imaginary = -number->imaginary * multiplicand;
return 1;
}
// ================ Get Product ================= //
inline void bgc_complex_get_product_fp32(const BgcComplexFP32* number1, const BgcComplexFP32* number2, BgcComplexFP32* result)
{
const float real = number1->real * number2->real - number1->imaginary * number2->imaginary;
const float imaginary = number1->real * number2->imaginary + number1->imaginary * number2->real;
result->real = real;
result->imaginary = imaginary;
}
inline void bgc_complex_get_product_fp64(const BgcComplexFP64* number1, const BgcComplexFP64* number2, BgcComplexFP64* result)
{
const double real = number1->real * number2->real - number1->imaginary * number2->imaginary;
const double imaginary = number1->real * number2->imaginary + number1->imaginary * number2->real;
result->real = real;
result->imaginary = imaginary;
}
// ================= Get Ratio ================== //
inline int bgc_complex_get_ratio_fp32(const BgcComplexFP32* divident, const BgcComplexFP32* divisor, BgcComplexFP32* quotient)
{
const float square_modulus = bgc_complex_get_square_modulus_fp32(divisor);
if (square_modulus <= BGC_SQUARE_EPSYLON_FP32) {
return 0;
}
const float real = divident->real * divisor->real + divident->imaginary * divisor->imaginary;
const float imaginary = divident->imaginary * divisor->real - divident->real * divisor->imaginary;
const float multiplier = 1.0f / square_modulus;
quotient->real = real * multiplier;
quotient->imaginary = imaginary * multiplier;
return 1;
}
inline int bgc_complex_get_ratio_fp64(const BgcComplexFP64* divident, const BgcComplexFP64* divisor, BgcComplexFP64* quotient)
{
const double square_modulus = bgc_complex_get_square_modulus_fp64(divisor);
if (square_modulus <= BGC_SQUARE_EPSYLON_FP64) {
return 0;
}
const double real = divident->real * divisor->real + divident->imaginary * divisor->imaginary;
const double imaginary = divident->imaginary * divisor->real - divident->real * divisor->imaginary;
const double multiplier = 1.0 / square_modulus;
quotient->real = real * multiplier;
quotient->imaginary = imaginary * multiplier;
return 1;
}
// =============== Get Exponation =============== //
void bgc_complex_get_exponation_fp32(const BgcComplexFP32* base, const float real_exponent, const float imaginary_exponent, BgcComplexFP32* power);
void bgc_complex_get_exponation_fp64(const BgcComplexFP64* base, const double real_exponent, const double imaginary_exponent, BgcComplexFP64* power);
// ==================== Add ===================== //
inline void bgc_complex_add_fp32(const BgcComplexFP32* number1, const BgcComplexFP32* number2, BgcComplexFP32* sum)
{
sum->real = number1->real + number2->real;
sum->imaginary = number1->imaginary + number2->imaginary;
}
inline void bgc_complex_add_fp64(const BgcComplexFP64* number1, const BgcComplexFP64* number2, BgcComplexFP64* sum)
{
sum->real = number1->real + number2->real;
sum->imaginary = number1->imaginary + number2->imaginary;
}
// ================= Add scaled ================= //
inline void bgc_complex_add_scaled_fp32(const BgcComplexFP32* basic_number, const BgcComplexFP32* scalable_number, const float scale, BgcComplexFP32* sum)
{
sum->real = basic_number->real + scalable_number->real * scale;
sum->imaginary = basic_number->imaginary + scalable_number->imaginary * scale;
}
inline void bgc_complex_add_scaled_fp64(const BgcComplexFP64* basic_number, const BgcComplexFP64* scalable_number, const double scale, BgcComplexFP64* sum)
{
sum->real = basic_number->real + scalable_number->real * scale;
sum->imaginary = basic_number->imaginary + scalable_number->imaginary * scale;
}
// ================== Subtract ================== //
inline void bgc_complex_subtract_fp32(const BgcComplexFP32* minuend, const BgcComplexFP32* subtrahend, BgcComplexFP32* difference)
{
difference->real = minuend->real - subtrahend->real;
difference->imaginary = minuend->imaginary - subtrahend->imaginary;
}
inline void bgc_complex_subtract_fp64(const BgcComplexFP64* minuend, const BgcComplexFP64* subtrahend, BgcComplexFP64* difference)
{
difference->real = minuend->real - subtrahend->real;
difference->imaginary = minuend->imaginary - subtrahend->imaginary;
}
// ============== Subtract scaled =============== //
inline void bgc_complex_subtract_scaled_fp32(const BgcComplexFP32* basic_number, const BgcComplexFP32* scalable_number, const float scale, BgcComplexFP32* difference)
{
difference->real = basic_number->real - scalable_number->real * scale;
difference->imaginary = basic_number->imaginary - scalable_number->imaginary * scale;
}
inline void bgc_complex_subtract_scaled_fp64(const BgcComplexFP64* basic_number, const BgcComplexFP64* scalable_number, const double scale, BgcComplexFP64* difference)
{
difference->real = basic_number->real - scalable_number->real * scale;
difference->imaginary = basic_number->imaginary - scalable_number->imaginary * scale;
}
// ================== Multiply ================== //
inline void bgc_complex_multiply_fp32(const BgcComplexFP32* multiplicand, const float multiplier, BgcComplexFP32* product)
{
product->real = multiplicand->real * multiplier;
product->imaginary = multiplicand->imaginary * multiplier;
}
inline void bgc_complex_multiply_fp64(const BgcComplexFP64* multiplicand, const double multiplier, BgcComplexFP64* product)
{
product->real = multiplicand->real * multiplier;
product->imaginary = multiplicand->imaginary * multiplier;
}
// =================== Divide =================== //
inline void bgc_complex_divide_fp32(const BgcComplexFP32* dividend, const float divisor, BgcComplexFP32* quotient)
{
bgc_complex_multiply_fp32(dividend, 1.0f / divisor, quotient);
}
inline void bgc_complex_divide_fp64(const BgcComplexFP64* dividend, const double divisor, BgcComplexFP64* quotient)
{
bgc_complex_multiply_fp64(dividend, 1.0 / divisor, quotient);
}
// ================== Average2 ================== //
inline void bgc_complex_get_mean_of_two_fp32(const BgcComplexFP32* number1, const BgcComplexFP32* number2, BgcComplexFP32* mean)
{
mean->real = (number1->real + number2->real) * 0.5f;
mean->imaginary = (number1->imaginary + number2->imaginary) * 0.5f;
}
inline void bgc_complex_get_mean_of_two_fp64(const BgcComplexFP64* number1, const BgcComplexFP64* number2, BgcComplexFP64* mean)
{
mean->real = (number1->real + number2->real) * 0.5;
mean->imaginary = (number1->imaginary + number2->imaginary) * 0.5;
}
// ================== Average3 ================== //
inline void bgc_complex_get_mean_of_three_fp32(const BgcComplexFP32* number1, const BgcComplexFP32* number2, const BgcComplexFP32* number3, BgcComplexFP32* mean)
{
mean->real = (number1->real + number2->real + number3->real) * BGC_ONE_THIRD_FP32;
mean->imaginary = (number1->imaginary + number2->imaginary + number3->imaginary) * BGC_ONE_THIRD_FP32;
}
inline void bgc_complex_get_mean_of_three_fp64(const BgcComplexFP64* number1, const BgcComplexFP64* number2, const BgcComplexFP64* number3, BgcComplexFP64* mean)
{
mean->real = (number1->real + number2->real + number3->real) * BGC_ONE_THIRD_FP64;
mean->imaginary = (number1->imaginary + number2->imaginary + number3->imaginary) * BGC_ONE_THIRD_FP64;
}
// =================== Linear =================== //
inline void bgc_complex_get_linear_interpolation_fp32(const BgcComplexFP32* number1, const BgcComplexFP32* number2, const float phase, BgcComplexFP32* interpolation)
{
const float counterphase = 1.0f - phase;
interpolation->real = number1->real * counterphase + number2->real * phase;
interpolation->imaginary = number1->imaginary * counterphase + number2->imaginary * phase;
}
inline void bgc_complex_get_linear_interpolation_fp64(const BgcComplexFP64* number1, const BgcComplexFP64* number2, const double phase, BgcComplexFP64* interpolation)
{
const double counterphase = 1.0 - phase;
interpolation->real = number1->real * counterphase + number2->real * phase;
interpolation->imaginary = number1->imaginary * counterphase + number2->imaginary * phase;
}
// ================== Minimal =================== //
inline void bgc_complex_minimize_fp32(const BgcComplexFP32* number, BgcComplexFP32* minimal)
{
if (number->real < minimal->real) {
minimal->real = number->real;
}
if (number->imaginary < minimal->imaginary) {
minimal->imaginary = number->imaginary;
}
}
inline void bgc_complex_minimize_fp64(const BgcComplexFP64* number, BgcComplexFP64* minimal)
{
if (number->real < minimal->real) {
minimal->real = number->real;
}
if (number->imaginary < minimal->imaginary) {
minimal->imaginary = number->imaginary;
}
}
// ================== Maximal =================== //
inline void bgc_complex_maximize_fp32(const BgcComplexFP32* number, BgcComplexFP32* maximal)
{
if (number->real > maximal->real) {
maximal->real = number->real;
}
if (number->imaginary > maximal->imaginary) {
maximal->imaginary = number->imaginary;
}
}
inline void bgc_complex_maximize_fp64(const BgcComplexFP64* number, BgcComplexFP64* maximal)
{
if (number->real > maximal->real) {
maximal->real = number->real;
}
if (number->imaginary > maximal->imaginary) {
maximal->imaginary = number->imaginary;
}
}
// ================== Are Close ================= //
inline int bgc_complex_are_close_fp32(const BgcComplexFP32* number1, const BgcComplexFP32* number2)
{
const float square_modulus1 = bgc_complex_get_square_modulus_fp32(number1);
const float square_modulus2 = bgc_complex_get_square_modulus_fp32(number2);
const float d_real = number1->real - number2->real;
const float d_imaginary = number1->imaginary - number2->imaginary;
const float square_distance = d_real * d_real + d_imaginary * d_imaginary;
if (square_modulus1 <= BGC_EPSYLON_EFFECTIVENESS_LIMIT_FP32 || square_modulus2 <= BGC_EPSYLON_EFFECTIVENESS_LIMIT_FP32) {
return square_distance <= BGC_SQUARE_EPSYLON_FP32;
}
return square_distance <= BGC_SQUARE_EPSYLON_FP32 * square_modulus1 && square_distance <= BGC_SQUARE_EPSYLON_FP32 * square_modulus2;
}
inline int bgc_complex_are_close_fp64(const BgcComplexFP64* number1, const BgcComplexFP64* number2)
{
const double square_modulus1 = bgc_complex_get_square_modulus_fp64(number1);
const double square_modulus2 = bgc_complex_get_square_modulus_fp64(number2);
const double d_real = number1->real - number2->real;
const double d_imaginary = number1->imaginary - number2->imaginary;
const double square_distance = d_real * d_real + d_imaginary * d_imaginary;
if (square_modulus1 <= BGC_EPSYLON_EFFECTIVENESS_LIMIT_FP64 || square_modulus2 <= BGC_EPSYLON_EFFECTIVENESS_LIMIT_FP64) {
return square_distance <= BGC_SQUARE_EPSYLON_FP64;
}
return square_distance <= BGC_SQUARE_EPSYLON_FP32 * square_modulus1 && square_distance <= BGC_SQUARE_EPSYLON_FP32 * square_modulus2;
}
#endif

View file

@ -0,0 +1,82 @@
#include "./cotes-number.h"
const BgcCotesNumberFP32 BGC_IDLE_COTES_NUMBER_FP32 = { 1.0f, 0.0f };
const BgcCotesNumberFP64 BGC_IDLE_COTES_NUMBER_FP64 = { 1.0, 0.0 };
extern inline void bgc_cotes_number_reset_fp32(BgcCotesNumberFP32* number);
extern inline void bgc_cotes_number_reset_fp64(BgcCotesNumberFP64* number);
extern inline void bgc_cotes_number_set_values_fp32(const float x1, const float x2, BgcCotesNumberFP32* number);
extern inline void bgc_cotes_number_set_values_fp64(const double x1, const double x2, BgcCotesNumberFP64* number);
extern inline void bgc_cotes_number_set_turn_fp32(const float angle, const BgcAngleUnitEnum unit, BgcCotesNumberFP32* number);
extern inline void bgc_cotes_number_set_turn_fp64(const double angle, const BgcAngleUnitEnum unit, BgcCotesNumberFP64* number);
extern inline float bgc_cotes_number_get_angle_fp32(const BgcCotesNumberFP32* number, const BgcAngleUnitEnum unit);
extern inline double bgc_cotes_number_get_angle_fp64(const BgcCotesNumberFP64* number, const BgcAngleUnitEnum unit);
extern inline void bgc_cotes_number_copy_fp32(const BgcCotesNumberFP32* source, BgcCotesNumberFP32* destination);
extern inline void bgc_cotes_number_copy_fp64(const BgcCotesNumberFP64* source, BgcCotesNumberFP64* destination);
extern inline void bgc_cotes_number_swap_fp32(BgcCotesNumberFP32* number1, BgcCotesNumberFP32* number2);
extern inline void bgc_cotes_number_swap_fp64(BgcCotesNumberFP64* number1, BgcCotesNumberFP64* number2);
extern inline void bgc_cotes_number_convert_fp64_to_fp32(const BgcCotesNumberFP64* source, BgcCotesNumberFP32* destination);
extern inline void bgc_cotes_number_convert_fp32_to_fp64(const BgcCotesNumberFP32* source, BgcCotesNumberFP64* destination);
extern inline void bgc_cotes_number_invert_fp32(const BgcCotesNumberFP32* number, BgcCotesNumberFP32* inverted);
extern inline void bgc_cotes_number_invert_fp64(const BgcCotesNumberFP64* number, BgcCotesNumberFP64* inverted);
extern inline void bgc_cotes_number_get_exponation_fp32(const BgcCotesNumberFP32* base, const float exponent, BgcCotesNumberFP32* power);
extern inline void bgc_cotes_number_get_exponation_fp64(const BgcCotesNumberFP64* base, const double exponent, BgcCotesNumberFP64* power);
extern inline void bgc_cotes_number_combine_fp32(const BgcCotesNumberFP32* number1, const BgcCotesNumberFP32* number2, BgcCotesNumberFP32* result);
extern inline void bgc_cotes_number_combine_fp64(const BgcCotesNumberFP64* number1, const BgcCotesNumberFP64* number2, BgcCotesNumberFP64* result);
extern inline void bgc_cotes_number_get_rotation_matrix_fp32(const BgcCotesNumberFP32* number, BgcMatrix2x2FP32* matrix);
extern inline void bgc_cotes_number_get_rotation_matrix_fp64(const BgcCotesNumberFP64* number, BgcMatrix2x2FP64* matrix);
extern inline void bgc_cotes_number_get_reverse_matrix_fp32(const BgcCotesNumberFP32* number, BgcMatrix2x2FP32* matrix);
extern inline void bgc_cotes_number_get_reverse_matrix_fp64(const BgcCotesNumberFP64* number, BgcMatrix2x2FP64* matrix);
extern inline void bgc_cotes_number_turn_vector_fp32(const BgcCotesNumberFP32* number, const BgcVector2FP32* vector, BgcVector2FP32* result);
extern inline void bgc_cotes_number_turn_vector_fp64(const BgcCotesNumberFP64* number, const BgcVector2FP64* vector, BgcVector2FP64* result);
extern inline void bgc_cotes_number_turn_vector_back_fp32(const BgcCotesNumberFP32* number, const BgcVector2FP32* vector, BgcVector2FP32* result);
extern inline void bgc_cotes_number_turn_vector_back_fp64(const BgcCotesNumberFP64* number, const BgcVector2FP64* vector, BgcVector2FP64* result);
extern inline int bgc_cotes_number_are_close_fp32(const BgcCotesNumberFP32* number1, const BgcCotesNumberFP32* number2);
extern inline int bgc_cotes_number_are_close_fp64(const BgcCotesNumberFP64* number1, const BgcCotesNumberFP64* number2);
void _bgc_cotes_number_normalize_fp32(const float square_modulus, _BgcTwinCotesNumberFP32* twin)
{
// (square_modulus != square_modulus) is true when square_modulus is NaN
if (square_modulus <= BGC_SQUARE_EPSYLON_FP32 || square_modulus != square_modulus) {
twin->cos = 1.0f;
twin->sin = 0.0f;
return;
}
const float multiplier = sqrtf(1.0f / square_modulus);
twin->cos *= multiplier;
twin->sin *= multiplier;
}
void _bgc_cotes_number_normalize_fp64(const double square_modulus, _BgcTwinCotesNumberFP64* twin)
{
// (square_modulus != square_modulus) is true when square_modulus is NaN
if (square_modulus <= BGC_SQUARE_EPSYLON_FP64 || square_modulus != square_modulus) {
twin->cos = 1.0;
twin->sin = 0.0;
return;
}
const double multiplier = sqrt(1.0 / square_modulus);
twin->cos *= multiplier;
twin->sin *= multiplier;
}

View file

@ -0,0 +1,374 @@
#ifndef _BGC_COTES_NUMBER_H_
#define _BGC_COTES_NUMBER_H_
#include <math.h>
#include "utilities.h"
#include "angle.h"
#include "vector2.h"
#include "matrix2x2.h"
// =================== Types ==================== //
typedef struct
{
const float cos, sin;
} BgcCotesNumberFP32;
typedef struct
{
const double cos, sin;
} BgcCotesNumberFP64;
// ================= Dark Twins ================= //
typedef struct {
float cos, sin;
} _BgcTwinCotesNumberFP32;
typedef struct {
double cos, sin;
} _BgcTwinCotesNumberFP64;
// ================= Constants ================== //
extern const BgcCotesNumberFP32 BGC_IDLE_COTES_NUMBER_FP32;
extern const BgcCotesNumberFP64 BGC_IDLE_COTES_NUMBER_FP64;
// =================== Reset ==================== //
inline void bgc_cotes_number_reset_fp32(BgcCotesNumberFP32* number)
{
_BgcTwinCotesNumberFP32* twin = (_BgcTwinCotesNumberFP32*)number;
twin->cos = 1.0f;
twin->sin = 0.0f;
}
inline void bgc_cotes_number_reset_fp64(BgcCotesNumberFP64* number)
{
_BgcTwinCotesNumberFP64* twin = (_BgcTwinCotesNumberFP64*)number;
twin->cos = 1.0;
twin->sin = 0.0;
}
// ==================== Set ===================== //
void _bgc_cotes_number_normalize_fp32(const float square_modulus, _BgcTwinCotesNumberFP32* twin);
void _bgc_cotes_number_normalize_fp64(const double square_modulus, _BgcTwinCotesNumberFP64* twin);
inline void bgc_cotes_number_set_values_fp32(const float x1, const float x2, BgcCotesNumberFP32* number)
{
const float square_modulus = x1 * x1 + x2 * x2;
_BgcTwinCotesNumberFP32* twin = (_BgcTwinCotesNumberFP32*)number;
twin->cos = x1;
twin->sin = x2;
if (!bgc_is_sqare_unit_fp32(square_modulus)) {
_bgc_cotes_number_normalize_fp32(square_modulus, twin);
}
}
inline void bgc_cotes_number_set_values_fp64(const double x1, const double x2, BgcCotesNumberFP64* number)
{
const double square_modulus = x1 * x1 + x2 * x2;
_BgcTwinCotesNumberFP64* twin = (_BgcTwinCotesNumberFP64*)number;
twin->cos = x1;
twin->sin = x2;
if (!bgc_is_sqare_unit_fp64(square_modulus)) {
_bgc_cotes_number_normalize_fp64(square_modulus, twin);
}
}
// ================== Set Turn ================== //
inline void bgc_cotes_number_set_turn_fp32(const float angle, const BgcAngleUnitEnum unit, BgcCotesNumberFP32* number)
{
const float radians = bgc_angle_to_radians_fp32(angle, unit);
_BgcTwinCotesNumberFP32* twin = (_BgcTwinCotesNumberFP32*)number;
twin->cos = cosf(radians);
twin->sin = sinf(radians);
}
inline void bgc_cotes_number_set_turn_fp64(const double angle, const BgcAngleUnitEnum unit, BgcCotesNumberFP64* number)
{
const double radians = bgc_angle_to_radians_fp64(angle, unit);
_BgcTwinCotesNumberFP64* twin = (_BgcTwinCotesNumberFP64*)number;
twin->cos = cos(radians);
twin->sin = sin(radians);
}
// =================== Angle =================== //
inline float bgc_cotes_number_get_angle_fp32(const BgcCotesNumberFP32* number, const BgcAngleUnitEnum unit)
{
if (number->cos >= 1.0f - BGC_EPSYLON_FP32) {
return 0.0f;
}
if (number->cos <= -1.0f + BGC_EPSYLON_FP32) {
return bgc_angle_get_half_circle_fp32(unit);
}
if (number->sin >= 1.0f - BGC_EPSYLON_FP32) {
return bgc_angle_get_quater_circle_fp32(unit);
}
if (number->sin <= -1.0f + BGC_EPSYLON_FP32) {
return 0.75f * bgc_angle_get_full_circle_fp32(unit);
}
return bgc_radians_to_units_fp32(atan2f(number->sin, number->cos), unit);
}
inline double bgc_cotes_number_get_angle_fp64(const BgcCotesNumberFP64* number, const BgcAngleUnitEnum unit)
{
if (number->cos >= 1.0 - BGC_EPSYLON_FP64) {
return 0.0;
}
if (number->cos <= -1.0 + BGC_EPSYLON_FP64) {
return bgc_angle_get_half_circle_fp64(unit);
}
if (number->sin >= 1.0 - BGC_EPSYLON_FP64) {
return bgc_angle_get_quater_circle_fp64(unit);
}
if (number->sin <= -1.0 + BGC_EPSYLON_FP64) {
return 0.75 * bgc_angle_get_full_circle_fp64(unit);
}
return bgc_radians_to_units_fp64(atan2(number->sin, number->cos), unit);
}
// ==================== Copy ==================== //
inline void bgc_cotes_number_copy_fp32(const BgcCotesNumberFP32* source, BgcCotesNumberFP32* destination)
{
_BgcTwinCotesNumberFP32* twin = (_BgcTwinCotesNumberFP32*)destination;
twin->cos = source->cos;
twin->sin = source->sin;
}
inline void bgc_cotes_number_copy_fp64(const BgcCotesNumberFP64* source, BgcCotesNumberFP64* destination)
{
_BgcTwinCotesNumberFP64* twin = (_BgcTwinCotesNumberFP64*)destination;
twin->cos = source->cos;
twin->sin = source->sin;
}
// ==================== Swap ==================== //
inline void bgc_cotes_number_swap_fp32(BgcCotesNumberFP32* number1, BgcCotesNumberFP32* number2)
{
const float cos = number1->cos;
const float sin = number1->sin;
_BgcTwinCotesNumberFP32* twin1 = (_BgcTwinCotesNumberFP32*)number1;
twin1->cos = number2->cos;
twin1->sin = number2->sin;
_BgcTwinCotesNumberFP32* twin2 = (_BgcTwinCotesNumberFP32*)number2;
twin2->cos = cos;
twin2->sin = sin;
}
inline void bgc_cotes_number_swap_fp64(BgcCotesNumberFP64* number1, BgcCotesNumberFP64* number2)
{
const double cos = number1->cos;
const double sin = number1->sin;
_BgcTwinCotesNumberFP64* twin1 = (_BgcTwinCotesNumberFP64*)number1;
twin1->cos = number2->cos;
twin1->sin = number2->sin;
_BgcTwinCotesNumberFP64* twin2 = (_BgcTwinCotesNumberFP64*)number2;
twin2->cos = cos;
twin2->sin = sin;
}
// ================== Convert =================== //
inline void bgc_cotes_number_convert_fp64_to_fp32(const BgcCotesNumberFP64* source, BgcCotesNumberFP32* destination)
{
bgc_cotes_number_set_values_fp32((float)source->cos, (float)source->sin, destination);
}
inline void bgc_cotes_number_convert_fp32_to_fp64(const BgcCotesNumberFP32* source, BgcCotesNumberFP64* destination)
{
bgc_cotes_number_set_values_fp64((double)source->cos, (double)source->sin, destination);
}
// =================== Invert =================== //
inline void bgc_cotes_number_invert_fp32(const BgcCotesNumberFP32* number, BgcCotesNumberFP32* inverted)
{
_BgcTwinCotesNumberFP32* twin = (_BgcTwinCotesNumberFP32*)inverted;
twin->cos = number->cos;
twin->sin = -number->sin;
}
inline void bgc_cotes_number_invert_fp64(const BgcCotesNumberFP64* number, BgcCotesNumberFP64* inverted)
{
_BgcTwinCotesNumberFP64* twin = (_BgcTwinCotesNumberFP64*)inverted;
twin->cos = number->cos;
twin->sin = -number->sin;
}
// ================= Exponation ================= //
inline void bgc_cotes_number_get_exponation_fp32(const BgcCotesNumberFP32* base, const float exponent, BgcCotesNumberFP32* power)
{
const float power_angle = exponent * atan2f(base->sin, base->cos);
_BgcTwinCotesNumberFP32* twin = (_BgcTwinCotesNumberFP32*)power;
twin->cos = cosf(power_angle);
twin->sin = sinf(power_angle);
}
inline void bgc_cotes_number_get_exponation_fp64(const BgcCotesNumberFP64* base, const double exponent, BgcCotesNumberFP64* power)
{
const double power_angle = exponent * atan2(base->sin, base->cos);
_BgcTwinCotesNumberFP64* twin = (_BgcTwinCotesNumberFP64*)power;
twin->cos = cos(power_angle);
twin->sin = sin(power_angle);
}
// ================ Combination ================= //
inline void bgc_cotes_number_combine_fp32(const BgcCotesNumberFP32* number1, const BgcCotesNumberFP32* number2, BgcCotesNumberFP32* result)
{
bgc_cotes_number_set_values_fp32(
number1->cos * number2->cos - number1->sin * number2->sin,
number1->cos * number2->sin + number1->sin * number2->cos,
result
);
}
inline void bgc_cotes_number_combine_fp64(const BgcCotesNumberFP64* number1, const BgcCotesNumberFP64* number2, BgcCotesNumberFP64* result)
{
bgc_cotes_number_set_values_fp64(
number1->cos * number2->cos - number1->sin * number2->sin,
number1->cos * number2->sin + number1->sin * number2->cos,
result
);
}
// ============== Rotation Matrix =============== //
inline void bgc_cotes_number_get_rotation_matrix_fp32(const BgcCotesNumberFP32* number, BgcMatrix2x2FP32* matrix)
{
matrix->r1c1 = number->cos;
matrix->r1c2 = -number->sin;
matrix->r2c1 = number->sin;
matrix->r2c2 = number->cos;
}
inline void bgc_cotes_number_get_rotation_matrix_fp64(const BgcCotesNumberFP64* number, BgcMatrix2x2FP64* matrix)
{
matrix->r1c1 = number->cos;
matrix->r1c2 = -number->sin;
matrix->r2c1 = number->sin;
matrix->r2c2 = number->cos;
}
// ============== Reverse Matrix ================ //
inline void bgc_cotes_number_get_reverse_matrix_fp32(const BgcCotesNumberFP32* number, BgcMatrix2x2FP32* matrix)
{
matrix->r1c1 = number->cos;
matrix->r1c2 = number->sin;
matrix->r2c1 = -number->sin;
matrix->r2c2 = number->cos;
}
inline void bgc_cotes_number_get_reverse_matrix_fp64(const BgcCotesNumberFP64* number, BgcMatrix2x2FP64* matrix)
{
matrix->r1c1 = number->cos;
matrix->r1c2 = number->sin;
matrix->r2c1 = -number->sin;
matrix->r2c2 = number->cos;
}
// ================ Turn Vector ================= //
inline void bgc_cotes_number_turn_vector_fp32(const BgcCotesNumberFP32* number, const BgcVector2FP32* vector, BgcVector2FP32* result)
{
const float x1 = number->cos * vector->x1 - number->sin * vector->x2;
const float x2 = number->sin * vector->x1 + number->cos * vector->x2;
result->x1 = x1;
result->x2 = x2;
}
inline void bgc_cotes_number_turn_vector_fp64(const BgcCotesNumberFP64* number, const BgcVector2FP64* vector, BgcVector2FP64* result)
{
const double x1 = number->cos * vector->x1 - number->sin * vector->x2;
const double x2 = number->sin * vector->x1 + number->cos * vector->x2;
result->x1 = x1;
result->x2 = x2;
}
// ============ Turn Vector Backward ============ //
inline void bgc_cotes_number_turn_vector_back_fp32(const BgcCotesNumberFP32* number, const BgcVector2FP32* vector, BgcVector2FP32* result)
{
const float x1 = number->sin * vector->x2 + number->cos * vector->x1;
const float x2 = number->cos * vector->x2 - number->sin * vector->x1;
result->x1 = x1;
result->x2 = x2;
}
inline void bgc_cotes_number_turn_vector_back_fp64(const BgcCotesNumberFP64* number, const BgcVector2FP64* vector, BgcVector2FP64* result)
{
const double x1 = number->sin * vector->x2 + number->cos * vector->x1;
const double x2 = number->cos * vector->x2 - number->sin * vector->x1;
result->x1 = x1;
result->x2 = x2;
}
// ================== Are Close ================= //
inline int bgc_cotes_number_are_close_fp32(const BgcCotesNumberFP32* number1, const BgcCotesNumberFP32* number2)
{
const float d_cos = number1->cos - number2->cos;
const float d_sin = number1->sin - number2->sin;
return d_cos * d_cos + d_sin * d_sin <= BGC_SQUARE_EPSYLON_FP32;
}
inline int bgc_cotes_number_are_close_fp64(const BgcCotesNumberFP64* number1, const BgcCotesNumberFP64* number2)
{
const double d_cos = number1->cos - number2->cos;
const double d_sin = number1->sin - number2->sin;
return d_cos * d_cos + d_sin * d_sin <= BGC_SQUARE_EPSYLON_FP64;
}
#endif

View file

@ -72,5 +72,9 @@ extern inline int bgc_quaternion_get_rotation_matrix_fp64(const BgcQuaternionFP6
extern inline int bgc_quaternion_get_reverse_matrix_fp32(const BgcQuaternionFP32* quaternion, BgcMatrix3x3FP32* reverse);
extern inline int bgc_quaternion_get_reverse_matrix_fp64(const BgcQuaternionFP64* quaternion, BgcMatrix3x3FP64* reverse);
extern inline int bgc_quaternion_get_both_matrixes_fp32(const BgcQuaternionFP32* quaternion, BgcMatrix3x3FP32* rotation, BgcMatrix3x3FP32* reverse);
extern inline int bgc_quaternion_get_both_matrixes_fp64(const BgcQuaternionFP64* quaternion, BgcMatrix3x3FP64* rotation, BgcMatrix3x3FP64* reverse);
extern inline int bgc_quaternion_are_close_fp32(const BgcQuaternionFP32* quaternion1, const BgcQuaternionFP32* quaternion2);
extern inline int bgc_quaternion_are_close_fp32(const BgcQuaternionFP32* quaternion1, const BgcQuaternionFP32* quaternion2);

View file

@ -659,6 +659,8 @@ inline int bgc_quaternion_get_reverse_matrix_fp64(const BgcQuaternionFP64* quate
return 1;
}
// ============= Get Both Matrixes ============== //
inline int bgc_quaternion_get_both_matrixes_fp32(const BgcQuaternionFP32* quaternion, BgcMatrix3x3FP32* rotation, BgcMatrix3x3FP32* reverse)
{
if (bgc_quaternion_get_reverse_matrix_fp32(quaternion, reverse)) {

View file

@ -1,79 +0,0 @@
#include "tangent-pair.h"
const BgcTangentPairFP32 BGC_IDLE_TANGENT_PAIR_FP32 = { 1.0f, 0.0f };
const BgcTangentPairFP64 BGC_IDLE_TANGENT_PAIR_FP64 = { 1.0, 0.0 };
extern inline void bgc_tangent_pair_reset_fp32(BgcTangentPairFP32* tangent);
extern inline void bgc_tangent_pair_reset_fp64(BgcTangentPairFP64* tangent);
extern inline void bgc_tangent_pair_set_values_fp32(const float x1, const float x2, BgcTangentPairFP32* tangent);
extern inline void bgc_tangent_pair_set_values_fp64(const double x1, const double x2, BgcTangentPairFP64* tangent);
extern inline void bgc_tangent_pair_set_turn_fp32(const float angle, const BgcAngleUnitEnum unit, BgcTangentPairFP32* tangent);
extern inline void bgc_tangent_pair_set_turn_fp64(const double angle, const BgcAngleUnitEnum unit, BgcTangentPairFP64* tangent);
extern inline float bgc_tangent_pair_get_angle_fp32(const BgcTangentPairFP32* tangent, const BgcAngleUnitEnum unit);
extern inline double bgc_tangent_pair_get_angle_fp64(const BgcTangentPairFP64* tangent, const BgcAngleUnitEnum unit);
extern inline void bgc_tangent_pair_copy_fp32(const BgcTangentPairFP32* source, BgcTangentPairFP32* destination);
extern inline void bgc_tangent_pair_copy_fp64(const BgcTangentPairFP64* source, BgcTangentPairFP64* destination);
extern inline void bgc_tangent_pair_swap_fp32(BgcTangentPairFP32* tangent1, BgcTangentPairFP32* tangent2);
extern inline void bgc_tangent_pair_swap_fp64(BgcTangentPairFP64* tangent1, BgcTangentPairFP64* tangent2);
extern inline void bgc_tangent_pair_convert_fp64_to_fp32(const BgcTangentPairFP64* source, BgcTangentPairFP32* destination);
extern inline void bgc_tangent_pair_convert_fp32_to_fp64(const BgcTangentPairFP32* source, BgcTangentPairFP64* destination);
extern inline void bgc_tangent_pair_invert_fp32(const BgcTangentPairFP32* tangent, BgcTangentPairFP32* inverted);
extern inline void bgc_tangent_pair_invert_fp64(const BgcTangentPairFP64* tangent, BgcTangentPairFP64* inverted);
extern inline void bgc_tangent_pair_combine_fp32(const BgcTangentPairFP32* tangent1, const BgcTangentPairFP32* tangent2, BgcTangentPairFP32* result);
extern inline void bgc_tangent_pair_combine_fp64(const BgcTangentPairFP64* tangent1, const BgcTangentPairFP64* tangent2, BgcTangentPairFP64* result);
extern inline void bgc_tangent_pair_get_rotation_matrix_fp32(const BgcTangentPairFP32* tangent, BgcMatrix2x2FP32* matrix);
extern inline void bgc_tangent_pair_get_rotation_matrix_fp64(const BgcTangentPairFP64* tangent, BgcMatrix2x2FP64* matrix);
extern inline void bgc_tangent_pair_get_reverse_matrix_fp32(const BgcTangentPairFP32* tangent, BgcMatrix2x2FP32* matrix);
extern inline void bgc_tangent_pair_get_reverse_matrix_fp64(const BgcTangentPairFP64* tangent, BgcMatrix2x2FP64* matrix);
extern inline void bgc_tangent_pair_turn_vector_fp32(const BgcTangentPairFP32* tangent, const BgcVector2FP32* vector, BgcVector2FP32* result);
extern inline void bgc_tangent_pair_turn_vector_fp64(const BgcTangentPairFP64* tangent, const BgcVector2FP64* vector, BgcVector2FP64* result);
extern inline void bgc_tangent_pair_turn_vector_back_fp32(const BgcTangentPairFP32* tangent, const BgcVector2FP32* vector, BgcVector2FP32* result);
extern inline void bgc_tangent_pair_turn_vector_back_fp64(const BgcTangentPairFP64* tangent, const BgcVector2FP64* vector, BgcVector2FP64* result);
extern inline int bgc_tangent_pair_are_close_fp32(const BgcTangentPairFP32* tangent1, const BgcTangentPairFP32* tangent2);
extern inline int bgc_tangent_pair_are_close_fp64(const BgcTangentPairFP64* tangent1, const BgcTangentPairFP64* tangent2);
void _bgc_tangent_pair_normalize_fp32(const float square_modulus, _BgcTwinTangentPairFP32* twin)
{
// (square_modulus != square_modulus) is true when square_modulus is NaN
if (square_modulus <= BGC_SQUARE_EPSYLON_FP32 || square_modulus != square_modulus) {
twin->cos = 1.0f;
twin->sin = 0.0f;
return;
}
const float multiplier = sqrtf(1.0f / square_modulus);
twin->cos *= multiplier;
twin->sin *= multiplier;
}
void _bgc_tangent_pair_normalize_fp64(const double square_modulus, _BgcTwinTangentPairFP64* twin)
{
// (square_modulus != square_modulus) is true when square_modulus is NaN
if (square_modulus <= BGC_SQUARE_EPSYLON_FP64 || square_modulus != square_modulus) {
twin->cos = 1.0;
twin->sin = 0.0;
return;
}
const double multiplier = sqrt(1.0 / square_modulus);
twin->cos *= multiplier;
twin->sin *= multiplier;
}

View file

@ -1,352 +0,0 @@
#ifndef _bgc_tangent_pair_H_
#define _bgc_tangent_pair_H_
#include <math.h>
#include "utilities.h"
#include "angle.h"
#include "vector2.h"
#include "matrix2x2.h"
// =================== Types ==================== //
typedef struct
{
const float cos, sin;
} BgcTangentPairFP32;
typedef struct
{
const double cos, sin;
} BgcTangentPairFP64;
// ================= Dark Twins ================= //
typedef struct {
float cos, sin;
} _BgcTwinTangentPairFP32;
typedef struct {
double cos, sin;
} _BgcTwinTangentPairFP64;
// ================= Constants ================== //
extern const BgcTangentPairFP32 BGC_IDLE_TANGENT_PAIR_FP32;
extern const BgcTangentPairFP64 BGC_IDLE_TANGENT_PAIR_FP64;
// =================== Reset ==================== //
inline void bgc_tangent_pair_reset_fp32(BgcTangentPairFP32* tangent)
{
_BgcTwinTangentPairFP32* twin = (_BgcTwinTangentPairFP32*)tangent;
twin->cos = 1.0f;
twin->sin = 0.0f;
}
inline void bgc_tangent_pair_reset_fp64(BgcTangentPairFP64* tangent)
{
_BgcTwinTangentPairFP64* twin = (_BgcTwinTangentPairFP64*)tangent;
twin->cos = 1.0;
twin->sin = 0.0;
}
// ==================== Set ===================== //
void _bgc_tangent_pair_normalize_fp32(const float square_modulus, _BgcTwinTangentPairFP32* twin);
void _bgc_tangent_pair_normalize_fp64(const double square_modulus, _BgcTwinTangentPairFP64* twin);
inline void bgc_tangent_pair_set_values_fp32(const float x1, const float x2, BgcTangentPairFP32* tangent)
{
const float square_modulus = x1 * x1 + x2 * x2;
_BgcTwinTangentPairFP32* twin = (_BgcTwinTangentPairFP32*)tangent;
twin->cos = x1;
twin->sin = x2;
if (!bgc_is_sqare_unit_fp32(square_modulus)) {
_bgc_tangent_pair_normalize_fp32(square_modulus, twin);
}
}
inline void bgc_tangent_pair_set_values_fp64(const double x1, const double x2, BgcTangentPairFP64* tangent)
{
const double square_modulus = x1 * x1 + x2 * x2;
_BgcTwinTangentPairFP64* twin = (_BgcTwinTangentPairFP64*)tangent;
twin->cos = x1;
twin->sin = x2;
if (!bgc_is_sqare_unit_fp64(square_modulus)) {
_bgc_tangent_pair_normalize_fp64(square_modulus, twin);
}
}
// ================== Set Turn ================== //
inline void bgc_tangent_pair_set_turn_fp32(const float angle, const BgcAngleUnitEnum unit, BgcTangentPairFP32* tangent)
{
const float radians = bgc_angle_to_radians_fp32(angle, unit);
_BgcTwinTangentPairFP32* twin = (_BgcTwinTangentPairFP32*)tangent;
twin->cos = cosf(radians);
twin->sin = sinf(radians);
}
inline void bgc_tangent_pair_set_turn_fp64(const double angle, const BgcAngleUnitEnum unit, BgcTangentPairFP64* tangent)
{
const double radians = bgc_angle_to_radians_fp64(angle, unit);
_BgcTwinTangentPairFP64* twin = (_BgcTwinTangentPairFP64*)tangent;
twin->cos = cos(radians);
twin->sin = sin(radians);
}
// =================== Angle =================== //
inline float bgc_tangent_pair_get_angle_fp32(const BgcTangentPairFP32* tangent, const BgcAngleUnitEnum unit)
{
if (tangent->cos >= 1.0f - BGC_EPSYLON_FP32) {
return 0.0f;
}
if (tangent->cos <= -1.0f + BGC_EPSYLON_FP32) {
return bgc_angle_get_half_circle_fp32(unit);
}
if (tangent->sin >= 1.0f - BGC_EPSYLON_FP32) {
return bgc_angle_get_quater_circle_fp32(unit);
}
if (tangent->sin <= -1.0f + BGC_EPSYLON_FP32) {
return 0.75f * bgc_angle_get_full_circle_fp32(unit);
}
return bgc_radians_to_units_fp32(atan2f(tangent->sin, tangent->cos), unit);
}
inline double bgc_tangent_pair_get_angle_fp64(const BgcTangentPairFP64* tangent, const BgcAngleUnitEnum unit)
{
if (tangent->cos >= 1.0 - BGC_EPSYLON_FP64) {
return 0.0;
}
if (tangent->cos <= -1.0 + BGC_EPSYLON_FP64) {
return bgc_angle_get_half_circle_fp64(unit);
}
if (tangent->sin >= 1.0 - BGC_EPSYLON_FP64) {
return bgc_angle_get_quater_circle_fp64(unit);
}
if (tangent->sin <= -1.0 + BGC_EPSYLON_FP64) {
return 0.75 * bgc_angle_get_full_circle_fp64(unit);
}
return bgc_radians_to_units_fp64(atan2(tangent->sin, tangent->cos), unit);
}
// ==================== Copy ==================== //
inline void bgc_tangent_pair_copy_fp32(const BgcTangentPairFP32* source, BgcTangentPairFP32* destination)
{
_BgcTwinTangentPairFP32* twin = (_BgcTwinTangentPairFP32*)destination;
twin->cos = source->cos;
twin->sin = source->sin;
}
inline void bgc_tangent_pair_copy_fp64(const BgcTangentPairFP64* source, BgcTangentPairFP64* destination)
{
_BgcTwinTangentPairFP64* twin = (_BgcTwinTangentPairFP64*)destination;
twin->cos = source->cos;
twin->sin = source->sin;
}
// ==================== Swap ==================== //
inline void bgc_tangent_pair_swap_fp32(BgcTangentPairFP32* tangent1, BgcTangentPairFP32* tangent2)
{
const float cos = tangent1->cos;
const float sin = tangent1->sin;
_BgcTwinTangentPairFP32* twin1 = (_BgcTwinTangentPairFP32*)tangent1;
twin1->cos = tangent2->cos;
twin1->sin = tangent2->sin;
_BgcTwinTangentPairFP32* twin2 = (_BgcTwinTangentPairFP32*)tangent2;
twin2->cos = cos;
twin2->sin = sin;
}
inline void bgc_tangent_pair_swap_fp64(BgcTangentPairFP64* tangent1, BgcTangentPairFP64* tangent2)
{
const double cos = tangent1->cos;
const double sin = tangent1->sin;
_BgcTwinTangentPairFP64* twin1 = (_BgcTwinTangentPairFP64*)tangent1;
twin1->cos = tangent2->cos;
twin1->sin = tangent2->sin;
_BgcTwinTangentPairFP64* twin2 = (_BgcTwinTangentPairFP64*)tangent2;
twin2->cos = cos;
twin2->sin = sin;
}
// ================== Convert =================== //
inline void bgc_tangent_pair_convert_fp64_to_fp32(const BgcTangentPairFP64* source, BgcTangentPairFP32* destination)
{
bgc_tangent_pair_set_values_fp32((float)source->cos, (float)source->sin, destination);
}
inline void bgc_tangent_pair_convert_fp32_to_fp64(const BgcTangentPairFP32* source, BgcTangentPairFP64* destination)
{
bgc_tangent_pair_set_values_fp64((double)source->cos, (double)source->sin, destination);
}
// =================== Invert =================== //
inline void bgc_tangent_pair_invert_fp32(const BgcTangentPairFP32* tangent, BgcTangentPairFP32* inverted)
{
_BgcTwinTangentPairFP32* twin = (_BgcTwinTangentPairFP32*)inverted;
twin->cos = tangent->cos;
twin->sin = -tangent->sin;
}
inline void bgc_tangent_pair_invert_fp64(const BgcTangentPairFP64* tangent, BgcTangentPairFP64* inverted)
{
_BgcTwinTangentPairFP64* twin = (_BgcTwinTangentPairFP64*)inverted;
twin->cos = tangent->cos;
twin->sin = -tangent->sin;
}
// ================ Combination ================= //
inline void bgc_tangent_pair_combine_fp32(const BgcTangentPairFP32* tangent1, const BgcTangentPairFP32* tangent2, BgcTangentPairFP32* result)
{
bgc_tangent_pair_set_values_fp32(
tangent1->cos * tangent2->cos - tangent1->sin * tangent2->sin,
tangent1->cos * tangent2->sin + tangent1->sin * tangent2->cos,
result
);
}
inline void bgc_tangent_pair_combine_fp64(const BgcTangentPairFP64* tangent1, const BgcTangentPairFP64* tangent2, BgcTangentPairFP64* result)
{
bgc_tangent_pair_set_values_fp64(
tangent1->cos * tangent2->cos - tangent1->sin * tangent2->sin,
tangent1->cos * tangent2->sin + tangent1->sin * tangent2->cos,
result
);
}
// ============== Rotation Matrix =============== //
inline void bgc_tangent_pair_get_rotation_matrix_fp32(const BgcTangentPairFP32* tangent, BgcMatrix2x2FP32* matrix)
{
matrix->r1c1 = tangent->cos;
matrix->r1c2 = -tangent->sin;
matrix->r2c1 = tangent->sin;
matrix->r2c2 = tangent->cos;
}
inline void bgc_tangent_pair_get_rotation_matrix_fp64(const BgcTangentPairFP64* tangent, BgcMatrix2x2FP64* matrix)
{
matrix->r1c1 = tangent->cos;
matrix->r1c2 = -tangent->sin;
matrix->r2c1 = tangent->sin;
matrix->r2c2 = tangent->cos;
}
// ============== Reverse Matrix ================ //
inline void bgc_tangent_pair_get_reverse_matrix_fp32(const BgcTangentPairFP32* tangent, BgcMatrix2x2FP32* matrix)
{
matrix->r1c1 = tangent->cos;
matrix->r1c2 = tangent->sin;
matrix->r2c1 = -tangent->sin;
matrix->r2c2 = tangent->cos;
}
inline void bgc_tangent_pair_get_reverse_matrix_fp64(const BgcTangentPairFP64* tangent, BgcMatrix2x2FP64* matrix)
{
matrix->r1c1 = tangent->cos;
matrix->r1c2 = tangent->sin;
matrix->r2c1 = -tangent->sin;
matrix->r2c2 = tangent->cos;
}
// ================ Turn Vector ================= //
inline void bgc_tangent_pair_turn_vector_fp32(const BgcTangentPairFP32* tangent, const BgcVector2FP32* vector, BgcVector2FP32* result)
{
const float x1 = tangent->cos * vector->x1 - tangent->sin * vector->x2;
const float x2 = tangent->sin * vector->x1 + tangent->cos * vector->x2;
result->x1 = x1;
result->x2 = x2;
}
inline void bgc_tangent_pair_turn_vector_fp64(const BgcTangentPairFP64* tangent, const BgcVector2FP64* vector, BgcVector2FP64* result)
{
const double x1 = tangent->cos * vector->x1 - tangent->sin * vector->x2;
const double x2 = tangent->sin * vector->x1 + tangent->cos * vector->x2;
result->x1 = x1;
result->x2 = x2;
}
// ============ Turn Vector Backward ============ //
inline void bgc_tangent_pair_turn_vector_back_fp32(const BgcTangentPairFP32* tangent, const BgcVector2FP32* vector, BgcVector2FP32* result)
{
const float x1 = tangent->sin * vector->x2 + tangent->cos * vector->x1;
const float x2 = tangent->cos * vector->x2 - tangent->sin * vector->x1;
result->x1 = x1;
result->x2 = x2;
}
inline void bgc_tangent_pair_turn_vector_back_fp64(const BgcTangentPairFP64* tangent, const BgcVector2FP64* vector, BgcVector2FP64* result)
{
const double x1 = tangent->sin * vector->x2 + tangent->cos * vector->x1;
const double x2 = tangent->cos * vector->x2 - tangent->sin * vector->x1;
result->x1 = x1;
result->x2 = x2;
}
// ================== Are Close ================= //
inline int bgc_tangent_pair_are_close_fp32(const BgcTangentPairFP32* tangent1, const BgcTangentPairFP32* tangent2)
{
const float d_cos = tangent1->cos - tangent2->cos;
const float d_sin = tangent1->sin - tangent2->sin;
return d_cos * d_cos + d_sin * d_sin <= BGC_SQUARE_EPSYLON_FP32;
}
inline int bgc_tangent_pair_are_close_fp64(const BgcTangentPairFP64* tangent1, const BgcTangentPairFP64* tangent2)
{
const double d_cos = tangent1->cos - tangent2->cos;
const double d_sin = tangent1->sin - tangent2->sin;
return d_cos * d_cos + d_sin * d_sin <= BGC_SQUARE_EPSYLON_FP64;
}
#endif

View file

@ -33,12 +33,6 @@ extern inline void bgc_vector2_reverse_fp64(const BgcVector2FP64* vector, BgcVec
extern inline int bgc_vector2_normalize_fp32(const BgcVector2FP32* vector, BgcVector2FP32* normalized);
extern inline int bgc_vector2_normalize_fp64(const BgcVector2FP64* vector, BgcVector2FP64* normalized);
extern inline void bgc_vector2_complex_conjugate_fp32(const BgcVector2FP32* vector, BgcVector2FP32* conjugate);
extern inline void bgc_vector2_complex_conjugate_fp64(const BgcVector2FP64* vector, BgcVector2FP64* conjugate);
extern inline int bgc_vector2_complex_invert_fp32(const BgcVector2FP32* vector, BgcVector2FP32* inverted);
extern inline int bgc_vector2_complex_invert_fp64(const BgcVector2FP64* vector, BgcVector2FP64* inverted);
extern inline void bgc_vector2_add_fp32(const BgcVector2FP32* vector1, const BgcVector2FP32* vector2, BgcVector2FP32* sum);
extern inline void bgc_vector2_add_fp64(const BgcVector2FP64* vector1, const BgcVector2FP64* vector2, BgcVector2FP64* sum);
@ -78,12 +72,6 @@ extern inline double bgc_vector2_get_scalar_product_fp64(const BgcVector2FP64* v
extern inline float bgc_vector2_get_cross_product_fp32(const BgcVector2FP32* vector1, const BgcVector2FP32* vector2);
extern inline double bgc_vector2_get_cross_product_fp64(const BgcVector2FP64* vector1, const BgcVector2FP64* vector2);
extern inline void bgc_vector2_get_complex_product_fp32(const BgcVector2FP32* vector1, const BgcVector2FP32* vector2, BgcVector2FP32* product);
extern inline void bgc_vector2_get_complex_product_fp64(const BgcVector2FP64* vector1, const BgcVector2FP64* vector2, BgcVector2FP64* product);
extern inline int bgc_vector2_get_complex_ratio_fp32(const BgcVector2FP32* divident, const BgcVector2FP32* divisor, BgcVector2FP32* quotient);
extern inline int bgc_vector2_get_complex_ratio_fp64(const BgcVector2FP64* divident, const BgcVector2FP64* divisor, BgcVector2FP64* quotient);
extern inline float bgc_vector2_get_square_distance_fp32(const BgcVector2FP32* vector1, const BgcVector2FP32* vector2);
extern inline double bgc_vector2_get_square_distance_fp64(const BgcVector2FP64* vector1, const BgcVector2FP64* vector2);
@ -96,48 +84,6 @@ extern inline int bgc_vector2_are_close_enough_fp64(const BgcVector2FP64* vector
extern inline int bgc_vector2_are_close_fp32(const BgcVector2FP32* vector1, const BgcVector2FP32* vector2);
extern inline int bgc_vector2_are_close_fp64(const BgcVector2FP64* vector1, const BgcVector2FP64* vector2);
// =============== Complex Power ================ //
void bgc_vector2_get_complex_power_fp32(const BgcVector2FP32* base, const BgcVector2FP32* power, BgcVector2FP32* result)
{
const float base_square_modulus = bgc_vector2_get_square_modulus_fp32(base);
if (base_square_modulus <= BGC_SQUARE_EPSYLON_FP32) {
result->x1 = 0.0f;
result->x2 = 0.0f;
return;
}
const float log_modulus = logf(base_square_modulus) * 0.5f;
const float angle = atan2f(base->x2, base->x1);
const float result_modulus = expf(power->x1 * log_modulus - power->x2 * angle);
const float result_angle = power->x1 * angle + power->x2 * log_modulus;
result->x1 = result_modulus * cosf(result_angle);
result->x2 = result_modulus * sinf(result_angle);
}
void bgc_vector2_get_complex_power_fp64(const BgcVector2FP64* base, const BgcVector2FP64* power, BgcVector2FP64* result)
{
const double base_square_modulus = bgc_vector2_get_square_modulus_fp64(base);
if (base_square_modulus <= BGC_SQUARE_EPSYLON_FP64) {
result->x1 = 0.0;
result->x2 = 0.0;
return;
}
const double log_modulus = log(base_square_modulus) * 0.5;
const double angle = atan2(base->x2, base->x1);
const double result_modulus = exp(power->x1 * log_modulus - power->x2 * angle);
const double result_angle = power->x1 * angle + power->x2 * log_modulus;
result->x1 = result_modulus * cos(result_angle);
result->x2 = result_modulus * sin(result_angle);
}
// =================== Angle ==================== //
float bgc_vector2_get_angle_fp32(const BgcVector2FP32* vector1, const BgcVector2FP32* vector2, const BgcAngleUnitEnum unit)

View file

@ -202,54 +202,6 @@ inline int bgc_vector2_normalize_fp64(const BgcVector2FP64* vector, BgcVector2FP
return 1;
}
// ============= Complex Conjugate ============== //
inline void bgc_vector2_complex_conjugate_fp32(const BgcVector2FP32* vector, BgcVector2FP32* conjugate)
{
conjugate->x1 = vector->x1;
conjugate->x2 = -vector->x2;
}
inline void bgc_vector2_complex_conjugate_fp64(const BgcVector2FP64* vector, BgcVector2FP64* conjugate)
{
conjugate->x1 = vector->x1;
conjugate->x2 = -vector->x2;
}
// =============== Complex Invert =============== //
inline int bgc_vector2_complex_invert_fp32(const BgcVector2FP32* vector, BgcVector2FP32* inverted)
{
const float square_modulus = bgc_vector2_get_square_modulus_fp32(vector);
if (square_modulus <= BGC_SQUARE_EPSYLON_FP32 || square_modulus != square_modulus) {
return 0;
}
const float multiplicand = 1.0f / square_modulus;
inverted->x1 = vector->x1 * multiplicand;
inverted->x2 = -vector->x2 * multiplicand;
return 1;
}
inline int bgc_vector2_complex_invert_fp64(const BgcVector2FP64* vector, BgcVector2FP64* inverted)
{
const double square_modulus = bgc_vector2_get_square_modulus_fp64(vector);
if (square_modulus <= BGC_SQUARE_EPSYLON_FP64 || square_modulus != square_modulus) {
return 0;
}
const double multiplicand = 1.0 / square_modulus;
inverted->x1 = vector->x1 * multiplicand;
inverted->x2 = -vector->x2 * multiplicand;
return 1;
}
// ==================== Add ===================== //
inline void bgc_vector2_add_fp32(const BgcVector2FP32* vector1, const BgcVector2FP32* vector2, BgcVector2FP32* sum)
@ -450,72 +402,6 @@ inline double bgc_vector2_get_cross_product_fp64(const BgcVector2FP64* vector1,
return vector1->x1 * vector2->x2 - vector1->x2 * vector2->x1;
}
// ============ Get Complex Product ============= //
inline void bgc_vector2_get_complex_product_fp32(const BgcVector2FP32* vector1, const BgcVector2FP32* vector2, BgcVector2FP32* result)
{
const float x1 = vector1->x1 * vector2->x1 - vector1->x2 * vector2->x2;
const float x2 = vector1->x1 * vector2->x2 + vector1->x2 * vector2->x1;
result->x1 = x1;
result->x2 = x2;
}
inline void bgc_vector2_get_complex_product_fp64(const BgcVector2FP64* vector1, const BgcVector2FP64* vector2, BgcVector2FP64* result)
{
const double x1 = vector1->x1 * vector2->x1 - vector1->x2 * vector2->x2;
const double x2 = vector1->x1 * vector2->x2 + vector1->x2 * vector2->x1;
result->x1 = x1;
result->x2 = x2;
}
// ============= Get Complex Ratio ============== //
inline int bgc_vector2_get_complex_ratio_fp32(const BgcVector2FP32* divident, const BgcVector2FP32* divisor, BgcVector2FP32* quotient)
{
const float square_modulus = bgc_vector2_get_square_modulus_fp32(divisor);
if (square_modulus <= BGC_SQUARE_EPSYLON_FP32) {
return 0;
}
const float x1 = divident->x1 * divisor->x1 + divident->x2 * divisor->x2;
const float x2 = divident->x2 * divisor->x1 - divident->x1 * divisor->x2;
const float multiplier = 1.0f / square_modulus;
quotient->x1 = x1 * multiplier;
quotient->x2 = x2 * multiplier;
return 1;
}
inline int bgc_vector2_get_complex_ratio_fp64(const BgcVector2FP64* divident, const BgcVector2FP64* divisor, BgcVector2FP64* quotient)
{
const double square_modulus = bgc_vector2_get_square_modulus_fp64(divisor);
if (square_modulus <= BGC_SQUARE_EPSYLON_FP64) {
return 0;
}
const double x1 = divident->x1 * divisor->x1 + divident->x2 * divisor->x2;
const double x2 = divident->x2 * divisor->x1 - divident->x1 * divisor->x2;
const double multiplier = 1.0 / square_modulus;
quotient->x1 = x1 * multiplier;
quotient->x2 = x2 * multiplier;
return 1;
}
// ============= Get Complex Power ============== //
void bgc_vector2_get_complex_power_fp32(const BgcVector2FP32* base, const BgcVector2FP32* power, BgcVector2FP32* result);
void bgc_vector2_get_complex_power_fp64(const BgcVector2FP64* base, const BgcVector2FP64* power, BgcVector2FP64* result);
// ================= Get Angle ================== //
float bgc_vector2_get_angle_fp32(const BgcVector2FP32* vector1, const BgcVector2FP32* vector2, const BgcAngleUnitEnum unit);

View file

@ -158,17 +158,9 @@ void bgc_versor_get_rotation_fp32(const BgcVersorFP32* versor, BgcRotation3FP32*
return;
}
const float s0s0 = versor->s0 * versor->s0;
const float x1x1 = versor->x1 * versor->x1;
const float x2x2 = versor->x2 * versor->x2;
const float x3x3 = versor->x3 * versor->x3;
const float multiplier = sqrtf(1.0f / (versor->x1 * versor->x1 + versor->x2 * versor->x2 + versor->x3 * versor->x3));
const float square_module = (s0s0 + x1x1) + (x2x2 + x3x3);
const float square_vector = x1x1 + (x2x2 + x3x3);
result->radians = 2.0f * acosf(versor->s0 / sqrtf(square_module));
const float multiplier = sqrtf(1.0f / square_vector);
result->radians = 2.0f * acosf(versor->s0);
result->axis.x1 = versor->x1 * multiplier;
result->axis.x2 = versor->x2 * multiplier;
@ -182,19 +174,45 @@ void bgc_versor_get_rotation_fp64(const BgcVersorFP64* versor, BgcRotation3FP64*
return;
}
const double s0s0 = versor->s0 * versor->s0;
const double x1x1 = versor->x1 * versor->x1;
const double x2x2 = versor->x2 * versor->x2;
const double x3x3 = versor->x3 * versor->x3;
const double multiplier = sqrt(1.0 / (versor->x1 * versor->x1 + versor->x2 * versor->x2 + versor->x3 * versor->x3));
const double square_module = (s0s0 + x1x1) + (x2x2 + x3x3);
const double square_vector = x1x1 + (x2x2 + x3x3);
result->radians = 2.0 * acos(versor->s0 / sqrt(square_module));
const double multiplier = sqrt(1.0 / square_vector);
result->radians = 2.0 * acos(versor->s0);
result->axis.x1 = versor->x1 * multiplier;
result->axis.x2 = versor->x2 * multiplier;
result->axis.x3 = versor->x3 * multiplier;
}
// =============== Get Exponation =============== //
void bgc_versor_get_exponation_fp32(const BgcVersorFP32* base, const float exponent, BgcVersorFP32* power)
{
const float square_vector = base->x1 * base->x1 + base->x2 * base->x2 + base->x3 * base->x3;
if (square_vector <= BGC_SQUARE_EPSYLON_FP32) {
bgc_versor_reset_fp32(power);
return;
}
const float angle = acosf(base->s0) * exponent;
const float multiplier = sinf(angle) / sqrtf(square_vector);
bgc_versor_set_values_fp32(cosf(angle), base->x1 * multiplier, base->x2 * multiplier, base->x3 * multiplier, power);
}
void bgc_versor_get_exponation_fp64(const BgcVersorFP64* base, const double exponent, BgcVersorFP64* power)
{
const double square_vector = base->x1 * base->x1 + base->x2 * base->x2 + base->x3 * base->x3;
if (square_vector <= BGC_SQUARE_EPSYLON_FP64) {
bgc_versor_reset_fp64(power);
return;
}
const double angle = acos(base->s0) * exponent;
const double multiplier = sin(angle) / sqrt(square_vector);
bgc_versor_set_values_fp64(cos(angle), base->x1 * multiplier, base->x2 * multiplier, base->x3 * multiplier, power);
}

View file

@ -274,6 +274,12 @@ inline void bgc_versor_invert_fp64(const BgcVersorFP64* versor, BgcVersorFP64* i
twin->x3 = -versor->x3;
}
// =============== Get Exponation =============== //
void bgc_versor_get_exponation_fp32(const BgcVersorFP32* base, const float exponent, BgcVersorFP32* power);
void bgc_versor_get_exponation_fp64(const BgcVersorFP64* base, const double exponent, BgcVersorFP64* power);
// ================ Combination ================= //
inline void bgc_versor_combine_fp32(const BgcVersorFP32* second, const BgcVersorFP32* first, BgcVersorFP32* result)