From 74be89f1f85aba78a2eb72dff3f4ccf080f64a76 Mon Sep 17 00:00:00 2001
From: Andrey Pokidov <9942846+Morgend@users.noreply.github.com>
Date: Wed, 26 Feb 2025 16:27:33 +0700
Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=B8=D0=BC=D0=B5?=
=?UTF-8?q?=D0=BD=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20tangent=20pair=20?=
=?UTF-8?q?=D0=B2=20=D1=87=D0=B8=D1=81=D0=BB=D0=B0=20=D0=9A=D0=BE=D1=82?=
=?UTF-8?q?=D1=81=D0=B0,=20=D0=B2=D1=8B=D0=B4=D0=B5=D0=BB=D0=B5=D0=BD?=
=?UTF-8?q?=D0=B8=D0=B5=20=D0=BA=D0=BE=D0=BC=D0=BF=D0=BB=D0=B5=D0=BA=D1=81?=
=?UTF-8?q?=D0=BD=D1=8B=D1=85=20=D1=87=D0=B8=D1=81=D0=B5=D0=BB=20=D0=B8?=
=?UTF-8?q?=D0=B7=20=D0=B4=D0=B2=D1=83=D0=BC=D0=B5=D1=80=D0=BD=D1=8B=D1=85?=
=?UTF-8?q?=20=D0=B2=D0=B5=D0=BA=D1=82=D0=BE=D1=80=D0=BE=D0=B2,=20=D0=B4?=
=?UTF-8?q?=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B2?=
=?UTF-8?q?=D0=BE=D0=B7=D0=B2=D0=B5=D0=B4=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B2?=
=?UTF-8?q?=20=D1=81=D0=BF=D0=B5=D0=B1=D0=B5=D0=BD=D1=8C=20=D0=B4=D0=BB?=
=?UTF-8?q?=D1=8F=20=D0=B2=D0=B5=D1=80=D0=BE=D1=81=D0=BE=D1=80=D0=B2=20?=
=?UTF-8?q?=D0=B8=20=D1=87=D0=B8=D1=81=D0=B5=D0=BB=20=D0=9A=D0=BE=D1=82?=
=?UTF-8?q?=D1=81=D0=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
basic-geometry-dev/main.c | 33 +-
basic-geometry/basic-geometry.cbp | 12 +-
basic-geometry/basic-geometry.h | 29 +-
basic-geometry/basic-geometry.vcxproj | 7 +-
basic-geometry/basic-geometry.vcxproj.filters | 18 +-
basic-geometry/complex.c | 124 ++++
basic-geometry/complex.h | 531 ++++++++++++++++++
basic-geometry/cotes-number.c | 82 +++
basic-geometry/cotes-number.h | 374 ++++++++++++
basic-geometry/quaternion.c | 4 +
basic-geometry/quaternion.h | 2 +
basic-geometry/tangent-pair.c | 79 ---
basic-geometry/tangent-pair.h | 352 ------------
basic-geometry/vector2.c | 54 --
basic-geometry/vector2.h | 114 ----
basic-geometry/versor.c | 58 +-
basic-geometry/versor.h | 6 +
17 files changed, 1233 insertions(+), 646 deletions(-)
create mode 100644 basic-geometry/complex.c
create mode 100644 basic-geometry/complex.h
create mode 100644 basic-geometry/cotes-number.c
create mode 100644 basic-geometry/cotes-number.h
delete mode 100644 basic-geometry/tangent-pair.c
delete mode 100644 basic-geometry/tangent-pair.h
diff --git a/basic-geometry-dev/main.c b/basic-geometry-dev/main.c
index 0f4ad34..901b4e3 100644
--- a/basic-geometry-dev/main.c
+++ b/basic-geometry-dev/main.c
@@ -79,7 +79,7 @@ void list_work(const uint_fast32_t amount, structure_fp32_t* list)
}
}
}
-
+/*
int main()
{
const unsigned int amount = 1000000;
@@ -121,3 +121,34 @@ int main()
return 0;
}
+*/
+
+/*
+int main() {
+ BgcComplexFP32 complex, exponent, result;
+
+ bgc_complex_set_values_fp32(0, 1, &complex);
+
+ bgc_complex_set_values_fp32(4, 0, &exponent);
+
+ bgc_complex_get_exponation_fp32(&complex, exponent.real, exponent.imaginary, &result);
+
+ printf("(%f, %f) ^ (%f, %f) = (%f, %f)\n", complex.real, complex.imaginary, exponent.real, exponent.imaginary, result.real, result.imaginary);
+
+ return 0;
+}
+*/
+
+int main() {
+ const float exponent = 2.0f;
+
+ BgcVersorFP32 turn, result;
+
+ bgc_versor_set_turn_fp32(0, 0, 1, 120, BGC_ANGLE_UNIT_DEGREES, &turn);
+
+ bgc_versor_get_exponation_fp32(&turn, exponent, &result);
+
+ printf("(%f, %f, %f, %f) ^ %f = (%f, %f, %f, %f)\n", turn.s0, turn.x1, turn.x2, turn.x3, exponent, result.s0, result.x1, result.x2, result.x3);
+
+ return 0;
+}
diff --git a/basic-geometry/basic-geometry.cbp b/basic-geometry/basic-geometry.cbp
index 3e21644..1dadfea 100644
--- a/basic-geometry/basic-geometry.cbp
+++ b/basic-geometry/basic-geometry.cbp
@@ -48,6 +48,14 @@
+
+
+
+
+
+
+
+
@@ -76,10 +84,6 @@
-
-
-
-
diff --git a/basic-geometry/basic-geometry.h b/basic-geometry/basic-geometry.h
index 5a3923c..fb83f61 100644
--- a/basic-geometry/basic-geometry.h
+++ b/basic-geometry/basic-geometry.h
@@ -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
diff --git a/basic-geometry/basic-geometry.vcxproj b/basic-geometry/basic-geometry.vcxproj
index 98620b5..6c60d06 100644
--- a/basic-geometry/basic-geometry.vcxproj
+++ b/basic-geometry/basic-geometry.vcxproj
@@ -21,6 +21,8 @@
+
+
@@ -28,7 +30,6 @@
-
@@ -36,6 +37,8 @@
+
+
@@ -44,7 +47,7 @@
-
+
diff --git a/basic-geometry/basic-geometry.vcxproj.filters b/basic-geometry/basic-geometry.vcxproj.filters
index 2349250..260e3e3 100644
--- a/basic-geometry/basic-geometry.vcxproj.filters
+++ b/basic-geometry/basic-geometry.vcxproj.filters
@@ -18,6 +18,12 @@
Файлы заголовков
+
+ Файлы заголовков
+
+
+ Файлы заголовков
+
Файлы заголовков
@@ -54,14 +60,17 @@
Файлы заголовков
-
- Файлы заголовков
-
Исходные файлы
+
+ Исходные файлы
+
+
+ Исходные файлы
+
Исходные файлы
@@ -95,8 +104,5 @@
Исходные файлы
-
- Исходные файлы
-
\ No newline at end of file
diff --git a/basic-geometry/complex.c b/basic-geometry/complex.c
new file mode 100644
index 0000000..59c6979
--- /dev/null
+++ b/basic-geometry/complex.c
@@ -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);
+}
diff --git a/basic-geometry/complex.h b/basic-geometry/complex.h
new file mode 100644
index 0000000..c7b77ff
--- /dev/null
+++ b/basic-geometry/complex.h
@@ -0,0 +1,531 @@
+#ifndef _BGC_COMPLEX_H_
+#define _BGC_COMPLEX_H_
+
+#include "utilities.h"
+#include "angle.h"
+
+#include
+
+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
diff --git a/basic-geometry/cotes-number.c b/basic-geometry/cotes-number.c
new file mode 100644
index 0000000..fc7cc57
--- /dev/null
+++ b/basic-geometry/cotes-number.c
@@ -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;
+}
diff --git a/basic-geometry/cotes-number.h b/basic-geometry/cotes-number.h
new file mode 100644
index 0000000..e4944a6
--- /dev/null
+++ b/basic-geometry/cotes-number.h
@@ -0,0 +1,374 @@
+#ifndef _BGC_COTES_NUMBER_H_
+#define _BGC_COTES_NUMBER_H_
+
+#include
+
+#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
diff --git a/basic-geometry/quaternion.c b/basic-geometry/quaternion.c
index 6694803..963dba7 100644
--- a/basic-geometry/quaternion.c
+++ b/basic-geometry/quaternion.c
@@ -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);
diff --git a/basic-geometry/quaternion.h b/basic-geometry/quaternion.h
index c88b66b..54be3fa 100644
--- a/basic-geometry/quaternion.h
+++ b/basic-geometry/quaternion.h
@@ -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)) {
diff --git a/basic-geometry/tangent-pair.c b/basic-geometry/tangent-pair.c
deleted file mode 100644
index c38571a..0000000
--- a/basic-geometry/tangent-pair.c
+++ /dev/null
@@ -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;
-}
diff --git a/basic-geometry/tangent-pair.h b/basic-geometry/tangent-pair.h
deleted file mode 100644
index 40c5c15..0000000
--- a/basic-geometry/tangent-pair.h
+++ /dev/null
@@ -1,352 +0,0 @@
-#ifndef _bgc_tangent_pair_H_
-#define _bgc_tangent_pair_H_
-
-#include
-
-#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
diff --git a/basic-geometry/vector2.c b/basic-geometry/vector2.c
index af738d4..b0b7c64 100644
--- a/basic-geometry/vector2.c
+++ b/basic-geometry/vector2.c
@@ -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)
diff --git a/basic-geometry/vector2.h b/basic-geometry/vector2.h
index dc8ff3c..8852721 100644
--- a/basic-geometry/vector2.h
+++ b/basic-geometry/vector2.h
@@ -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);
diff --git a/basic-geometry/versor.c b/basic-geometry/versor.c
index 393b9ea..0fadc5c 100644
--- a/basic-geometry/versor.c
+++ b/basic-geometry/versor.c
@@ -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);
+}
diff --git a/basic-geometry/versor.h b/basic-geometry/versor.h
index e5ea79e..895d249 100644
--- a/basic-geometry/versor.h
+++ b/basic-geometry/versor.h
@@ -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)