diff --git a/basic-geometry/basic-geometry.vcxproj b/basic-geometry/basic-geometry.vcxproj
index 2b985f5..bd39f43 100644
--- a/basic-geometry/basic-geometry.vcxproj
+++ b/basic-geometry/basic-geometry.vcxproj
@@ -25,6 +25,10 @@
+
+
+
+
@@ -47,6 +51,10 @@
+
+
+
+
diff --git a/basic-geometry/basic-geometry.vcxproj.filters b/basic-geometry/basic-geometry.vcxproj.filters
index 5200901..4f47928 100644
--- a/basic-geometry/basic-geometry.vcxproj.filters
+++ b/basic-geometry/basic-geometry.vcxproj.filters
@@ -84,6 +84,18 @@
Файлы заголовков
+
+ Файлы заголовков
+
+
+ Файлы заголовков
+
+
+ Файлы заголовков
+
+
+ Файлы заголовков
+
@@ -137,5 +149,17 @@
Исходные файлы
+
+ Исходные файлы
+
+
+ Исходные файлы
+
+
+ Исходные файлы
+
+
+ Исходные файлы
+
\ No newline at end of file
diff --git a/basic-geometry/dual-number.c b/basic-geometry/dual-number.c
new file mode 100644
index 0000000..a8da6d7
--- /dev/null
+++ b/basic-geometry/dual-number.c
@@ -0,0 +1,13 @@
+#include "dual-number.h"
+
+inline void bgc_fp32_dual_number_reset(BGC_FP32_DualNumber* number);
+inline void bgc_fp64_dual_number_reset(BGC_FP64_DualNumber* number);
+
+inline void bgc_fp32_dual_number_make(BGC_FP32_DualNumber* number, const float real, const float dual);
+inline void bgc_fp64_dual_number_make(BGC_FP64_DualNumber* number, const double real, const double dual);
+
+inline void bgc_fp32_dual_number_copy(BGC_FP32_DualNumber* destination, const BGC_FP32_DualNumber* source);
+inline void bgc_fp64_dual_number_copy(BGC_FP64_DualNumber* destination, const BGC_FP64_DualNumber* source);
+
+inline void bgc_fp32_dual_number_swap(BGC_FP32_DualNumber* first, BGC_FP32_DualNumber* second);
+inline void bgc_fp64_dual_number_swap(BGC_FP64_DualNumber* first, BGC_FP64_DualNumber* second);
diff --git a/basic-geometry/dual-number.h b/basic-geometry/dual-number.h
new file mode 100644
index 0000000..3a1eaf5
--- /dev/null
+++ b/basic-geometry/dual-number.h
@@ -0,0 +1,70 @@
+#ifndef _BGC_DUAL_NUMBER_H_
+#define _BGC_DUAL_NUMBER_H_
+
+// =================== Types ==================== //
+
+typedef struct {
+ float real, dual;
+} BGC_FP32_DualNumber;
+
+typedef struct {
+ double real, dual;
+} BGC_FP64_DualNumber;
+
+// =================== Reset ==================== //
+
+inline void bgc_fp32_dual_number_reset(BGC_FP32_DualNumber* number)
+{
+ number->real = 0.0f;
+ number->dual = 0.0f;
+}
+
+inline void bgc_fp64_dual_number_reset(BGC_FP64_DualNumber* number)
+{
+ number->real = 0.0;
+ number->dual = 0.0;
+}
+
+// ==================== Make ==================== //
+
+inline void bgc_fp32_dual_number_make(BGC_FP32_DualNumber* number, const float real, const float dual)
+{
+ number->real = real;
+ number->dual = dual;
+}
+
+inline void bgc_fp64_dual_number_make(BGC_FP64_DualNumber* number, const double real, const double dual)
+{
+ number->real = real;
+ number->dual = dual;
+}
+
+// ==================== Copy ==================== //
+
+inline void bgc_fp32_dual_number_copy(BGC_FP32_DualNumber* destination, const BGC_FP32_DualNumber* source)
+{
+ destination->real = source->real;
+ destination->dual = source->dual;
+}
+
+inline void bgc_fp64_dual_number_copy(BGC_FP64_DualNumber* destination, const BGC_FP64_DualNumber* source)
+{
+ destination->real = source->real;
+ destination->dual = source->dual;
+}
+
+// ==================== Swap ==================== //
+
+inline void bgc_fp32_dual_number_swap(BGC_FP32_DualNumber* first, BGC_FP32_DualNumber* second)
+{
+ first->real = second->real;
+ first->dual = second->dual;
+}
+
+inline void bgc_fp64_dual_number_swap(BGC_FP64_DualNumber* first, BGC_FP64_DualNumber* second)
+{
+ first->real = second->real;
+ first->dual = second->dual;
+}
+
+#endif
diff --git a/basic-geometry/dual-vector3.c b/basic-geometry/dual-vector3.c
new file mode 100644
index 0000000..b222db1
--- /dev/null
+++ b/basic-geometry/dual-vector3.c
@@ -0,0 +1,22 @@
+#include "./dual-vector3.h"
+
+inline void bgc_fp32_dual_vector3_reset(BGC_FP32_DualVector3* vector);
+inline void bgc_fp64_dual_vector3_reset(BGC_FP64_DualVector3* vector);
+
+inline void bgc_fp32_dual_vector3_make(BGC_FP32_DualVector3* vector, const BGC_FP32_Vector3* real, const BGC_FP32_Vector3* dual);
+inline void bgc_fp64_dual_vector3_make(BGC_FP64_DualVector3* vector, const BGC_FP64_Vector3* real, const BGC_FP64_Vector3* dual);
+
+inline void bgc_fp32_dual_vector3_set_real_values(BGC_FP32_DualVector3* vector, const float x1, const float x2, const float x3);
+inline void bgc_fp64_dual_vector3_set_real_values(BGC_FP64_DualVector3* vector, const double x1, const double x2, const double x3);
+
+inline void bgc_fp32_dual_vector3_set_dual_values(BGC_FP32_DualVector3* vector, const float x1, const float x2, const float x3);
+inline void bgc_fp64_dual_vector3_set_dual_values(BGC_FP64_DualVector3* vector, const double x1, const double x2, const double x3);
+
+inline void bgc_fp32_dual_vector3_add(BGC_FP32_DualVector3* sum, const BGC_FP32_DualVector3* first, const BGC_FP32_DualVector3* second);
+inline void bgc_fp64_dual_vector3_add(BGC_FP64_DualVector3* sum, const BGC_FP64_DualVector3* first, const BGC_FP64_DualVector3* second);
+
+inline void bgc_fp32_dual_vector3_add_scaled(BGC_FP32_DualVector3* sum, const BGC_FP32_DualVector3* base_vector, const BGC_FP32_DualVector3* scalable_vector, const float scale);
+inline void bgc_fp64_dual_vector3_add_scaled(BGC_FP64_DualVector3* sum, const BGC_FP64_DualVector3* base_vector, const BGC_FP64_DualVector3* scalable_vector, const double scale);
+
+inline void bgc_fp32_dual_vector3_subtract(BGC_FP32_DualVector3* difference, const BGC_FP32_DualVector3* minuend, const BGC_FP32_DualVector3* subtrahend);
+inline void bgc_fp64_dual_vector3_subtract(BGC_FP64_DualVector3* difference, const BGC_FP64_DualVector3* minuend, const BGC_FP64_DualVector3* subtrahend);
diff --git a/basic-geometry/dual-vector3.h b/basic-geometry/dual-vector3.h
new file mode 100644
index 0000000..b0df5b8
--- /dev/null
+++ b/basic-geometry/dual-vector3.h
@@ -0,0 +1,146 @@
+#ifndef _BGC_DUAL_VECTOR3_H_INCLUDE_
+#define _BGC_DUAL_VECTOR3_H_INCLUDE_
+
+#include "./vector3.h"
+
+// =================== Types ==================== //
+
+typedef struct {
+ BGC_FP32_Vector3 real, dual;
+} BGC_FP32_DualVector3;
+
+typedef struct {
+ BGC_FP64_Vector3 real, dual;
+} BGC_FP64_DualVector3;
+
+// =================== Reset ==================== //
+
+inline void bgc_fp32_dual_vector3_reset(BGC_FP32_DualVector3* vector)
+{
+ bgc_fp32_vector3_reset(&vector->real);
+ bgc_fp32_vector3_reset(&vector->dual);
+}
+
+inline void bgc_fp64_dual_vector3_reset(BGC_FP64_DualVector3* vector)
+{
+ bgc_fp64_vector3_reset(&vector->real);
+ bgc_fp64_vector3_reset(&vector->dual);
+}
+
+// ==================== Make ==================== //
+
+inline void bgc_fp32_dual_vector3_make(BGC_FP32_DualVector3* vector, const BGC_FP32_Vector3* real, const BGC_FP32_Vector3* dual)
+{
+ bgc_fp32_vector3_copy(&vector->real, real);
+ bgc_fp32_vector3_copy(&vector->dual, dual);
+}
+
+inline void bgc_fp64_dual_vector3_make(BGC_FP64_DualVector3* vector, const BGC_FP64_Vector3* real, const BGC_FP64_Vector3* dual)
+{
+ bgc_fp64_vector3_copy(&vector->real, real);
+ bgc_fp64_vector3_copy(&vector->dual, dual);
+}
+
+// ================== Set Real ================== //
+
+inline void bgc_fp32_dual_vector3_set_real_values(BGC_FP32_DualVector3* vector, const float x1, const float x2, const float x3)
+{
+ vector->real.x1 = x1;
+ vector->real.x2 = x2;
+ vector->real.x3 = x3;
+}
+
+inline void bgc_fp64_dual_vector3_set_real_values(BGC_FP64_DualVector3* vector, const double x1, const double x2, const double x3)
+{
+ vector->real.x1 = x1;
+ vector->real.x2 = x2;
+ vector->real.x3 = x3;
+}
+
+// ================== Set Dual ================== //
+
+inline void bgc_fp32_dual_vector3_set_dual_values(BGC_FP32_DualVector3* vector, const float x1, const float x2, const float x3)
+{
+ vector->dual.x1 = x1;
+ vector->dual.x2 = x2;
+ vector->dual.x3 = x3;
+}
+
+inline void bgc_fp64_dual_vector3_set_dual_values(BGC_FP64_DualVector3* vector, const double x1, const double x2, const double x3)
+{
+ vector->dual.x1 = x1;
+ vector->dual.x2 = x2;
+ vector->dual.x3 = x3;
+}
+
+// ==================== Add ===================== //
+
+inline void bgc_fp32_dual_vector3_add(BGC_FP32_DualVector3* sum, const BGC_FP32_DualVector3* first, const BGC_FP32_DualVector3* second)
+{
+ bgc_fp32_vector3_add(&sum->real, &first->real, &second->real);
+ bgc_fp32_vector3_add(&sum->dual, &first->dual, &second->dual);
+}
+
+inline void bgc_fp64_dual_vector3_add(BGC_FP64_DualVector3* sum, const BGC_FP64_DualVector3* first, const BGC_FP64_DualVector3* second)
+{
+ bgc_fp64_vector3_add(&sum->real, &first->real, &second->real);
+ bgc_fp64_vector3_add(&sum->dual, &first->dual, &second->dual);
+}
+
+// ================= Add Scaled ================= //
+
+inline void bgc_fp32_dual_vector3_add_scaled(BGC_FP32_DualVector3* sum, const BGC_FP32_DualVector3* base_vector, const BGC_FP32_DualVector3* scalable_vector, const float scale)
+{
+ bgc_fp32_vector3_add_scaled(&sum->real, &base_vector->real, &scalable_vector->real, scale);
+ bgc_fp32_vector3_add_scaled(&sum->dual, &base_vector->dual, &scalable_vector->dual, scale);
+}
+
+inline void bgc_fp64_dual_vector3_add_scaled(BGC_FP64_DualVector3* sum, const BGC_FP64_DualVector3* base_vector, const BGC_FP64_DualVector3* scalable_vector, const double scale)
+{
+ bgc_fp64_vector3_add_scaled(&sum->real, &base_vector->real, &scalable_vector->real, scale);
+ bgc_fp64_vector3_add_scaled(&sum->dual, &base_vector->dual, &scalable_vector->dual, scale);
+}
+
+// ================== Subtract ================== //
+
+inline void bgc_fp32_dual_vector3_subtract(BGC_FP32_DualVector3* difference, const BGC_FP32_DualVector3* minuend, const BGC_FP32_DualVector3* subtrahend)
+{
+ bgc_fp32_vector3_subtract(&difference->real, &minuend->real, &subtrahend->real);
+ bgc_fp32_vector3_subtract(&difference->dual, &minuend->dual, &subtrahend->dual);
+}
+
+inline void bgc_fp64_dual_vector3_subtract(BGC_FP64_DualVector3* difference, const BGC_FP64_DualVector3* minuend, const BGC_FP64_DualVector3* subtrahend)
+{
+ bgc_fp64_vector3_subtract(&difference->real, &minuend->real, &subtrahend->real);
+ bgc_fp64_vector3_subtract(&difference->dual, &minuend->dual, &subtrahend->dual);
+}
+
+// ================== Average2 ================== //
+
+inline void bgc_fp32_dual_vector3_get_mean2(BGC_FP32_DualVector3* mean, const BGC_FP32_DualVector3* vector1, const BGC_FP32_DualVector3* vector2)
+{
+ bgc_fp32_vector3_get_mean2(&mean->real, &vector1->real, &vector2->real);
+ bgc_fp32_vector3_get_mean2(&mean->dual, &vector1->dual, &vector2->dual);
+}
+
+inline void bgc_fp64_dual_vector3_get_mean2(BGC_FP64_DualVector3* mean, const BGC_FP64_DualVector3* vector1, const BGC_FP64_DualVector3* vector2)
+{
+ bgc_fp64_vector3_get_mean2(&mean->real, &vector1->real, &vector2->real);
+ bgc_fp64_vector3_get_mean2(&mean->dual, &vector1->dual, &vector2->dual);
+}
+
+// ================== Average3 ================== //
+
+inline void bgc_fp32_dual_vector3_get_mean3(BGC_FP32_DualVector3* mean, const BGC_FP32_DualVector3* vector1, const BGC_FP32_DualVector3* vector2, const BGC_FP32_DualVector3* vector3)
+{
+ bgc_fp32_vector3_get_mean2(&mean->real, &vector1->real, &vector2->real, &vector3->real);
+ bgc_fp32_vector3_get_mean2(&mean->dual, &vector1->dual, &vector2->dual, &vector3->dual);
+}
+
+inline void bgc_fp64_dual_vector3_get_mean3(BGC_FP64_DualVector3* mean, const BGC_FP64_DualVector3* vector1, const BGC_FP64_DualVector3* vector2, const BGC_FP64_DualVector3* vector3)
+{
+ bgc_fp64_vector3_get_mean2(&mean->real, &vector1->real, &vector2->real, &vector3->real);
+ bgc_fp64_vector3_get_mean2(&mean->dual, &vector1->dual, &vector2->dual, &vector3->dual);
+}
+
+#endif
diff --git a/basic-geometry/dual-versor.c b/basic-geometry/dual-versor.c
new file mode 100644
index 0000000..e5ed49d
--- /dev/null
+++ b/basic-geometry/dual-versor.c
@@ -0,0 +1,10 @@
+#include "dual-versor.h"
+
+extern inline void bgc_fp32_dual_versor_reset(BGC_FP32_DualVersor* number);
+extern inline void bgc_fp64_dual_versor_reset(BGC_FP64_DualVersor* number);
+
+extern inline void bgc_fp32_dual_versor_copy(BGC_FP32_DualVersor* destination, const BGC_FP32_DualVersor* source);
+extern inline void bgc_fp64_dual_versor_copy(BGC_FP64_DualVersor* destination, const BGC_FP64_DualVersor* source);
+
+extern inline void bgc_fp32_dual_versor_swap(BGC_FP32_DualVersor* first, BGC_FP32_DualVersor* second);
+extern inline void bgc_fp64_dual_versor_swap(BGC_FP64_DualVersor* first, BGC_FP64_DualVersor* second);
diff --git a/basic-geometry/dual-versor.h b/basic-geometry/dual-versor.h
new file mode 100644
index 0000000..b1b6e81
--- /dev/null
+++ b/basic-geometry/dual-versor.h
@@ -0,0 +1,147 @@
+#ifndef _BGC_DUAL_VERSOR_H_
+#define _BGC_DUAL_VERSOR_H_
+
+// =================== Types ==================== //
+
+typedef struct {
+ struct {
+ float s0, x1, x2, x3;
+ } _real, _dual;
+} BGC_FP32_DualVersor;
+
+typedef struct {
+ struct {
+ double s0, x1, x2, x3;
+ } _real, _dual;
+} BGC_FP64_DualVersor;
+
+// =================== Reset ==================== //
+
+inline void bgc_fp32_dual_versor_reset(BGC_FP32_DualVersor* number)
+{
+ number->_real.s0 = 1.0f;
+ number->_real.x1 = 0.0f;
+ number->_real.x2 = 0.0f;
+ number->_real.x3 = 0.0f;
+
+ number->_dual.s0 = 0.0f;
+ number->_dual.x1 = 0.0f;
+ number->_dual.x2 = 0.0f;
+ number->_dual.x3 = 0.0f;
+}
+
+inline void bgc_fp64_dual_versor_reset(BGC_FP64_DualVersor* number)
+{
+ number->_real.s0 = 1.0f;
+ number->_real.x1 = 0.0f;
+ number->_real.x2 = 0.0f;
+ number->_real.x3 = 0.0f;
+
+ number->_dual.s0 = 0.0f;
+ number->_dual.x1 = 0.0f;
+ number->_dual.x2 = 0.0f;
+ number->_dual.x3 = 0.0f;
+}
+
+// ==================== Copy ==================== //
+
+inline void bgc_fp32_dual_versor_copy(BGC_FP32_DualVersor* destination, const BGC_FP32_DualVersor* source)
+{
+ destination->_real.s0 = source->_real.s0;
+ destination->_real.x1 = source->_real.x1;
+ destination->_real.x2 = source->_real.x2;
+ destination->_real.x3 = source->_real.x3;
+
+ destination->_dual.s0 = source->_dual.s0;
+ destination->_dual.x1 = source->_dual.x1;
+ destination->_dual.x2 = source->_dual.x2;
+ destination->_dual.x3 = source->_dual.x3;
+}
+
+inline void bgc_fp64_dual_versor_copy(BGC_FP64_DualVersor* destination, const BGC_FP64_DualVersor* source)
+{
+ destination->_real.s0 = source->_real.s0;
+ destination->_real.x1 = source->_real.x1;
+ destination->_real.x2 = source->_real.x2;
+ destination->_real.x3 = source->_real.x3;
+
+ destination->_dual.s0 = source->_dual.s0;
+ destination->_dual.x1 = source->_dual.x1;
+ destination->_dual.x2 = source->_dual.x2;
+ destination->_dual.x3 = source->_dual.x3;
+}
+
+// ==================== Swap ==================== //
+
+inline void bgc_fp32_dual_versor_swap(BGC_FP32_DualVersor* first, BGC_FP32_DualVersor* second)
+{
+ // Real
+ float s0 = second->_real.s0;
+ float x1 = second->_real.x1;
+ float x2 = second->_real.x2;
+ float x3 = second->_real.x3;
+
+ second->_real.s0 = first->_real.s0;
+ second->_real.x1 = first->_real.x1;
+ second->_real.x2 = first->_real.x2;
+ second->_real.x3 = first->_real.x3;
+
+ first->_real.s0 = s0;
+ first->_real.x1 = x1;
+ first->_real.x2 = x2;
+ first->_real.x3 = x3;
+
+ // Dual
+ s0 = second->_dual.s0;
+ x1 = second->_dual.x1;
+ x2 = second->_dual.x2;
+ x3 = second->_dual.x3;
+
+ second->_dual.s0 = first->_dual.s0;
+ second->_dual.x1 = first->_dual.x1;
+ second->_dual.x2 = first->_dual.x2;
+ second->_dual.x3 = first->_dual.x3;
+
+ first->_dual.s0 = s0;
+ first->_dual.x1 = x1;
+ first->_dual.x2 = x2;
+ first->_dual.x3 = x3;
+}
+
+inline void bgc_fp64_dual_versor_swap(BGC_FP64_DualVersor* first, BGC_FP64_DualVersor* second)
+{
+ // Real
+ double s0 = second->_real.s0;
+ double x1 = second->_real.x1;
+ double x2 = second->_real.x2;
+ double x3 = second->_real.x3;
+
+ second->_real.s0 = first->_real.s0;
+ second->_real.x1 = first->_real.x1;
+ second->_real.x2 = first->_real.x2;
+ second->_real.x3 = first->_real.x3;
+
+ first->_real.s0 = s0;
+ first->_real.x1 = x1;
+ first->_real.x2 = x2;
+ first->_real.x3 = x3;
+
+ // Dual
+ s0 = second->_dual.s0;
+ x1 = second->_dual.x1;
+ x2 = second->_dual.x2;
+ x3 = second->_dual.x3;
+
+ second->_dual.s0 = first->_dual.s0;
+ second->_dual.x1 = first->_dual.x1;
+ second->_dual.x2 = first->_dual.x2;
+ second->_dual.x3 = first->_dual.x3;
+
+ first->_dual.s0 = s0;
+ first->_dual.x1 = x1;
+ first->_dual.x2 = x2;
+ first->_dual.x3 = x3;
+}
+
+
+#endif