diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/include/electrostatic/electronetsoft/algorithm/arithmos/README.md b/electrostatic-sandbox-framework/electrostatic-core/src/include/electrostatic/electronetsoft/algorithm/arithmos/README.md index bb2e77c4..85746c2c 100644 --- a/electrostatic-sandbox-framework/electrostatic-core/src/include/electrostatic/electronetsoft/algorithm/arithmos/README.md +++ b/electrostatic-sandbox-framework/electrostatic-core/src/include/electrostatic/electronetsoft/algorithm/arithmos/README.md @@ -1,14 +1,14 @@ # Arithmos _αριθμός_ -Arithmos is a set of APIs that target different taxonomies of algorithms to solve problems through providing _algorithm generic utilities_, and several implementations for the common _abstract data types (adt)_ commonly encountered during solving problems while building commericial applications or participating in problem solving contests. +Arithmos is a set of APIs that target different taxonomies of algorithms to solve problems through providing _algorithm generic utilities_, and several implementations for the common _abstract data types (adt)_ commonly encountered during solving problems while building commercial applications or participating in problem solving contests. Arithmos is essentially composed of the following: - [x] Vector2d Library (Finished). -- [ ] Vector3d Library. -- [ ] MatrixNd Library. +- [x] Vector3d Library (Partially Finished). +- [x] MatrixNd Library (Partially Finished). - [ ] Discrete Sets Operations (Conjunctive, Disjunctive, Subtraction, Powersets, De'Morgans formulas). - [ ] Physics Simulation Library (Collision detection - Force Control - Objects interactions). -- [ ] Statistics Algoritms Library (Present in Java - WIP to port). +- [ ] Statistics Algorithms Library (Present in Java - WIP to port). - [ ] Differential and Integral Calculus Library. - [ ] Generic Algorithms Utilities Library. - [ ] Linear Algorithms Library. @@ -52,7 +52,7 @@ Most of these libraries rely on the _Generic Algorithms Utilities Library_; this - Hashing Algorithms. - [ ] Modular Arithmetics. - Un-hashing Algorithms. - - Switching Algebra ALgorithms. + - Switching Algebra Algorithms. - [ ] Elementary Bit switching. - [ ] Elementary Bit shifting. - [ ] Elementary Byte switching. diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/include/electrostatic/electronetsoft/algorithm/arithmos/vectorspaces/coordinate.h b/electrostatic-sandbox-framework/electrostatic-core/src/include/electrostatic/electronetsoft/algorithm/arithmos/vectorspaces/coordinate.h deleted file mode 100644 index a94953d0..00000000 --- a/electrostatic-sandbox-framework/electrostatic-core/src/include/electrostatic/electronetsoft/algorithm/arithmos/vectorspaces/coordinate.h +++ /dev/null @@ -1,77 +0,0 @@ -#if !(defined _vector2d_H_ || defined _vector3d_H_) -# error "Use vector2d or vector3d instead of this!" -#endif - -#ifndef _COORDINATE_H_ -#define _COORDINATE_H_ - -#include -#include - -#if defined (_VECTOR2D_USE_UINT8_) -# define coordinate uint8_t -# define mod_coordinate coordinate -# define vector2d_pow(v, p) ((uint8_t) powf(v, p)) -# define vector2d_atan2(y, x) ((uint8_t) atan2f(y, x)) -# define vector2d_acos(v) ((uint8_t) acosf(v)) -#elif defined (_VECTOR2D_USE_INT8_) -# define coordinate int8_t -# define mod_coordinate coordinate -# define vector2d_pow(v, p) ((int8_t) powf(v, p)) -# define vector2d_atan2(y, x) ((int8_t) atan2f(y, x)) -# define vector2d_acos(v) ((int8_t) acosf(v)) -#elif defined (_VECTOR2D_USE_UINT16_) -# define coordinate uint16_t -# define mod_coordinate coordinate -# define vector2d_pow(v, p) ((uint16_t) powf(v, p)) -# define vector2d_atan2(y, x) ((uint16_t) atan2f(y, x)) -# define vector2d_acos(v) ((uint16_t) acosf(v)) -#elif defined (_VECTOR2D_USE_INT16_) -# define coordinate int16_t -# define mod_coordinate coordinate -# define vector2d_pow(v, p) ((int16_t) powf(v, p)) -# define vector2d_atan2(y, x) ((int16_t) atan2f(y, x)) -# define vector2d_acos(v) ((int16_t) acosf(v)) -#elif defined (_VECTOR2D_USE_UINT32_) -# define coordinate uint32_t -# define mod_coordinate coordinate -# define vector2d_pow(v, p) ((uint32_t) powf(v, p)) -# define vector2d_atan2(y, x) ((uint32_t) atan2f(y, x)) -# define vector2d_acos(v) ((uint32_t) acosf(v)) -#elif defined (_VECTOR2D_USE_INT32_) -# define coordinate int32_t -# define mod_coordinate coordinate -# define vector2d_pow(v, p) ((int32_t) powf(v, p)) -# define vector2d_atan2(y, x) ((int32_t) atan2f(y, x)) -# define vector2d_acos(v) ((int32_t) acosf(v)) -#elif defined (_VECTOR2D_USE_UINT64_) -# define coordinate uint64_t -# define mod_coordinate coordinate -# define vector2d_pow(v, p) ((uint64_t) powl(v, p)) -# define vector2d_atan2(y, x) ((uint64_t) atan2l(y, x)) -# define vector2d_acos(v) ((uint64_t) acosl(v)) -#elif defined (_VECTOR2D_USE_INT64_) -# define coordinate int64_t -# define mod_coordinate coordinate -# define vector2d_pow(v, p) ((int64_t) powl(v, p)) -# define vector2d_atan2(y, x) ((int64_t) atan2l(y, x)) -# define vector2d_acos(v) ((int64_t) acosl(v)) -#elif defined (_VECTOR2D_USE_DOUBLE_) -# define coordinate double -# define mod_coordinate int64_t -# define vector2d_pow(v, p) ((double) powl(v, p)) -# define vector2d_atan2(y, x) ((double) atan2l(y, x)) -# define vector2d_acos(v) ((double) acosl(v)) -#else -// default program flow -typedef float coordinate; -typedef int32_t mod_coordinate; -# define vector2d_pow(v, p) ((float) pow(v, p)) -# define vector2d_atan2(y, x) ((float) atan2f(y, x)) -# define vector2d_acos(v) ((float) acosf(v)) -#endif - -#define vector2d_sqrt(v) vector2d_pow(v, 0.5) -#define vector2d_abs(v) ((coordinate) vector2d_sqrt(vector2d_pow(v, 2))) - -#endif // _COORDINATE_H_ diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/include/electrostatic/electronetsoft/algorithm/arithmos/vectorspaces/matrix/matrix.h b/electrostatic-sandbox-framework/electrostatic-core/src/include/electrostatic/electronetsoft/algorithm/arithmos/vectorspaces/matrix/matrix.h new file mode 100644 index 00000000..197d0538 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/include/electrostatic/electronetsoft/algorithm/arithmos/vectorspaces/matrix/matrix.h @@ -0,0 +1,81 @@ +#ifndef _MAT_ND_H_ +#define _MAT_ND_H_ + +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct matrix { + vec_component **element; + uint64_t m; + uint64_t n; +}; + +struct mat_processors { + status_code (*on_entry_iterated)(mat_proc_sig); + status_code (*on_row_iterated)(mat_proc_sig); + status_code (*on_column_iterated)(mat_proc_sig); + status_code (*on_binary_op_preprocessor)(mat_binary_op_sig); + status_code (*on_binary_op_postprocessor)(mat_binary_op_sig); + status_code (*on_unary_op_preprocessor)(mat_proc_sig); + status_code (*on_elementary_op_postprocessor)(mat_proc_sig); + void (*on_op_success)(mat_proc_sig); + void (*on_op_failure)(mat_proc_sig, status_code); + caller_graph *root; + void *metadata; +}; + +struct mat_binary_op_sig { + matrix m0; + matrix m1; + uint64_t row_index; + uint64_t col_index; + mat_processors proc; + void *metadata; +}; + +struct mat_proc_sig { + matrix mat; + uint64_t row_index; + uint64_t col_index; + mat_processors proc; + caller_graph caller; + void *metadata; +}; + +static inline status_code is_last_column(matrix mat, uint64_t index) { + return index != 0 // the last column is never at the first index! + && (index % (mat.n - 1) == 0) + && ASSERTION_SUCCESS; +} + +static inline status_code is_last_row(matrix mat, uint64_t index) { + return index != 0 // the last row is never at the first index! + && (index % (mat.m - 1) == 0) + && ASSERTION_SUCCESS; +} + +status_code mat_add(matrix, matrix, matrix *, mat_processors); +status_code mat_subtract(matrix, matrix, matrix *, mat_processors); +status_code mat_product(matrix, matrix, matrix *, mat_processors); +status_code mat_scalar_prod(matrix, vec_component, matrix *, mat_processors); +status_code mat_scalar_divide(matrix, vec_component, matrix *, mat_processors); +status_code mat_create_rotator_matrix(vec_component, matrix *, mat_processors *); +status_code mat_create_from_vector2d(vector2d, matrix *, mat_processors); +status_code mat_create_from_vector3d(vector3d, matrix *, mat_processors); +status_code mat_iterate_rows(matrix, mat_processors); +status_code mat_iterate_columns(matrix, mat_processors); +status_code mat_iterate_elements(matrix, mat_iterator, mat_processors); + +#ifdef __cplusplus +}; +#endif + +#endif \ No newline at end of file diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/include/electrostatic/electronetsoft/algorithm/arithmos/vectorspaces/vec_component.h b/electrostatic-sandbox-framework/electrostatic-core/src/include/electrostatic/electronetsoft/algorithm/arithmos/vectorspaces/vec_component.h new file mode 100644 index 00000000..f6c0de95 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/include/electrostatic/electronetsoft/algorithm/arithmos/vectorspaces/vec_component.h @@ -0,0 +1,88 @@ +#if !(defined __VECTOR_2D_H_ || defined __VECTOR_3D_H_) +# error "Use vector2d or vector3d instead of this!" +#endif + +#ifndef __VEC_COMPONENT_H_ +#define __VEC_COMPONENT_H_ + +#include +#include + +#if defined (_VECTOR2D_USE_UINT8_) +# define vec_component uint8_t +# define mod_vec_component vec_component +# define vector2d_pow(v, p) ((uint8_t) powf(v, p)) +# define vector2d_atan2(y, x) ((uint8_t) atan2f(y, x)) +# define vector2d_acos(v) ((uint8_t) acosf(v)) +# define vector2d_cos(v) ((uint8_t) cosf(v)) +#elif defined (_VECTOR2D_USE_INT8_) +# define vec_component int8_t +# define mod_vec_component vec_component +# define vector2d_pow(v, p) ((int8_t) powf(v, p)) +# define vector2d_atan2(y, x) ((int8_t) atan2f(y, x)) +# define vector2d_acos(v) ((int8_t) acosf(v)) +# define vector2d_cos(v) ((int8_t) cosf(v)) +#elif defined (_VECTOR2D_USE_UINT16_) +# define vec_component uint16_t +# define mod_vec_component vec_component +# define vector2d_pow(v, p) ((uint16_t) powf(v, p)) +# define vector2d_atan2(y, x) ((uint16_t) atan2f(y, x)) +# define vector2d_acos(v) ((uint16_t) acosf(v)) +# define vector2d_cos(v) ((uint16_t) cosf(v)) +#elif defined (_VECTOR2D_USE_INT16_) +# define vec_component int16_t +# define mod_vec_component vec_component +# define vector2d_pow(v, p) ((int16_t) powf(v, p)) +# define vector2d_atan2(y, x) ((int16_t) atan2f(y, x)) +# define vector2d_acos(v) ((int16_t) acosf(v)) +# define vector2d_cos(v) ((int16_t) cosf(v)) +#elif defined (_VECTOR2D_USE_UINT32_) +# define vec_component uint32_t +# define mod_vec_component vec_component +# define vector2d_pow(v, p) ((uint32_t) powf(v, p)) +# define vector2d_atan2(y, x) ((uint32_t) atan2f(y, x)) +# define vector2d_acos(v) ((uint32_t) acosf(v)) +# define vector2d_cos(v) ((uint32_t) cosf(v)) +#elif defined (_VECTOR2D_USE_INT32_) +# define vec_component int32_t +# define mod_vec_component vec_component +# define vector2d_pow(v, p) ((int32_t) powf(v, p)) +# define vector2d_atan2(y, x) ((int32_t) atan2f(y, x)) +# define vector2d_acos(v) ((int32_t) acosf(v)) +# define vector2d_cos(v) ((int32_t) cosf(v)) +#elif defined (_VECTOR2D_USE_UINT64_) +# define vec_component uint64_t +# define mod_vec_component vec_component +# define vector2d_pow(v, p) ((uint64_t) powl(v, p)) +# define vector2d_atan2(y, x) ((uint64_t) atan2l(y, x)) +# define vector2d_acos(v) ((uint64_t) acosl(v)) +# define vector2d_cos(v) ((uint64_t) cosf(v)) +#elif defined (_VECTOR2D_USE_INT64_) +# define vec_component int64_t +# define mod_vec_component vec_component +# define vector2d_pow(v, p) ((int64_t) powl(v, p)) +# define vector2d_atan2(y, x) ((int64_t) atan2l(y, x)) +# define vector2d_acos(v) ((int64_t) acosl(v)) +# define vector2d_cos(v) ((int64_t) cosf(v)) +#elif defined (_VECTOR2D_USE_DOUBLE_) +# define vec_component double +# define mod_vec_component int64_t +# define vector2d_pow(v, p) ((double) powl(v, p)) +# define vector2d_atan2(y, x) ((double) atan2l(y, x)) +# define vector2d_acos(v) ((double) acosl(v)) +# define vector2d_cos(v) ((double) cosf(v)) +#else +// default program flow +typedef float vec_component; +typedef int32_t mod_vec_component; +# define vector2d_pow(v, p) ((float) pow(v, p)) +# define vector2d_atan2(y, x) ((float) atan2f(y, x)) +# define vector2d_acos(v) ((float) acosf(v)) +# define vector2d_cos(v) ((float) cosf(v)) +# define vector2d_sin(v) ((float) sinf(v)) +#endif + +#define vector2d_sqrt(v) vector2d_pow(v, 0.5) +#define vector2d_abs(v) ((vec_component) vector2d_sqrt(vector2d_pow(v, 2))) + +#endif // __VEC_COMPONENT_H_ diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/include/electrostatic/electronetsoft/algorithm/arithmos/vectorspaces/vector2d/vector2d.h b/electrostatic-sandbox-framework/electrostatic-core/src/include/electrostatic/electronetsoft/algorithm/arithmos/vectorspaces/vector2d/vector2d.h index f1518a01..e856c2a6 100644 --- a/electrostatic-sandbox-framework/electrostatic-core/src/include/electrostatic/electronetsoft/algorithm/arithmos/vectorspaces/vector2d/vector2d.h +++ b/electrostatic-sandbox-framework/electrostatic-core/src/include/electrostatic/electronetsoft/algorithm/arithmos/vectorspaces/vector2d/vector2d.h @@ -1,238 +1,457 @@ /** - * @brief The R(2) vectorspace to represent 2-dimensional vectors providing a - * powerful utility to operate on them. + * @brief Defines the API for a 2D vector (R(2) space) library, providing a + * powerful set of utilities for vector operations. * @author pavl_g. * @copyright arithmos-native. */ -#ifndef _vector2d_H_ -#define _vector2d_H_ +#ifndef __VECTOR_2D_H_ +#define __VECTOR_2D_H_ + +#define ___ROTATION_MIN_THRESHOLD (vector2d_abs(cosf(M_PI/2))) +#define ___ROTATION_MIN2_THRESHOLD (___ROTATION_MIN_THRESHOLD/2) #include #include -#include +#include +#include +#include #ifdef __cplusplus extern "C" { #endif /** - * @brief Represents a 2-dimensional (aka. R(2) space) vector point - * with a x-component and a y-component. + * @brief Represents a vector in a 2-dimensional (R(2)) space, defined by + * x and y components. */ struct vector2d { /** - * @brief The x-coordinate (Vx->) component of this vector in the R(2) space. + * @brief The x-component (abscissa) of the vector. + */ + vec_component x; + + /** + * @brief The y-component (ordinate) of the vector. */ - coordinate x; + vec_component y; + matrix *orientation; +}; + +/** + * @brief Represents a 2D coordinate system (a vector space) defined by two basis vectors. + * @details A vector space is a collection of vectors and the operations that can be + * performed on them. By defining custom basis vectors (x_axis, y_axis), you can + * create a transformed coordinate system (e.g., rotated or scaled) relative + * to the standard Cartesian plane. Any vector can then be represented as a + * linear combination of these basis vectors. + */ +struct vec2d_space { /** - * @brief The y-coordinate (Vy->) component of this vector in the R(2) space. + * @brief The first basis vector, defining the direction of the local x-axis. */ - coordinate y; + vector2d x_axis; + /** + * @brief The second basis vector, defining the direction of the local y-axis. + */ + vector2d y_axis; + + vector2d ref_point; }; /** - * @brief Adds a scalar value to the vector components and returns a new vector. - * - * @param vector2d the initial vector in R(2) space. - * @param coordinate the value to add to that vector. - * @return a new vector2d with x and y components. + * @brief Represents a 2D vector in polar coordinates. + */ +struct vec2d_polar { + /** + * @brief The radial distance from the origin (the vector's magnitude or length). + */ + vec_component r; + /** + * @brief The angle (phi) in radians, measured counter-clockwise from the positive x-axis. + */ + vec_component phi; +}; + +/** + * @brief A structure of callback functions for handling the results of vector operations. + * This enables asynchronous or decoupled result processing. + */ +struct vec2d_processors { + /** + * @brief A function pointer to be called on a successful operation. + * @param caller A void pointer to the original calling context or object. + * @param result The vector2d result of the operation. + */ + void (*on_op_success)(void *caller, vector2d result); + /** + * @brief A function pointer to be called on a failed operation. + * @param caller A void pointer to the original calling context or object. + * @param code The status_code indicating the reason for failure. + */ + void (*on_op_failed)(void *caller, status_code code); +}; + +// --- Global Constant Vectors --- + +extern vector2d VEC2_X_COMPONENT; // Unit vector for the x-axis (1, 0) +extern vector2d VEC2_Y_COMPONENT; // Unit vector for the y-axis (0, 1) +extern vector2d VEC2_XY_PLANE; // Often a zero vector or placeholder in 2D context + +// --- Function Prototypes --- + + +extern status_code vec2d_is_unit(vector2d v, vec2d_processors *procs); + +/** + * @brief Adds a scalar value to each component of a vector. + * @param v The initial vector. + * @param scalar The value to add. + * @param out Pointer to store the resulting vector. + * @param procs Pointer to callback handlers for the result. + * @return A status code indicating the operation's outcome. + */ +extern status_code vec2d_scalar_add(vector2d v, vec_component scalar, + vector2d *out, vec2d_processors *procs); + +/** + * @brief Creates a new vector from the components of two other vectors. + * @param v1 The vector providing the x-component. + * @param v2 The vector providing the y-component. + * @param out Pointer to store the resulting vector. + * @param procs Pointer to the callback handlers. + * @return A status code. + */ +extern status_code vec2d_component(vector2d v1, vector2d v2, + vector2d *out, vec2d_processors *procs); + +/** + * @brief Subtracts a scalar value from each component of a vector. + * @param v The initial vector. + * @param scalar The value to subtract. + * @param out Pointer to store the resulting vector. + * @param procs Pointer to callback handlers. + * @return A status code. + */ +extern status_code vec2d_scalar_subtract(vector2d v, vec_component scalar, + vector2d *out, vec2d_processors *procs); + +/** + * @brief Multiplies each component of a vector by a scalar (scales the vector). + * @param v The initial vector. + * @param scalar The value to multiply by. + * @param out Pointer to store the resulting vector. + * @param procs Pointer to callback handlers. + * @return A status code. + */ +extern status_code vec2d_scalar_multiply(vector2d v, vec_component scalar, + vector2d *out, vec2d_processors *procs); + +/** + * @brief Divides each component of a vector by a scalar. + * @param v The initial vector. + * @param scalar The value to divide by. + * @param out Pointer to store the resulting vector. + * @param procs Pointer to callback handlers. + * @return A status code. + */ +extern status_code vec2d_scalar_divide(vector2d v, vec_component scalar, + vector2d *out, vec2d_processors *procs); + +/** + * @brief Calculates the unit vector of a given vector (a vector with length 1). + * @param in The original vector. + * @param out Pointer to store the resulting unit vector. + * @param procs Pointer to callback handlers. + * @return A status code. + */ +extern status_code vec2d_normalize(vector2d in, vector2d *out, vec2d_processors *procs); + +/** + * @brief Adds two vectors component-wise. + * @param v1 The first vector. + * @param v2 The second vector. + * @param out Pointer to store the vector sum. + * @param procs Pointer to callback handlers. + * @return A status code. + */ +extern status_code vec2d_add(vector2d v1, vector2d v2, vector2d *out, vec2d_processors *procs); + +/** + * @brief Divides two vectors component-wise. + * @param v1 The dividend vector. + * @param v2 The divisor vector. + * @param out Pointer to store the resulting vector. + * @param procs Pointer to callback handlers. + * @return A status code. + */ +extern status_code vec2d_divide(vector2d v1, vector2d v2, vector2d *out, vec2d_processors *procs); + +/** + * @brief Subtracts the second vector from the first, component-wise. + * @param v1 The minuend vector. + * @param v2 The subtrahend vector. + * @param out Pointer to store the vector difference. + * @param procs Pointer to callback handlers. + * @return A status code. + */ +extern status_code vec2d_subtract(vector2d v1, vector2d v2, vector2d *out, vec2d_processors *procs); + +/** + * @brief Linearly interpolates between two vectors. + * @param v1 The starting vector. + * @param v2 The ending vector. + * @param scale The interpolation factor (usually [0, 1]). + * @param out Pointer to store the interpolated vector. + * @param procs Pointer to callback handlers. + * @return A status code. + */ +extern status_code vec2d_interpolate(vector2d v1, vector2d v2, vec_component scale, + vector2d *out, vec2d_processors *procs); + +/** + * @brief Linearly extrapolates from a line defined by two vectors. + * @details This is mathematically identical to interpolation but implies the `scale` + * is outside the `[0, 1]` range. + * @param v1 The first vector on the line. + * @param v2 The second vector on the line. + * @param scale The extrapolation factor. + * @param out Pointer to store the extrapolated vector. + * @param procs Pointer to callback handlers. + * @return A status code. */ -extern vector2d vector2d_scalar_add(vector2d, coordinate); +extern status_code vec2d_extrapolate(vector2d v1, vector2d v2, vec_component scale, + vector2d *out, vec2d_processors *procs); /** - * @brief Subtracts a scalar value from the vector components and returns a new vector. - * - * @param vector2d the initial vector in R(2) space. - * @param coordinate the value to subtract from that vector. - * @return a new vector2d with x and y components. + * @brief Computes the dot product of two vectors. + * @details The dot product is a scalar that relates to the angle between two vectors. + * It is calculated as: `v1.x * v2.x + v1.y * v2.y`. + * - If `dot(v1, v2) > 0`, the angle is less than 90°. + * - If `dot(v1, v2) < 0`, the angle is greater than 90°. + * - If `dot(v1, v2) = 0`, the vectors are perpendicular. + * It can also be expressed as `|v1| * |v2| * cos(theta)`. + * @param v1 The first vector. + * @param v2 The second vector. + * @param out Pointer to store the resulting scalar dot product. + * @param procs Pointer to callback handlers. + * @return A status code. */ -extern vector2d vector2d_scalar_subtract(vector2d, coordinate); +extern status_code vec2d_dot_product(vector2d v1, vector2d v2, + vec_component *out, vec2d_processors *procs); /** - * @brief Multiplies a scalar value with the vector components and returns a new vector. - * - * @param vector2d the initial vector in R(2) space. - * @param coordinate the value to multiply to that vector. - * @return a new vector2d with x and y components. + * @brief Performs component-wise multiplication (Hadamard product). + * @param v1 The first vector. + * @param v2 The second vector. + * @param out Pointer to store the resulting vector. + * @param procs Pointer to callback handlers. + * @return A status code. */ -extern vector2d vector2d_scalar_multiply(vector2d, coordinate); +extern status_code vec2d_product(vector2d v1, vector2d v2, + vector2d *out, vec2d_processors *procs); /** - * @brief Divides a scalar value by the vector components and returns a new vector. - * - * @param vector2d the initial vector in R(2) space. - * @param coordinate the value to divide by that vector. - * @return a new vector2d with x and y components. + * @brief Computes the 2D pseudo cross product, which yields a scalar. + * @details In 2D, the cross product is not a vector but a scalar representing the + * magnitude of the Z-component of the 3D cross product. It is calculated as: + * `v1.x * v2.y - v1.y * v2.x`. + * The result is the signed area of the parallelogram formed by the two vectors. + * - A positive value means v2 is counter-clockwise from v1. + * - A negative value means v2 is clockwise from v1. + * - A zero value means the vectors are collinear. + * @param v1 The first vector. + * @param v2 The second vector. + * @param out Pointer to store the resulting scalar. + * @param procs Pointer to callback handlers. + * @return A status code. */ -extern vector2d vector2d_scalar_divide(vector2d, coordinate); +extern status_code vec2d_cross_product(vector2d v1, vector2d v2, + vec_component *out, vec2d_processors *procs); /** - * @brief Finds the uint vector of a vector in R(2) space which represents the direction of that vector. - * - * @param vector2d the original vector in R(2) space. - * @return a new vector2d representing the uint vector of the input vector. + * @brief Finds the angle in radians between two vectors. + * @param v1 The first vector. + * @param v2 The second vector. + * @param out Pointer to store the angle in radians. + * @param procs Pointer to callback handlers. + * @return A status code. */ -extern vector2d vector2d_normalize(vector2d); +extern status_code vec2d_angle(vector2d v1, vector2d v2, + vec_component *out, vec2d_processors *procs); /** - * @brief Adds two vector2d components together in a R(2) space returning a new vector. - * - * @param vector2d the first vector. - * @param vector2d the second vector. - * @return a new vector2d in the R(2) space. + * @brief Finds the length (magnitude or L2 norm) of a vector. + * @param v The vector to measure. + * @param out Pointer to store the scalar length. + * @param procs Pointer to callback handlers. + * @return A status code. */ -extern vector2d vector2d_add(vector2d, vector2d); +extern status_code vec2d_length(vector2d v, vec_component *out, vec2d_processors *procs); /** - * @brief Divides the first vector by the second vector in a R(2) space returning a new vector. - * - * @param vector2d the first vector. - * @param vector2d the second vector. - * @return a new vector2d in the R(2) space. + * @brief Converts a vector from rectangular (Cartesian) to polar coordinates. + * @param v The rectangular coordinate vector. + * @param out Pointer to a polar coordinate struct to store the result. + * @param procs Pointer to callback handlers. + * @return A status code. */ -extern vector2d vector2d_divide(vector2d, vector2d); +extern status_code vec2d_retrieve_polar(vector2d v, vec2d_polar *out, vec2d_processors *procs); /** - * @brief Subtracts the second vector components from first vector components in a R(2) space returning a new vector. - * - * @param vector2d the first vector. - * @param vector2d the second vector. - * @return a new vector2d in the R(2) space. + * @brief Converts a vector from polar to rectangular (Cartesian) coordinates. + * @param polar The polar coordinate vector. + * @param out Pointer to a vector2d struct to store the result. + * @param procs Pointer to callback handlers. + * @return A status code. */ -extern vector2d vector2d_subtract(vector2d, vector2d); +extern status_code vec2d_retrieve_rectangular(vec2d_polar polar, vector2d *out, vec2d_processors *procs); /** - * @brief Interpolates between the first vector components and the second vector components with a scale in a R(2) space. - * - * @param vector2d the first vector. - * @param vector2d the second vector. - * @return a new vector2d in the R(2) space. + * @brief Applies a modulo operation on each component of a vector by the components of a second vector. + * @param v1 The dividend vector. + * @param v2 The divisor vector. + * @param out Pointer to store the resulting vector of remainders. + * @param procs Pointer to callback handlers. + * @return A status code. */ -extern vector2d vector2d_interpolate(vector2d, vector2d, coordinate); +extern status_code vec2d_moduluo(vector2d v1, vector2d v2, + vector2d *out, vec2d_processors *procs); /** - * @brief Extrapolates from the first vector components and the second vector components with a scale in a R(2) space. - * - * @param vector2d the first vector. - * @param vector2d the second vector. - * @return a new vector2d in the R(2) space. + * @brief Calculates the Euclidean distance between two points (represented as vectors). + * @param v1 The first point/vector. + * @param v2 The second point/vector. + * @param out Pointer to store the resulting scalar distance. + * @param procs Pointer to callback handlers. + * @return A status code. */ -extern vector2d vector2d_extrapolate(vector2d, vector2d, coordinate); +extern status_code vec2d_distance(vector2d v1, vector2d v2, + vec_component *out, vec2d_processors *procs); /** - * @brief Performs a matrix multiplication operation on two vectors in the R(2) space. - * - * @param vector2d the first vector. - * @param vector2d the second vector. - * @return a new vector2d in the R(2) space. + * @brief Tests whether two vectors are linearly dependent (collinear). + * @details Two vectors `u` and `v` are linearly dependent if one is a scalar multiple + * of the other (i.e., `u = c*v` for some scalar `c`). In 2D, this means they + * lie on the same line through the origin. This can be checked by seeing if + * their 2D cross product is zero. + * @param v1 The first vector. + * @param v2 The second vector. + * @param procs Pointer to callback handlers for the boolean result. + * @return A status code indicating if the check was performed. */ -extern coordinate vector2d_dot_product(vector2d, vector2d); +extern status_code vec2d_is_dependent(vector2d v1, vector2d v2, vec2d_processors *procs); /** - * @brief Performs a scalar multiplication operation on the first vector components using the - * second vector components in a R(2) vector-space returning a new vector. - * - * @param vector2d the first vector. - * @param vector2d the second vector. - * @return a new vector2d in the R(2) space. + * @brief Tests whether two vectors are perpendicular (orthogonal). + * @details Two non-zero vectors are perpendicular if and only if their dot product is zero. + * @param v1 The first vector. + * @param v2 The second vector. + * @param procs Pointer to callback handlers for the boolean result. + * @return A status code. */ -extern vector2d vector2d_product(vector2d, vector2d); +extern status_code vec2d_are_perpendicular(vector2d v1, vector2d v2, vec2d_processors *procs); /** - * @brief Performs a cross-product or vector product which resembles the direction of the plane - * those 2 vectors are making in the R(2) vector-space. - * - * @param vector2d the first vector. - * @param vector2d the second vector. - * @return the cross product component. + * @brief Tests whether two vectors are parallel. + * @details Two vectors are parallel if their 2D cross product is zero. This is a more + * robust check for collinearity than comparing angles. + * @param v1 The first vector. + * @param v2 The second vector. + * @param procs Pointer to callback handlers for the boolean result. + * @return A status code indicating if the check was performed. */ -extern coordinate vector2d_cross_product(vector2d vec0, vector2d vec1); +extern status_code vector2d_are_parallel(vector2d v1, vector2d v2, vec2d_processors *procs); /** - * @brief Finds the angle between two vectors in the R(2) space by dividing their dot product by the product of their norms. - * @note The angle is in radians by default! - * - * @param vector2d the first vector. - * @param vector2d the second vector. - * @return a new vector2d in the R(2) space. + * @brief An alias for `vec2d_is_dependent`. Tests for collinearity. + * @param v1 The first vector. + * @param v2 The second vector. + * @param procs Pointer to callback handlers for the boolean result. + * @return A status code. */ -extern coordinate vector2d_angle(vector2d, vector2d); +extern status_code vec2d_are_dependent(vector2d v1, vector2d v2, vec2d_processors *procs); /** - * @brief Finds the length (aka. norm) of a vector in the R(2) space by using the Pythagorean theorem on its components. - * - * @param vector2d a vector in the R(2) space to find its length. - * @return a scalar value representing the length of this vector in the R(2) space. + * @brief Computes the projection of vector v1 onto vector v2. + * @details Vector projection finds the "shadow" that `v1` casts onto the line defined by `v2`. + * It results in a vector parallel to `v2`. The formula is: + * `proj_v2(v1) = ( (v1 . v2) / |v2|^2 ) * v2` + * This is geometrically equivalent to finding the closest point on the line of `v2` to the tip of `v1`. + * @param v1 The vector to be projected. + * @param v2 The vector to project onto. + * @param out Pointer to store the resulting projection vector. + * @param procs Pointer to callback handlers. + * @return A status code. */ -extern coordinate vector2d_length(vector2d); +extern status_code vec2d_projection_vector(vector2d v1, vector2d v2, vector2d *out, vec2d_processors *procs); /** - * @brief Converts the rectangular coordinate into a polar coordinate by finding - * the inverse of the tangent of Y/X. - * @note The angle is with the postive direction of x-axis and in rads! - * - * @param vector2d a rectangular coordinate vector. - * @return the polar coordinate value in radians. + * @brief Rotates a vector around a specified pivot point. + * @details To rotate a vector `v` around a pivot `p`, we first translate the system so the + * pivot is at the origin (`v' = v - p`). Then, we apply the standard 2D rotation matrix: + * `x_new = x' * cos(angle) - y' * sin(angle)` + * `y_new = x' * sin(angle) + y' * cos(angle)` + * Finally, we translate the system back by adding the pivot (`result = v_rotated + p`). + * @param v The vector to rotate. + * @param axis The axis from which the angle of rotation is applied. + * @param angle The angle of rotation in radians (counter-clockwise). + * @param out Pointer to store the rotated vector. + * @param procs Pointer to callback handlers. + * @return A status code. */ -extern coordinate vector2d_polar(vector2d); +extern status_code vec2d_rotate(vector2d v, vector2d axis, vec_component angle, vector2d *out, vec2d_processors *procs); /** - * @brief Applies a moduluo (integer division) on vector components, returing the remainder - * of the integer division in a new vector2d in a R(2) space. - * - * @param vector2d a rectangular coordinate vector. - * @return the polar coordinate value in radians. + * @brief Creates a 2D vector space (a coordinate system) from two basis vectors. + * @param basis1 The first basis vector (e.g., the new x-axis). + * @param basis2 The second basis vector (e.g., the new y-axis). + * @param out Pointer to store the created subspace. + * @param procs Pointer to callback handlers. + * @return A status code. */ -extern vector2d vector2f_scalar_moduluo(vector2d, coordinate); +extern status_code vec2d_create_subspace(vector2d basis1, vector2d basis2, vec2d_space *out, vec2d_processors *procs); /** - * @brief Finds the metric distance between two vectors in a R(2) space by calculating the - * norm of the their subtraction. - * - * @param vector2d the first vector. - * @param vector2d the second vector. - * @return the metric distance between the specified vectors. + * @brief Tests if vector `v2` is a rotated version of `v1` by a specific angle. + * @param v1 The original vector. + * @param v2 The vector to check. + * @param angle The angle of rotation in radians to test against. + * @param procs Pointer to callback handlers for the boolean result. + * @return A status code. */ -extern coordinate vector2d_distance(vector2d, vector2d); +extern status_code vec2d_is_rotated(vector2d v1, vector2d v2, vec_component angle, vec2d_processors *procs); /** - * @brief Tests whether two vectors are dependent in a R(2) vector-space. - * @note Two vectors are said to be dependent if they are multiplies of one another, - * such that, the [u = cv], where u and v are vectors and c is a scalar value not equal to zero. - * @note Linear dependent vectors are coincident vectors in a R(2) space. - * - * @param vector2d the first vector. - * @param vector2d the second vector. - * @return (1) for true if the two vectors are dependent or (0) for false otherwise. + * @brief Tests if two vectors are equal within a small tolerance. + * @param v1 The first vector. + * @param v2 The second vector. + * @param procs Pointer to callback handlers for the boolean result. + * @return A status code. */ -extern uint8_t vector2d_is_dependent(vector2d, vector2d); +extern status_code vec2d_are_equal(vector2d v1, vector2d v2, vec2d_processors *procs); /** - * @brief Tests whether two vectors are perpendicular in a R(2) vector-space. - * @note Two vectors are said to be perpendicular if and only if their dot-product is zero - * because, cos(90) is zero, so u.v = |u|.|v|.cos(90) = 0. - * - * @param vector2d the first vector. - * @param vector2d the second vector. - * @return (1) for true if the two vectors are perpendicular or (0) for false otherwise. + * @brief Swaps the x and y components of a vector. + * @param v The input vector. + * @param out Pointer to store the vector with swapped components. + * @param procs Pointer to callback handlers. + * @return A status code. */ -extern uint8_t vector2d_are_perpendicular(vector2d, vector2d); +extern status_code vec2d_swap_components(vector2d v, vector2d *out, vec2d_processors *procs); /** - * @brief Tests whether two vectors are parallel in a R(2) vector-space. - * @note Two vectors are said to be parallel if and only if their dot-product - * is equal to the product of their norms (lengths); - * because, cos(0) is 1, so u.v = |u|.|v|.cos(0) = |u|.|v|. - * - * @param vector2d the first vector. - * @param vector2d the second vector. - * @return (1) for true if the two vectors are parallel or (0) for false otherwise. + * @brief Negates both components of a vector, reversing its direction. + * @param v1 The vector to negate. + * @param v2 (Note: This parameter appears unused and could be deprecated for clarity). + * @param out Pointer to store the negated vector. + * @param procs Pointer to callback handlers. + * @return A status code. */ -extern uint8_t vector2d_are_parallel(vector2d, vector2d); +extern status_code vec2d_negate(vector2d v1, vector2d v2, vector2d *out, vec2d_processors *procs); #ifdef __cplusplus } #endif -#endif //_vector2d_H_ +#endif //__VECTOR_2D_H_ diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/include/electrostatic/electronetsoft/algorithm/arithmos/vectorspaces/vector3d/vector3d.h b/electrostatic-sandbox-framework/electrostatic-core/src/include/electrostatic/electronetsoft/algorithm/arithmos/vectorspaces/vector3d/vector3d.h new file mode 100644 index 00000000..c6eca5f7 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/include/electrostatic/electronetsoft/algorithm/arithmos/vectorspaces/vector3d/vector3d.h @@ -0,0 +1,310 @@ +/** + * @brief The R(3) vectorspace to represent 3-dimensional vectors providing a + * powerful utility to operate on them. + * @author pavl_g. + * @copyright arithmos-native. + */ +#ifndef __VECTOR_3D_H_ +#define __VECTOR_3D_H_ + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct vec3d_gimbal { + vec_component x_gimbal; + vec_component y_gimbal; + vec_component z_gimbal; + + matrix *orientation; +}; + +/** + * @brief Represents a 3-dimensional (aka. R(3) space) vector point + * with a x-component, a y-component, and z-component. + */ +struct vector3d { + /** + * @brief The x-coordinate (Vx->) component of this vector in the R(3) space. + */ + vec_component x; + + /** + * @brief The y-coordinate (Vy->) component of this vector in the R(3) space. + */ + vec_component y; + + vec_component z; + + vec3d_gimbal gimbal; +}; + +struct vec3d_space { + vector3d x_axis; + vector3d y_axis; + vector3d z_axis; + vector3d ref_point; +}; + +struct vec3d_polar { + vec_component r; // the length of the vector; the radius of the unit sphere + vec_component phi; // angle with +ve direction of x-axis + vec_component theta; // angle with +ve direction of xy plane +}; + +struct vec3d_processors { + /** + * @brief A function pointer to be called on a successful operation. + * @param caller A void pointer to the original calling context or object. + * @param result The vector3d result of the operation. + */ + void (*on_op_success)(void *caller, vector3d result); + /** + * @brief A function pointer to be called on a failed operation. + * @param caller A void pointer to the original calling context or object. + * @param code The status_code indicating the reason for failure. + */ + void (*on_op_failed)(void *caller, status_code code); +}; + +extern vector3d VEC3_X_COMPONENT; + +extern vector3d VEC3_Y_COMPONENT; + +extern vector3d VEC3_Z_COMPONENT; + +/** + * @brief Adds a scalar value to the vector components and returns a new vector. + * + * @param vector3d the initial vector in R(3) space. + * @param vec_component the value to add to that vector. + * @return status code. + */ +extern status_code vec3d_scalar_add(vector3d, vec_component, + vector3d *, vec3d_processors *); + +extern status_code vec3d_component(vector3d, vector3d, + vector3d *, vec3d_processors *); + +/** + * @brief Subtracts a scalar value from the vector components and rewrites the vector. + * + * @param vector3d the initial vector in R(3) space. + * @param vec_component the value to subtract from that vector. + * @return a status code. + */ +extern status_code vec3d_scalar_subtract(vector3d, vec_component, + vector3d *, vec3d_processors *); + +/** + * @brief Multiplies a scalar value with the vector components and rewrites the given vector. + * + * @param vector3d the initial vector in R(3) space. + * @param vec_component the value to multiply to that vector. + * @return a status code. + */ +extern status_code vec3d_scalar_multiply(vector3d, vec_component, + vector3d *, vec3d_processors *); + +/** + * @brief Divides a scalar value by the vector components and rewrites the given vector. + * + * @param vector3d the initial vector in R(3) space. + * @param vec_component the value to divide by that vector. + * @return a status code. + */ +extern status_code vec3d_scalar_divide(vector3d, vec_component, + vector3d *, vec3d_processors *); + +/** + * @brief Finds the uint vector of a vector in R(3) space which represents the direction of that vector. + * + * @param in the original vector in R(3) space. + * @param out the output vector in R(3) space from this operation. + * @return a status code. + */ +extern status_code vec3d_normalize(vector3d, vector3d *, vec3d_processors *); + +/** + * @brief Adds two vector components together in a R(3) space putting the result in the third vector + * structure. + * + * @param vector3d the first vector. + * @param vector3d the second vector. + * @return a status code. + */ +extern status_code vec3d_add(vector3d, vector3d, vector3d *, vec3d_processors *); + +/** + * @brief Divides the first vector by the second vector in a R(3) space putting the result in the third vector + * structure. + * + * @param vector3d the first vector. + * @param vector3d the second vector. + * @return a status code. + */ +extern status_code vec3d_divide(vector3d, vector3d, vector3d *, vec3d_processors *); + +/** + * @brief Subtracts the second vector components from first vector components in a R(2) space returning a new vector. + * + * @param vector3d the first vector. + * @param vector3d the second vector. + * @return a new vector3d in the R(2) space. + */ +extern status_code vec3d_subtract(vector3d, vector3d, vector3d *, vec3d_processors *); + +/** + * @brief Interpolates between the first vector components and the second vector components with a scale in a R(2) space. + * + * @param vector3d the first vector. + * @param vector3d the second vector. + * @return a new vector3d in the R(2) space. + */ +extern status_code vec3d_interpolate(vector3d, vector3d, vec_component, + vector3d *, vec3d_processors *); + +/** + * @brief Extrapolates from the first vector components and the second vector components with a scale in a R(2) space. + * + * @param vector3d the first vector. + * @param vector3d the second vector. + * @return a new vector3d in the R(2) space. + */ +extern status_code vec3d_extrapolate(vector3d, vector3d, vec_component, + vector3d *, vec3d_processors *); + +/** + * @brief Performs a matrix multiplication operation on two vectors in the R(2) space. + * + * @param vector3d the first vector. + * @param vector3d the second vector. + * @return a new vector3d in the R(2) space. + */ +extern status_code vec3d_dot_product(vector3d, vector3d, + vec_component *, vec3d_processors *); + +/** + * @brief Performs a scalar multiplication operation on the first vector components using the + * second vector components in a R(2) vector-space returning a new vector. + * + * @param vector3d the first vector. + * @param vector3d the second vector. + * @return a new vector3d in the R(2) space. + */ +extern status_code vec3d_product(vector3d, vector3d, + vector3d *, vec3d_processors *); + +/** + * @brief Performs a cross-product or vector product which resembles the direction of the plane those 2 vectors are making in the R(2) vector-space. + * + * @param vector3d the first vector. + * @param vector3d the second vector. + * @return the cross product component. + */ +extern status_code vec3d_cross_product(vector3d, vector3d, + vec_component *, vec3d_processors *); + +/** + * @brief Finds the angle between two vectors in the R(2) space by dividing their dot product by the product of their norms. + * @note The angle is in radians by default! + * + * @param vector3d the first vector. + * @param vector3d the second vector. + * @return a new vector3d in the R(2) space. + */ +extern status_code vec3d_angle(vector3d, vector3d, + vec_component *, vec3d_processors *); + +/** + * @brief Finds the length (aka. norm) of a vector in the R(2) space by using the Pythagorean theorem on its components. + * + * @param vector3d a vector in the R(2) space to find its length. + * @return a scalar value representing the length of this vector in the R(2) space. + */ +extern status_code vec3d_length(vector3d, vec_component *, vec3d_processors *); + +/** + * @brief Converts the rectangular coordinate into a polar coordinate by finding + * the inverse of the tangent of Y/X. + * @note The angle is with the positive direction of x-axis and in rads! + * + * @param vector3d a rectangular coordinate vector. + * @return the polar coordinate value in radians. + */ +extern status_code vec3d_retrieve_polar(vector3d, vec3d_polar *, vec3d_processors *); + +/** + * @brief Applies a moduluo (integer division) on vector components, returning the remainder + * of the integer division in a new vector3d in a R(2) space. + * + * @param vector3d a rectangular coordinate vector. + * @return the polar coordinate value in radians. + */ +extern status_code vec3d_moduluo(vector3d, vector3d, + vector3d *, vec3d_processors *); + +/** + * @brief Finds the metric distance between two vectors in a R(2) space by calculating the + * norm of the their subtraction. + * + * @param vector3d the first vector. + * @param vector3d the second vector. + * @return the metric distance between the specified vectors. + */ +extern status_code vec3d_distance(vector3d, vector3d, + vec_component *, vec3d_processors *); + +/** + * @brief Tests whether two vectors are dependent in a R(2) vector-space. + * @note Two vectors are said to be dependent if they are multiplies of one another, + * such that, the [u = cv], where u and v are vectors and c is a scalar value not equal to zero. + * @note Linear dependent vectors are coincident vectors in a R(2) space. + * + * @param vector3d the first vector. + * @param vector3d the second vector. + * @return (1) for true if the two vectors are dependent or (0) for false otherwise. + */ +extern status_code vec3d_are_dependent(vector3d, vector3d, vec3d_processors *); + +/** + * @brief Tests whether two vectors are perpendicular in a R(2) vector-space. + * @note Two vectors are said to be perpendicular if and only if their dot-product is zero + * because, cos(90) is zero, so u.v = |u|.|v|.cos(90) = 0. + * + * @param vector3d the first vector. + * @param vector3d the second vector. + * @return (1) for true if the two vectors are perpendicular or (0) for false otherwise. + */ +extern status_code vec3d_are_perpendicular(vector3d, vector3d, vec3d_processors *); + +/** + * @brief Tests whether two vectors are parallel in a R(2) vector-space. + * @note Two vectors are said to be parallel if and only if their dot-product + * is equal to the product of their norms (lengths); + * because, cos(0) is 1, so u.v = |u|.|v|.cos(0) = |u|.|v|. + * + * @param vector3d the first vector. + * @param vector3d the second vector. + * @return (1) for true if the two vectors are parallel or (0) for false otherwise. + */ +extern status_code vector3d_are_parallel(vector3d, vector3d, vec3d_processors *); + +extern status_code vec3d_are_equal(vector3d, vector3d, vec3d_processors *); + +extern status_code vec3d_rotate(vector3d, vector3d, vec_component, vector3d *, vec3d_processors *); + +extern status_code vec3d_abs(vector3d, vector3d *, vec3d_processors *); + + +#ifdef __cplusplus +} +#endif + +#endif //_vector3d_H_ diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/include/electrostatic/electronetsoft/arithmos_calculus.h b/electrostatic-sandbox-framework/electrostatic-core/src/include/electrostatic/electronetsoft/arithmos_calculus.h new file mode 100644 index 00000000..1d483cc8 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/include/electrostatic/electronetsoft/arithmos_calculus.h @@ -0,0 +1,3 @@ +#include +#include +#include \ No newline at end of file diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/include/electrostatic/electronetsoft/util/arithmos_data_structures.h b/electrostatic-sandbox-framework/electrostatic-core/src/include/electrostatic/electronetsoft/util/arithmos_data_structures.h new file mode 100644 index 00000000..d4edee33 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/include/electrostatic/electronetsoft/util/arithmos_data_structures.h @@ -0,0 +1,4 @@ +#include +#include +#include +#include diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/include/electrostatic/electronetsoft/util/caller_graphs.h b/electrostatic-sandbox-framework/electrostatic-core/src/include/electrostatic/electronetsoft/util/caller_graphs.h new file mode 100644 index 00000000..72d302db --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/include/electrostatic/electronetsoft/util/caller_graphs.h @@ -0,0 +1,22 @@ +#ifndef __CALLER_GRAPH_API_H_ +#define __CALLER_GRAPH_API_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct caller_graph { + char *api; + void *func; + void *return_value; + void **params; + caller_graph *root; +}; + +#ifdef __cplusplus +}; +#endif + +#endif \ No newline at end of file diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/include/electrostatic/electronetsoft/util/types.h b/electrostatic-sandbox-framework/electrostatic-core/src/include/electrostatic/electronetsoft/util/types.h index a02f2c00..dd700caf 100644 --- a/electrostatic-sandbox-framework/electrostatic-core/src/include/electrostatic/electronetsoft/util/types.h +++ b/electrostatic-sandbox-framework/electrostatic-core/src/include/electrostatic/electronetsoft/util/types.h @@ -90,6 +90,32 @@ typedef struct pipe_serializer (pipe_serializer); // Types for Vector Maths Libraries typedef struct vector2d (vector2d); +typedef struct vec2d_space (vec2d_space); +typedef struct vec2d_polar (vec2d_polar); +typedef struct vec2d_processors (vec2d_processors); + +typedef struct physics2d_engine (physics2d_engine); +typedef struct physics2d_object (physics2d_object); +typedef struct physics2d_processor (physics2d_processor); + +typedef struct object2d_transformation (object2d_transformation); + +typedef struct vector3d (vector3d); +typedef struct vec3d_space (vec3d_space); +typedef struct vec3d_polar (vec3d_polar); +typedef struct vec3d_processors (vec3d_processors); +typedef struct vec3d_gimbal (vec3d_gimbal); + +typedef struct matrix (matrix); +typedef struct mat_processors (mat_processors); +typedef struct mat_proc_sig (mat_proc_sig); +typedef struct mat_binary_op_sig (mat_binary_op_sig); +typedef enum mat_iterator { + ROW_CONVENTION_ITERATOR = ((INT32_MAX >> 16) ^ INT32_MAX), + COLUMN_CONVENTION_ITERATOR = ROW_CONVENTION_ITERATOR - 1, +} mat_iterator; + +typedef struct caller_graph (caller_graph); #ifdef __cplusplus }; diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/matrix/mat_add.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/matrix/mat_add.c new file mode 100644 index 00000000..48a681db --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/matrix/mat_add.c @@ -0,0 +1,105 @@ +#include + +struct mat_add_metadata { + matrix *m1; + matrix *output; + mat_processors *processors; +}; + +static inline status_code __on_entry_iterated(mat_proc_sig proc_sig) { + // preprocessing automata -- Machine Input + matrix m0 = proc_sig.mat; + uint64_t row = proc_sig.row_index; + uint64_t column = proc_sig.col_index; + struct mat_add_metadata *metadata = proc_sig.proc.metadata; + + matrix m1 = *(metadata->m1); + matrix *out = metadata->output; + mat_processors user_proc = *(metadata->processors); + + status_code __code; + + // preprocessing automata -- Execute preprocessing sub-automata + if (NULL != user_proc.on_binary_op_preprocessor) { + __code = user_proc.on_binary_op_preprocessor((mat_binary_op_sig) { + .m0 = m0, + .m1 = m1, + .row_index = row, + .col_index = column, + .proc = user_proc, + }); + if (PASS != __code) { + return __code; + } + } + + // processing automata + out->element[row][column] = + m0.element[row][column] + + m1.element[row][column]; + + // postprocessing chain + if (NULL != user_proc.on_elementary_op_postprocessor) { + __code = user_proc.on_elementary_op_postprocessor(proc_sig); + if (PASS != __code) { + return __code; + } + } + return PASS; +} + +status_code mat_add(matrix m0, matrix m1, + matrix *out, + mat_processors processors) { + + caller_graph caller = { + .api = "arithmos:matrix#mat_add", + .func = &mat_add, + .root = processors.root, + }; + + mat_proc_sig proc_sig = { + .proc = processors, + .caller = caller, + .metadata = processors.metadata, + }; + + if (rvalue(out) == NULL || + rvalue(out->element) == NULL) { + return EUNDEFINEDBUFFER; + } + + proc_sig.mat = *out; + + if (m0.m != m1.m || + m0.n != m1.n || + m0.m != out->m || + m0.n != out->n) { + return EBUFFERTURNCATION; + } + + struct mat_add_metadata metadata = { + .m1 = &m1, + .output = out, + .processors = &processors, // performed a chained automata processors + }; + + mat_processors __proc = { + .on_entry_iterated = &__on_entry_iterated, + .metadata = &metadata + }; + + status_code __code = mat_iterate_elements(m0, ROW_CONVENTION_ITERATOR, __proc); + if (PASS != __code) { + if (NULL != processors.on_op_failure) { + processors.on_op_failure(proc_sig, __code); + } + return __code; + } + + if (NULL != processors.on_op_success) { + processors.on_op_success(proc_sig); + } + + return PASS; +} \ No newline at end of file diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/matrix/mat_create_from_vector2d.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/matrix/mat_create_from_vector2d.c new file mode 100644 index 00000000..617b16d4 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/matrix/mat_create_from_vector2d.c @@ -0,0 +1,44 @@ +#include + +status_code mat_create_from_vector2d(vector2d v, matrix *mat, mat_processors processors) { + caller_graph caller = { + .api = "arithmos:matrix#mat_create_from_vector2d", + .func = &mat_create_from_vector2d, + .root = processors.root, + }; + + mat_proc_sig proc_sig = { + .proc = processors, + .caller = caller, + .metadata = processors.metadata, + }; + + // preprocessor automata -- Test main matrix memory addresses + if (rvalue(mat) == NULL || + rvalue(mat->element) == NULL) { + if (NULL != processors.on_op_failure) { + processors.on_op_failure(proc_sig, EUNDEFINEDBUFFER); + } + return EUNDEFINEDBUFFER; + } + + // preprocessor automata -- Test elements allocation + if (rvalue(mat->element + 1) == NULL) { + if (NULL != processors.on_op_failure) { + processors.on_op_failure(proc_sig, EBUFFERTURNCATION); + } + return EBUFFERTURNCATION; + } + + proc_sig.mat = *mat; + + // processing automata -- Adapt elements + *(mat->element[0]) = v.x; + *(mat->element[1]) = v.y; + + if (NULL != processors.on_op_success) { + processors.on_op_success(proc_sig); + } + + return PASS; +} \ No newline at end of file diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/matrix/mat_create_from_vector3d.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/matrix/mat_create_from_vector3d.c new file mode 100644 index 00000000..4dbb2a0f --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/matrix/mat_create_from_vector3d.c @@ -0,0 +1,41 @@ +#include + +status_code mat_create_from_vector3d(vector3d v, matrix *mat, mat_processors processors) { + caller_graph caller = { + .api = "arithmos:matrix#mat_create_from_vector3d", + .func = &mat_create_from_vector3d, + .root = processors.root, + }; + + mat_proc_sig proc_sig = { + .proc = processors, + .caller = caller, + .metadata = processors.metadata, + }; + + // preprocessor automata -- Test main matrix memory addresses + if (rvalue(mat) == NULL || + rvalue(mat->element) == NULL) { + if (NULL != processors.on_op_failure) { + processors.on_op_failure(proc_sig, EUNDEFINEDBUFFER); + } + return EUNDEFINEDBUFFER; + } + + proc_sig.mat = *mat; + + // preprocessor automata -- Test elements allocation + if (rvalue(mat->element + 1) == NULL || rvalue(mat->element + 2) == NULL) { + if (NULL != processors.on_op_failure) { + processors.on_op_failure(proc_sig, EBUFFERTURNCATION); + } + return EBUFFERTURNCATION; + } + + // processing automata -- Adapt elements + *(mat->element[0]) = v.x; + *(mat->element[1]) = v.y; + *(mat->element[2]) = v.z; + + return PASS; +} \ No newline at end of file diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/matrix/mat_iterate_elements.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/matrix/mat_iterate_elements.c new file mode 100644 index 00000000..244b6976 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/matrix/mat_iterate_elements.c @@ -0,0 +1,202 @@ +#include +#include + +static inline status_code row_convention_iterator(matrix mat, mat_processors proc, + uint64_t *rows, uint64_t *columns, + uint8_t *signal_row_increment, + caller_graph *root_caller) { + + // preprocessing automata -- Define Machine Input (Sigma, the machine language) + caller_graph caller = { + .api = "arithmos:matrix#row_convention_iterator", + .func = &row_convention_iterator, + .params = NULL, + .return_value = NULL, + .root = root_caller + }; + + mat_proc_sig proc_sig = { + .mat = mat, + .row_index = *rows, + .col_index = *columns, + .proc = proc, + .caller = caller, + .metadata = proc.metadata + }; + + status_code __code; + + // preprocessing automata -- Validate machine input + // for null-terminated matrices + if (NULL == mat.element[*rows]) { + if (NULL != proc.on_op_failure) { + proc.on_op_failure(proc_sig, EUNDEFINEDBUFFER); + } + return EUNDEFINEDBUFFER; + } + + // processing automata -- conditional sub-automata (1) + // use row-first convention to iterate over elements + // therefore, increment columns first + if (is_last_column(mat, *columns)) { + // signal a on_row_iterated + if (NULL != proc.on_row_iterated) { + __code = proc.on_row_iterated(proc_sig); + if (PASS != __code) { + return __code; + } + } + // signal an increment at the final states (post-processing) + *signal_row_increment = 1; + } + + // processing automata -- conditional sub-automata (2) + // signal a on_column_iterated for all elements lying in this range + if (is_last_row(mat, *rows)) { + // signal a on_column_iterated + if (NULL != proc.on_column_iterated) { + __code = proc.on_column_iterated(proc_sig); + if (PASS != __code) { + return __code; + } + } + } + + // post-processing automata + // signal a on_entry_iterated + __code = proc.on_entry_iterated(proc_sig); + + // Update the machine input + *columns = (*columns + 1) % mat.n; // increment the columns, but protect memory accessibility! + + if (*signal_row_increment) { + *rows = *rows + 1; + *signal_row_increment = 0; + } + return __code; +} + +static inline status_code column_convention_iterator(matrix mat, mat_processors proc, + uint64_t *rows, uint64_t *columns, + uint8_t *signal_column_increment, + caller_graph *root_caller) { + + // preprocessing automata -- Define Machine Input (Sigma, the machine language) + caller_graph caller = { + .api = "arithmos:matrix#column_convention_iterator", + .func = &column_convention_iterator, + .params = NULL, + .return_value = NULL, + .root = root_caller + }; + + mat_proc_sig proc_sig = { + .mat = mat, + .row_index = *rows, + .col_index = *columns, + .proc = proc, + .caller = caller, + .metadata = proc.metadata + }; + + status_code __code; + + // preprocessing automata -- Validate machine input + // for null-terminated matrices + if (NULL == mat.element[*rows]) { + if (NULL != proc.on_op_failure) { + proc.on_op_failure(proc_sig, EUNDEFINEDBUFFER); + } + return EUNDEFINEDBUFFER; + } + + // processing automata -- conditional sub-automata (1) + // use column-first convention to iterate over elements + // therefore, increment rows for every column of index (columns) + if (is_last_row(mat, *rows)) { + // signal a on_column_iterated + if (NULL != proc.on_column_iterated) { + __code = proc.on_column_iterated(proc_sig); + if (PASS != __code) { + return __code; + } + } + // signal an increment at the final states (post-processing) + *signal_column_increment = 1; + } + + // processing automata -- conditional sub-automata (2) + // signal a on_row_iterated for all elements lying in this range + if (is_last_column(mat, *columns)) { + // signal a on_row_iterated for the last column only + if (NULL != proc.on_row_iterated) { + __code = proc.on_row_iterated(proc_sig); + if (PASS != __code) { + return __code; + } + } + } + + // post-processing automata + // signal a on_entry_iterated + __code = proc.on_entry_iterated(proc_sig); + + // Update the machine input + *rows = (*rows + 1) % mat.m; // increment the rows, but protect memory accessibility! + + if (*signal_column_increment) { + *columns = *columns + 1; + *signal_column_increment = 0; + } + return __code; +} + +status_code mat_iterate_elements(matrix mat, mat_iterator iterator, mat_processors proc) { + caller_graph caller = { + .api = "arithmos:matrix#mat_iterate_elements", + .func = &mat_iterate_elements, + .params = NULL, + .return_value = NULL, + .root = proc.root + }; + + mat_proc_sig proc_sig = { + .proc = proc, + .caller = caller, + .metadata = proc.metadata + }; + + // pre-processing automata -- Validate main matrix memory addresses + if (NULL == mat.element || 0 == mat.m || 0 == mat.n || + NULL == proc.on_entry_iterated) { + return EUNDEFINEDBUFFER; + } + + // preprocessing automata -- Local automatic stack allocation + // those are grouped into a set of input sigma + // the sigmas are the language recognized by the machine + status_code __code; + uint8_t signal_increment = 0; + uint64_t rows = 0; + uint64_t columns = 0; + uint64_t elements = 0; + + for (;elements < mat.m * mat.n; elements++) { + if (iterator == ROW_CONVENTION_ITERATOR) { + __code = row_convention_iterator(mat, proc, &rows, &columns, + &signal_increment, + &caller); + } else { + __code = column_convention_iterator(mat, proc, &rows, &columns, + &signal_increment, + &caller); + } + if (PASS != __code) { + if (NULL != proc.on_op_failure) { + proc.on_op_failure(proc_sig, __code); + } + return __code; + } + } + return PASS; +} \ No newline at end of file diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/matrix/mat_iterate_rows.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/matrix/mat_iterate_rows.c new file mode 100644 index 00000000..9c1a9c8e --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/matrix/mat_iterate_rows.c @@ -0,0 +1,34 @@ +#include + +status_code mat_iterate_rows(matrix mat, mat_processors proc) { + caller_graph caller = { + .api = "arithmos:matrix#mat_iterate_rows", + .func = &mat_iterate_rows, + .params = NULL, + .root = proc.root, + }; + + mat_proc_sig proc_sig = { + .proc = proc, + .caller = caller, + .metadata = proc.metadata + }; + + if (NULL == mat.element || 0 == mat.m || NULL == proc.on_row_iterated) { + return EUNDEFINEDBUFFER; + } + + for (uint64_t i = 0; i < mat.m; i++) { + proc_sig.row_index = i; + + status_code __code = proc.on_row_iterated(proc_sig); + if (PASS != __code) { + if (NULL != proc.on_op_failure) { + proc.on_op_failure(proc_sig, __code); + } + return __code; + } + } + + return PASS; +} \ No newline at end of file diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/matrix/mat_product.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/matrix/mat_product.c new file mode 100644 index 00000000..124d7c77 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/matrix/mat_product.c @@ -0,0 +1,184 @@ +#include + +struct mat_product_metadata { + matrix *m0; + matrix *m1; + matrix *output; + mat_processors *processors; + vec_component *cache; + uint64_t *dot_prod_index; +}; + +static inline status_code __on_entry_iterated(mat_proc_sig proc_sig) { + // preprocessing automata -- Machine Input + uint64_t row = proc_sig.row_index; + uint64_t column = proc_sig.col_index; + struct mat_product_metadata *metadata = proc_sig.proc.metadata; + + matrix m0 = *(metadata->m0); + matrix m1 = *(metadata->m1); + matrix *out = metadata->output; + mat_processors user_proc = *(metadata->processors); + vec_component *cache = metadata->cache; + + uint64_t dot_prod_index = *(metadata->dot_prod_index); + + status_code __code; + + // preprocessing automata -- Execute preprocessing sub-automata + if (NULL != user_proc.on_binary_op_preprocessor) { + __code = user_proc.on_binary_op_preprocessor((mat_binary_op_sig) { + .m0 = m0, + .m1 = m1, + .row_index = row, + .col_index = column, + .proc = user_proc, + .metadata = user_proc.metadata + }); + if (PASS != __code) { + return __code; + } + } + + // processing automata + *cache += m0.element[dot_prod_index][row] * m1.element[row][column]; + +// if (NULL != user_proc.on_binary_op_postprocessor) { +// __code = user_proc.on_binary_op_postprocessor((mat_binary_op_sig) { +// .m0 = m0, +// .m1 = m1, +// .row_index = row, +// .col_index = column, +// .proc = user_proc, +// .metadata = user_proc.metadata +// }); +// if (PASS != __code) { +// return __code; +// } +// } + + // postprocessing automata -- test the column + if (is_last_row(m1, row)) { + out->element[dot_prod_index][column] = *cache; + *cache = (vec_component) 0; // reset cache value + + if (NULL != user_proc.on_elementary_op_postprocessor) { + __code = user_proc.on_elementary_op_postprocessor( + (mat_proc_sig) { + .mat = *out, + .row_index = dot_prod_index, + .col_index = column, + .metadata = user_proc.metadata + }); + if (PASS != __code) { + return __code; + } + } + } + + return PASS; +} + +static inline status_code __on_row_iterated(mat_proc_sig proc_sig) { + // preprocessing automata -- Machine Input + uint64_t row = proc_sig.row_index; // the row buffer index + uint64_t column = proc_sig.col_index; + struct mat_product_metadata *metadata = proc_sig.proc.metadata; + + matrix m0 = *(metadata->m0); + matrix m1 = *(metadata->m1); + matrix *out = metadata->output; + mat_processors user_proc = *(metadata->processors); + vec_component *cache = metadata->cache; + + uint64_t *dot_prod_index = metadata->dot_prod_index; + *dot_prod_index = row; + + status_code __code; + + mat_processors __proc = { + .on_entry_iterated = &__on_entry_iterated, + .metadata = metadata, + }; + + // processing automata + __code = mat_iterate_elements(m1, COLUMN_CONVENTION_ITERATOR, __proc); + if (PASS != __code) { + if (NULL != user_proc.on_op_failure) { + user_proc.on_op_failure(proc_sig, __code); + } + return __code; + } + + return PASS; +} + +status_code mat_product(matrix m0, matrix m1, + matrix *out, mat_processors processors) { + + caller_graph caller = { + .api = "arithmos:matrix#mat_product", + .func = &mat_product, + .params = NULL, + .root = processors.root, + }; + + mat_proc_sig proc_sig = { + .proc = processors, + .caller = caller, + .metadata = processors.metadata + }; + + if (NULL == out || NULL == out->element || + NULL == m0.element || NULL == m1.element) { + if (NULL != processors.on_op_failure) { + processors.on_op_failure(proc_sig, EUNDEFINEDBUFFER); + } + return EUNDEFINEDBUFFER; + } + + proc_sig.mat = *out; + + // preprocessing automata -- validating the general predicate + // P (m*n x n*q == m*q); general predicate for matrix product + if (m0.n != m1.m || + out->m != m0.m || + out->n != m1.n) { + if (NULL != processors.on_op_failure) { + processors.on_op_failure(proc_sig, EBUFFERTURNCATION); + } + return EBUFFERTURNCATION; + } + + vec_component cache; + + uint64_t dot_prod_index; + + struct mat_product_metadata metadata = { + .m0 = &m0, + .m1 = &m1, + .output = out, + .processors = &processors, // performed a chained automata processors + .cache = &cache, + .dot_prod_index = &dot_prod_index + }; + + mat_processors __proc = { + .on_row_iterated = &__on_row_iterated, + .metadata = &metadata + }; + + status_code __code = mat_iterate_rows(m0, __proc); + if (PASS != __code) { + if (NULL != processors.on_op_failure) { + processors.on_op_failure(proc_sig, __code); + } + return __code; + } + + if (NULL != processors.on_op_success) { + processors.on_op_success(proc_sig); + } + + return PASS; +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/matrix/mat_scalar_divide.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/matrix/mat_scalar_divide.c new file mode 100644 index 00000000..9cca8451 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/matrix/mat_scalar_divide.c @@ -0,0 +1,19 @@ +#include + +status_code mat_scalar_divide(matrix m, vec_component scalar, + matrix *out, mat_processors processors) { + caller_graph caller = { + .api = "arithmos:matrix#mat_scalar_divide", + .func = &mat_scalar_divide, + .params = NULL, + .root = processors.root, + }; + + mat_proc_sig proc_sig = { + .proc = processors, + .caller = caller, + .metadata = processors.metadata + }; + + return mat_scalar_prod(m, 1/scalar, out, processors); +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/matrix/mat_scalar_prod.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/matrix/mat_scalar_prod.c new file mode 100644 index 00000000..23c1febf --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/matrix/mat_scalar_prod.c @@ -0,0 +1,115 @@ +#include + +struct mat_scalar_prod_metadata { + matrix *m; + vec_component scalar; + matrix *output; + mat_processors *processors; +}; + +status_code __on_entry_iterated(mat_proc_sig proc_sig) { + // preprocessing automata -- Machine Input + uint64_t row = proc_sig.row_index; + uint64_t column = proc_sig.col_index; + struct mat_scalar_prod_metadata *metadata = proc_sig.proc.metadata; + + matrix m = *(metadata->m); + vec_component scalar = metadata->scalar; + matrix *out = metadata->output; + mat_processors user_proc = *(metadata->processors); + + status_code __code; + + // preprocessing automata -- Execute preprocessing sub-automata + if (NULL != user_proc.on_unary_op_preprocessor) { + __code = user_proc.on_unary_op_preprocessor((mat_proc_sig) { + .mat = m, + .row_index = row, + .col_index = column, + .proc = user_proc, + }); + if (PASS != __code) { + return __code; + } + } + + out->element[row][column] = scalar * m.element[row][column]; + + if (NULL != user_proc.on_elementary_op_postprocessor) { + __code = user_proc.on_elementary_op_postprocessor( + (mat_proc_sig) { + .mat = *out, + .row_index = row, + .col_index = column, + }); + if (PASS != __code) { + return __code; + } + } + + return PASS; +} + +status_code mat_scalar_product(matrix m, vec_component scalar, + matrix *out, mat_processors processors) { + + caller_graph caller = { + .api = "arithmos:matrix#mat_scalar_product", + .func = &mat_scalar_product, + .params = NULL, + .root = processors.root, + }; + + mat_proc_sig proc_sig = { + .proc = processors, + .caller = caller, + .metadata = processors.metadata + }; + + if (NULL == m.element || NULL == out + || NULL == out->element) { + if (NULL != processors.on_op_failure) { + processors.on_op_failure(proc_sig, EUNDEFINEDBUFFER); + } + return EUNDEFINEDBUFFER; + } + + // preprocessing automata -- validating the general predicate + if (m.m != out->m || m.n != out->n) { + if (NULL != processors.on_op_failure) { + processors.on_op_failure(proc_sig, EBUFFERTURNCATION); + } + return EBUFFERTURNCATION; + } + + proc_sig.mat = m; + + struct mat_scalar_prod_metadata metadata = { + .m = &m, + .scalar = scalar, + .output = out, + .processors = &processors, + }; + + mat_processors __proc = { + .on_entry_iterated = &__on_entry_iterated, + .metadata = &metadata + }; + + // processing automata -- iteration and scalar product + status_code __code = mat_iterate_elements(m, ROW_CONVENTION_ITERATOR, __proc); + + // post-processing automata + if (PASS != __code) { + if (NULL != processors.on_op_failure) { + processors.on_op_failure(proc_sig, EBUFFERTURNCATION); + } + return __code; + } + + if (NULL != processors.on_op_success) { + processors.on_op_success(proc_sig); + } + + return PASS; +} \ No newline at end of file diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/matrix/mat_subtract.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/matrix/mat_subtract.c new file mode 100644 index 00000000..654345ac --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/matrix/mat_subtract.c @@ -0,0 +1,103 @@ +#include + +struct mat_subtract_metadata { + matrix *m1; + matrix *output; + mat_processors *processors; +}; + +static inline status_code __on_entry_iterated(mat_proc_sig proc_sig) { + // preprocessing automata -- Machine Input + matrix m0 = proc_sig.mat; + uint64_t row = proc_sig.row_index; + uint64_t column = proc_sig.col_index; + struct mat_subtract_metadata *metadata = proc_sig.proc.metadata; + + matrix m1 = *(metadata->m1); + matrix *out = metadata->output; + mat_processors user_proc = *(metadata->processors); + status_code __code; + + // preprocessing automata -- Execute preprocessing sub-automata + if (NULL != user_proc.on_binary_op_preprocessor) { + __code = user_proc.on_binary_op_preprocessor((mat_binary_op_sig) { + .m0 = m0, + .m1 = m1, + .row_index = row, + .col_index = column, + .proc = user_proc, + }); + if (PASS != __code) { + return __code; + } + } + + // processing automata + out->element[row][column] = + m0.element[row][column] - m1.element[row][column]; + + // postprocessing chain + if (NULL != user_proc.on_elementary_op_postprocessor) { + __code = user_proc.on_elementary_op_postprocessor(proc_sig); + if (PASS != __code) { + return __code; + } + } + + return PASS; +} + +status_code mat_subtract(matrix m0, matrix m1, matrix *out, + mat_processors processors) { + caller_graph caller = { + .api = "arithmos:matrix#mat_subtract", + .func = &mat_subtract, + .params = NULL, + .root = processors.root, + }; + + mat_proc_sig proc_sig = { + .proc = processors, + .caller = caller, + .metadata = processors.metadata + }; + + if (rvalue(out) == NULL || + rvalue(out->element) == NULL) { + return EUNDEFINEDBUFFER; + } + + proc_sig.mat = *out; + + if (m0.m != m1.m || + m0.n != m1.n || + m0.m != out->m || + m0.n != out->n) { + return EBUFFERTURNCATION; + } + + struct mat_subtract_metadata metadata = { + .m1 = &m1, + .output = out, + .processors = &processors, // performed a chained automata processors + }; + + mat_processors __proc = { + .on_entry_iterated = &__on_entry_iterated, + .metadata = &metadata + }; + + status_code __code = mat_iterate_elements(m0, ROW_CONVENTION_ITERATOR, __proc); + if (PASS != __code) { + if (NULL != processors.on_op_failure) { + processors.on_op_failure(proc_sig, __code); + } + return __code; + } + + if (NULL != processors.on_op_success) { + processors.on_op_success(proc_sig); + } + + return PASS; +} \ No newline at end of file diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_add.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_add.c new file mode 100644 index 00000000..58622742 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_add.c @@ -0,0 +1,20 @@ +#include + +status_code vec2d_add(vector2d v0, vector2d v1, vector2d *out, + vec2d_processors *processors) { + if (rvalue(out) == NULL) { + if (NULL != processors && NULL != processors->on_op_failed) { + processors->on_op_failed(&vec2d_add, EUNDEFINEDBUFFER); + } + return EUNDEFINEDBUFFER; + } + + out->x = v0.x + v1.x; + out->y = v0.y + v1.y; + + if (NULL != processors && NULL != processors->on_op_success) { + processors->on_op_success(&vec2d_add, *out); + } + + return PASS; +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_angle.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_angle.c new file mode 100644 index 00000000..2ec6aa6f --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_angle.c @@ -0,0 +1,29 @@ +#include + +status_code vec2d_angle(vector2d v0, vector2d v1, + vec_component *out, vec2d_processors *processors) { + // 1) find the dot product (inner product) + vec_component dot_prod; + status_code __code = vec2d_dot_product(v0, v1, &dot_prod, processors); + if (PASS != __code) { + return __code; + } + + // 2) find the norm of both vectors + vec_component vec0_norm; + vec_component vec1_norm; + + __code = vec2d_length(v0, &vec0_norm, processors); + if (PASS != __code) { + return __code; + } + __code = vec2d_length(v1, &vec1_norm, processors); + if (PASS != __code) { + return __code; + } + + // 3) find the angle of their inner product in this vector space + *out = vector2d_acos(dot_prod / (vec0_norm * vec1_norm)); + + return PASS; +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_are_dependent.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_are_dependent.c new file mode 100644 index 00000000..5ed39e83 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_are_dependent.c @@ -0,0 +1,12 @@ +#include + +status_code vec2d_are_dependent(vector2d v0, vector2d v1, vec2d_processors *processors) { + + vector2d out; + status_code __code = vec2d_divide(v0, v1, &out, processors); + if (PASS != __code) { + return __code; + } + + return out.x == out.y != 0; +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_are_equal.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_are_equal.c new file mode 100644 index 00000000..a484b91d --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_are_equal.c @@ -0,0 +1,17 @@ +#include + +status_code vec2d_are_equal(vector2d v0, vector2d v1, vec2d_processors *processors) { + + if (v0.x != v1.x || v0.y != v1.y) { + if (NULL != processors && NULL != processors->on_op_failed) { + processors->on_op_failed(&vec2d_are_equal, ASSERTION_FAILURE); + } + return ASSERTION_FAILURE; + } + + if (NULL != processors && NULL != processors->on_op_success) { + processors->on_op_success(&vec2d_are_equal, v1); + } + + return PASS; +} \ No newline at end of file diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_are_parallel.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_are_parallel.c new file mode 100644 index 00000000..71f937d1 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_are_parallel.c @@ -0,0 +1,25 @@ +#include + +status_code vec2d_are_parallel(vector2d v0, vector2d v1, vec2d_processors *processors) { + + vec_component dot_prod; + status_code __code = + vec2d_dot_product(v0, v1, &dot_prod, processors); + if (PASS != __code) { + return __code; + } + + vec_component v0_len; + __code = vec2d_length(v0, &v0_len, processors); + if (PASS != __code) { + return __code; + } + + vec_component v1_len; + __code = vec2d_length(v1, &v1_len, processors); + if (PASS != __code) { + return __code; + } + + return dot_prod == (v0_len * v1_len); +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_are_perpendicular.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_are_perpendicular.c new file mode 100644 index 00000000..ab9afb92 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_are_perpendicular.c @@ -0,0 +1,11 @@ +#include + +status_code vec2d_are_perpendicular(vector2d v0, vector2d v1, vec2d_processors *processors) { + vec_component dot_prod; + status_code __code = + vec2d_dot_product(v0, v1, &dot_prod, processors); + if (PASS != __code) { + return __code; + } + return PASS; +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_component.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_component.c new file mode 100644 index 00000000..1b8c0886 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_component.c @@ -0,0 +1,20 @@ +#include + +vector2d VEC2_X_COMPONENT = { + .x = 1, + .y = 0 +}; + +vector2d VEC2_Y_COMPONENT = { + .x = 0, + .y = 1 +}; + +status_code vec2d_component(vector2d v, vector2d comp, + vector2d *out, vec2d_processors *processors) { + if (rvalue(out) == NULL) { + return EUNDEFINEDBUFFER; + } + + return vec2d_product(v, comp, out, processors); +} \ No newline at end of file diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_create_subspace.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_create_subspace.c new file mode 100644 index 00000000..d85f8025 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_create_subspace.c @@ -0,0 +1,41 @@ +#include + +status_code vec2d_create_subspace(vector2d ref_point, + vector2d x_axis, vec2d_space *space, + vec2d_processors *processors) { + if (rvalue(space) == NULL) { + return EUNDEFINEDBUFFER; + } + // 1) subtract the axis from the ref-point to find the x-axis + vector2d space_x; + vector2d rotated_x; + + status_code __code; + + __code = vec2d_subtract(ref_point, x_axis, + &space_x, processors); + if (PASS != __code) { + return __code; + } + + // 2) rotate the axis by 90 degrees; creating a new vector +// +// __code = vec2d_rotate(x_axis, ref_point, M_PI_2); +// if (PASS != __code) { +// return __code; +// } + + // 3) normalize both axes and store them in the space + + __code = vec2d_normalize(space_x, &space->x_axis, processors); + if (PASS != __code) { + return __code; + } + + __code = vec2d_normalize(rotated_x, &space->y_axis, processors); + if (PASS != __code) { + return __code; + } + + return PASS; +} \ No newline at end of file diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_cross_product.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_cross_product.c similarity index 59% rename from electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_cross_product.c rename to electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_cross_product.c index af1a0d58..a82b0078 100644 --- a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_cross_product.c +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_cross_product.c @@ -15,8 +15,15 @@ * = (u1 v2 - u2 v1)ixj * * # Conclusion: - * ixj is the projection k component which is congurent to z-axis in R(3) vectorspaces. + * ixj is the projection k component which is congruent to z-axis in R(3) vectorspaces. */ -coordinate vector2d_cross_product(vector2d vec0, vector2d vec1) { - return vec0.x * vec1.y - vec0.y * vec1.x; +status_code vec2d_cross_product(vector2d v0, vector2d v1, + vec_component *out, vec2d_processors *processors) { + if (rvalue(out) == NULL) { + return EUNDEFINEDBUFFER; + } + + *out = v0.x * v1.y - v0.y * v1.x; + + return PASS; } diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_distance.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_distance.c new file mode 100644 index 00000000..bcdd89ae --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_distance.c @@ -0,0 +1,21 @@ +#include + +status_code vec2d_distance(vector2d v0, vector2d v1, + vec_component *out, vec2d_processors *processors) { + if (rvalue(out) == NULL) { + return EUNDEFINEDBUFFER; + } + + vector2d subtract = {}; + status_code __code = vec2d_subtract(v0, v1, &subtract, processors); + if (PASS != __code) { + return __code; + } + + __code = vec2d_length(subtract, out, processors); + if (PASS != __code) { + return __code; + } + + return PASS; +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_divide.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_divide.c new file mode 100644 index 00000000..b6a5af62 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_divide.c @@ -0,0 +1,13 @@ +#include + +status_code vec2d_divide(vector2d v0, vector2d v1, + vector2d *out, vec2d_processors *processors) { + if (rvalue(out) == NULL) { + return EUNDEFINEDBUFFER; + } + + out->x = v0.x / v1.x; + out->y = v0.y / v1.y; + + return PASS; +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_dot_product.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_dot_product.c new file mode 100644 index 00000000..8a8c0a0e --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_dot_product.c @@ -0,0 +1,10 @@ +#include + +status_code vec2d_dot_product(vector2d v0, vector2d v1, + vec_component *out, vec2d_processors *processors) { + if (rvalue(out) == NULL) { + return EUNDEFINEDBUFFER; + } + *out = v0.x * v1.x + v0.y * v1.y; + return PASS; +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_extrapolate.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_extrapolate.c new file mode 100644 index 00000000..14a5706c --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_extrapolate.c @@ -0,0 +1,14 @@ +#include + +status_code vec2d_extrapolate(vector2d v0, vector2d v1, + vec_component scale, vector2d *out, + vec2d_processors *processors) { + if (rvalue(out) == NULL) { + return EUNDEFINEDBUFFER; + } + + out->x = ((v0.x + v1.x) * scale) + v0.x; + out->y = ((v0.y + v1.y) * scale) + v0.y; + + return PASS; +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_interpolate.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_interpolate.c new file mode 100644 index 00000000..4fd09337 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_interpolate.c @@ -0,0 +1,17 @@ +#include + +status_code vec2d_interpolate(vector2d v0, vector2d v1, + vec_component scale, vector2d *out, + vec2d_processors *processors) { + if (rvalue(out) == NULL) { + return EUNDEFINEDBUFFER; + } + // 1) find the absolute x_distance and y_distance + vec_component x_distance = vector2d_abs(v0.x - v1.x); + vec_component y_distance = vector2d_abs(v0.y - v1.y); + // 2) interpolate between components with a scale starting from the first vector + out->x = ((x_distance) * scale) + v0.x; + out->y = ((y_distance) * scale) + v0.y; + + return PASS; +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_is_rotated.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_is_rotated.c new file mode 100644 index 00000000..badb799f --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_is_rotated.c @@ -0,0 +1,21 @@ +#include + +status_code vec2d_is_rotated(vector2d v0, vector2d v1, vec_component angle, + vec2d_processors *processors) { + vector2d vec = {}; + vec.x = v0.x * vector2d_cos(angle) - v0.y * vector2d_sin(angle); + vec.y = v0.x * vector2d_sin(angle) + v0.y * vector2d_cos(angle); + + if (v1.x != vec.x || v1.y != vec.y) { + if (NULL != processors && NULL != processors->on_op_failed) { + processors->on_op_failed(&vec2d_is_rotated, ASSERTION_FAILURE); + } + return ASSERTION_FAILURE; + } + + if (NULL != processors && NULL != processors->on_op_success) { + processors->on_op_success(&vec2d_is_rotated, v1); + } + + return PASS; +} \ No newline at end of file diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_is_unit.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_is_unit.c new file mode 100644 index 00000000..830d6976 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_is_unit.c @@ -0,0 +1,26 @@ +#include +#include + +status_code vec2d_is_unit(vector2d v, vec2d_processors *procs) { + vec_component out; + status_code __code = vec2d_length(v, &out, NULL); + if (__code != PASS) { + if (NULL != procs && NULL != procs->on_op_failed) { + procs->on_op_failed(&vec2d_is_unit, __code); + } + return __code; + } + + if (round(out) != 1) { + if (NULL != procs && NULL != procs->on_op_failed) { + procs->on_op_failed(&vec2d_is_unit, ASSERTION_FAILURE); + } + return ASSERTION_FAILURE; + } + + if (NULL != procs && NULL != procs->on_op_success) { + procs->on_op_success(&vec2d_is_unit, v); + } + + return PASS; +} \ No newline at end of file diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_length.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_length.c new file mode 100644 index 00000000..2e9e4412 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_length.c @@ -0,0 +1,13 @@ +#include + +status_code vec2d_length(vector2d v, vec_component *out, + vec2d_processors *processors) { + if (rvalue(out) == NULL) { + return EUNDEFINEDBUFFER; + } + + float sum = powf(v.x, 2) + powf(v.y, 2); + *out = (vec_component) powf(sum, 0.5f); + + return PASS; +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_moduluo.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_moduluo.c new file mode 100644 index 00000000..93790f16 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_moduluo.c @@ -0,0 +1,11 @@ +#include + +status_code vec2d_moduluo(vector2d v0, vector2d v1, + vector2d *out, vec2d_processors *processors) { + if (rvalue(out) == NULL) { + return EUNDEFINEDBUFFER; + } + out->x = ((mod_vec_component) v0.x) % ((mod_vec_component) v1.x); + out->y = ((mod_vec_component) v0.y) % ((mod_vec_component) v1.y); + return PASS; +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_negate.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_negate.c new file mode 100644 index 00000000..98464c40 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_negate.c @@ -0,0 +1,28 @@ +#include + +status_code vec2d_negate(vector2d v, vector2d axis, + vector2d *out, vec2d_processors *processors) { + if (NULL == out) { + if (NULL != processors && NULL != processors->on_op_failed) { + processors->on_op_failed(&vec2d_negate, EUNDEFINEDBUFFER); + } + return EUNDEFINEDBUFFER; + } + + out->x = v.x * -1 * axis.x; + out->y = v.y * -1 * axis.y; + + if (out->x == 0) { + out->x = v.x; + } + + if (out->y == 0) { + out->y = v.y; + } + + if (NULL != processors && NULL != processors->on_op_success) { + processors->on_op_success(&vec2d_negate, *out); + } + + return PASS; +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_normalize.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_normalize.c new file mode 100644 index 00000000..f87357c6 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_normalize.c @@ -0,0 +1,15 @@ +#include + +status_code vec2d_normalize(vector2d v, vector2d *out, vec2d_processors *processors) { + if (rvalue(out) == NULL) { + return EUNDEFINEDBUFFER; + } + + vec_component length; + status_code __code = vec2d_length(v, &length, processors); + if (PASS != __code) { + return __code; + } + + return vec2d_scalar_divide(v, length, out, processors); +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_product.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_product.c new file mode 100644 index 00000000..6a8ae35e --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_product.c @@ -0,0 +1,12 @@ +#include + +status_code vec2d_product(vector2d v0, vector2d v1, vector2d *out, + vec2d_processors *processors) { + if (rvalue(out) == NULL) { + return EUNDEFINEDBUFFER; + } + out->x = v0.x * v1.x; + out->y = v0.y * v1.y; + + return PASS; +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_projection_vector.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_projection_vector.c new file mode 100644 index 00000000..1d8dd074 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_projection_vector.c @@ -0,0 +1,40 @@ +#include + +status_code vec2d_projection_vector(vector2d v, vector2d u, vector2d *proj, vec2d_processors *processors) { + if (rvalue(proj) == NULL) { + return EUNDEFINEDBUFFER; + } + + status_code __code; + vec_component dot_prod; + vector2d norm_u; + vec_component length_u; + + // 1) find the dot product of vectors (v, u) + __code = vec2d_dot_product(v, u, &dot_prod, processors); + if (PASS != __code) { + return __code; + } + + // 2) find the norm of vector u + __code = vec2d_normalize(u, &norm_u, processors); + if (PASS != __code) { + return __code; + } + + // 3) find the length of vector u + __code = vec2d_length(u, &length_u, processors); + if (PASS != __code) { + return __code; + } + + // 4) the component ||v||.cos(theta).n is the projection vector + __code = vec2d_scalar_multiply(norm_u, + ((vec_component) dot_prod/length_u), + proj, processors); + if (PASS != __code) { + return __code; + } + + return PASS; +} \ No newline at end of file diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_retrieve_polar.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_retrieve_polar.c new file mode 100644 index 00000000..96b36255 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_retrieve_polar.c @@ -0,0 +1,16 @@ +#include + +status_code vec2d_retrieve_polar(vector2d v, vec2d_polar *out, vec2d_processors *processors) { + if (rvalue(out) == NULL) { + return EUNDEFINEDBUFFER; + } + + // calculate length of the vector + status_code __code = vec2d_length(v, &(out->r), processors); + if (PASS != __code) { + return __code; + } + out->phi = vector2d_atan2(v.y, v.x); + + return PASS; +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_retrieve_rectangular.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_retrieve_rectangular.c new file mode 100644 index 00000000..1c12c967 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_retrieve_rectangular.c @@ -0,0 +1,13 @@ +#include + +status_code vec2d_retrieve_rectangular(vec2d_polar polar, vector2d *rect, + vec2d_processors *processors) { + if (rvalue(rect) == NULL) { + return EUNDEFINEDBUFFER; + } + + rect->x = polar.r * ((vec_component) cosf(polar.phi)); + rect->y = polar.r * ((vec_component) sinf(polar.phi)); + + return PASS; +} \ No newline at end of file diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_rotate.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_rotate.c new file mode 100644 index 00000000..18581017 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_rotate.c @@ -0,0 +1,130 @@ +#include +#include + +struct vec2d_orient_metadata { + matrix *local; + matrix *shared; +}; + +status_code __on_op_postprocessor(mat_proc_sig proc_sig) { + struct vec2d_orient_metadata *metadata = proc_sig.metadata; + uint64_t row = proc_sig.row_index; + uint64_t column = proc_sig.col_index; + + matrix *local = metadata->local; + + // post-processing -- deep copy the new orientation of the two axes + if (vector2d_abs(local->element[row][column]) + <= ___ROTATION_MIN_THRESHOLD) { + local->element[row][column] = 0; + } else { + local->element[row][column] = vector2d_abs(local->element[row][column]); + } + + return PASS; +} + +static inline status_code __on_entry_iterated(mat_proc_sig proc_sig) { + struct vec2d_orient_metadata *metadata = proc_sig.metadata; + uint64_t row = proc_sig.row_index; + uint64_t column = proc_sig.col_index; + + matrix *local = metadata->local; + matrix *shared = metadata->shared; + + shared->element[row][column] = local->element[row][column]; + + return PASS; +} + +status_code vec2d_rotate(vector2d v, vector2d axis, vec_component angle, + vector2d *out, vec2d_processors *processors) { + + // Pre-processing Automata -- Machine Input Validation + if (rvalue(out) == NULL) { + return EUNDEFINEDBUFFER; + } + + if (rvalue(out->orientation) == NULL) { + return EUNDEFINEDBUFFER; + } + + if (NULL == v.orientation || NULL == out->orientation + || NULL == v.orientation->element || NULL == out->orientation->element) { + return EUNDEFINEDBUFFER; + } + + if ((v.orientation->n != 2) || + (v.orientation->m != v.orientation->n)) { + return EBUFFERTURNCATION; + } + + // use the complementary angle if the angle + // is ordered with the positive direction of y-axis. + if (axis.y) { + angle = M_PI - angle; + } + + // processing automata -- rotate the vector + out->x = v.x * vector2d_cos(angle) - v.y * vector2d_sin(angle); + out->y = v.x * vector2d_sin(angle) + v.y * vector2d_cos(angle); + + // post-processing -- rotate the orientation vectors + // allocate a rotator matrix + vec_component x_comps[2] = {vector2d_cos(angle), -vector2d_sin(angle)}; + vec_component y_comps[2] = {vector2d_sin(angle), vector2d_cos(angle)}; + vec_component *comps[2] = {x_comps, y_comps}; + matrix rotator = { + .element = comps, + .m = 2, + .n = 2 + }; + + // allocate an output orientator + vec_component out_x[2] = {0, 0}; + vec_component out_y[2] = {0, 0}; + vec_component *out_comps[2] = {out_x, out_y}; + matrix out_orientator = { + .element = out_comps, + .m = 2, + .n = 2 + }; + + struct vec2d_orient_metadata metadata = { + .local = &out_orientator, + .shared = out->orientation + }; + + mat_processors procs = { + .on_elementary_op_postprocessor = &__on_op_postprocessor, + .on_entry_iterated = &__on_entry_iterated, + .metadata = &metadata + }; + + // rotate the orientation using matrix algebra + status_code __code = mat_product(rotator, *(v.orientation), + &out_orientator, procs); + if (PASS != __code) { + if (NULL != processors && NULL != processors->on_op_failed) { + processors->on_op_failed(&vec2d_rotate, __code); + } + return __code; + } + + // postprocessing finalizing automata -- + // deep copy the values to the output orientation + __code = mat_iterate_elements(out_orientator, + ROW_CONVENTION_ITERATOR, procs); + if (PASS != __code) { + if (NULL != processors && NULL != processors->on_op_failed) { + processors->on_op_failed(&vec2d_rotate, __code); + } + return __code; + } + + if (NULL != processors && NULL != processors->on_op_success) { + processors->on_op_success(&vec2d_rotate, *out); + } + + return PASS; +} \ No newline at end of file diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_scalar_add.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_scalar_add.c new file mode 100644 index 00000000..1a1e69ef --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_scalar_add.c @@ -0,0 +1,12 @@ +#include + +status_code vec2d_scalar_add(vector2d vec, vec_component scalar, vector2d *out, + vec2d_processors *processors) { + if (rvalue(out) == NULL) { + return EUNDEFINEDBUFFER; + } + out->x = vec.x + scalar; + out->y = vec.y + scalar; + + return PASS; +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_scalar_divide.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_scalar_divide.c new file mode 100644 index 00000000..8fb9af84 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_scalar_divide.c @@ -0,0 +1,12 @@ +#include + +status_code vec2d_scalar_divide(vector2d v0, vec_component scalar, + vector2d *out, vec2d_processors *processors) { + if (rvalue(out) == NULL) { + return EUNDEFINEDBUFFER; + } + out->x = v0.x / scalar; + out->y = v0.y / scalar; + + return PASS; +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_scalar_multiply.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_scalar_multiply.c new file mode 100644 index 00000000..61d9b96b --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_scalar_multiply.c @@ -0,0 +1,12 @@ +#include + +status_code vec2d_scalar_multiply(vector2d v, vec_component scalar, + vector2d *out, vec2d_processors *processors) { + if (rvalue(out) == NULL) { + return EUNDEFINEDBUFFER; + } + out->x = v.x * scalar; + out->y = v.y * scalar; + + return PASS; +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_scalar_subtract.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_scalar_subtract.c new file mode 100644 index 00000000..56b7fc6d --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_scalar_subtract.c @@ -0,0 +1,11 @@ +#include + +status_code vec2d_scalar_subtract(vector2d v, vec_component scalar, + vector2d *out, vec2d_processors *processors) { + if (rvalue(out) == NULL) { + return EUNDEFINEDBUFFER; + } + out->x = v.x - scalar; + out->y = v.y - scalar; + return PASS; +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_subtract.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_subtract.c new file mode 100644 index 00000000..a563c8d2 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_subtract.c @@ -0,0 +1,23 @@ +#include + +status_code vec2d_subtract(vector2d v0, vector2d v1, + vector2d *out, vec2d_processors *processors) { + if (rvalue(out) == NULL) { + return EUNDEFINEDBUFFER; + } + // find the negation of v1 + status_code __code; + vector2d neg_v1; + vector2d neg_unit = { + .x = (vec_component) -1, + .y = (vec_component) -1, + }; + + __code = vec2d_product(v1, neg_unit, &neg_v1, processors); + if (PASS != __code) { + return __code; + } + // calculate the addition primitive op. + + return vec2d_add(v0, neg_v1, out, processors); +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_swap_components.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_swap_components.c new file mode 100644 index 00000000..d034bde2 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vec2d_swap_components.c @@ -0,0 +1,19 @@ +#include + +status_code vec2d_swap_components(vector2d v, vector2d *out, vec2d_processors *processors) { + if (NULL == out) { + if (NULL != processors && NULL != processors->on_op_failed) { + processors->on_op_failed(&vec2d_swap_components, EUNDEFINEDBUFFER); + } + return EUNDEFINEDBUFFER; + } + + out->x = v.y; + out->y = v.x; + + if (NULL != processors && NULL != processors->on_op_success) { + processors->on_op_success(&vec2d_swap_components, *out); + } + + return PASS; +} \ No newline at end of file diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_add.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_add.c deleted file mode 100644 index e6571ffd..00000000 --- a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_add.c +++ /dev/null @@ -1,8 +0,0 @@ -#include - -vector2d vector2d_add(vector2d vec0, vector2d vec1) { - return (vector2d) { - vec0.x + vec1.x, - vec0.y + vec1.y - }; -} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_angle.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_angle.c deleted file mode 100644 index b450bb6a..00000000 --- a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_angle.c +++ /dev/null @@ -1,11 +0,0 @@ -#include - -coordinate vector2d_angle(vector2d vec0, vector2d vec1) { - // 1) find the dot product - coordinate product = vector2d_dot_product(vec0, vec1); - // 2) find the norm of both vectors - coordinate vec0_norm = vector2d_length(vec0); - coordinate vec1_norm = vector2d_length(vec1); - // 3) find the angle of their inner product in this vector space - return vector2d_acos(product / (vec0_norm * vec1_norm)); -} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_are_dependent.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_are_dependent.c deleted file mode 100644 index 1eb590fe..00000000 --- a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_are_dependent.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -uint8_t vector2d_are_dependent(vector2d vec0, vector2d vec1) { - vector2d constant = vector2d_divide(vec0, vec1); - return constant.x == constant.y != 0; -} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_are_parallel.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_are_parallel.c deleted file mode 100644 index f387fa29..00000000 --- a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_are_parallel.c +++ /dev/null @@ -1,5 +0,0 @@ -#include - -uint8_t vector2d_are_parallel(vector2d vec0, vector2d vec1) { - return vector2d_dot_product(vec0, vec1) == (vector2d_length(vec0) * vector2d_length(vec1)); -} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_are_perpendicular.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_are_perpendicular.c deleted file mode 100644 index 7ac745ba..00000000 --- a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_are_perpendicular.c +++ /dev/null @@ -1,5 +0,0 @@ -#include - -uint8_t vector2d_are_perpendicular(vector2d vec0, vector2d vec1) { - return vector2d_dot_product(vec0, vec1) == 0; -} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_distance.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_distance.c deleted file mode 100644 index 1f70d09a..00000000 --- a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_distance.c +++ /dev/null @@ -1,5 +0,0 @@ -#include - -coordinate vector2d_distance(vector2d vec0, vector2d vec1) { - return vector2d_length(vector2d_subtract(vec0, vec1)); -} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_divide.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_divide.c deleted file mode 100644 index f93dbea8..00000000 --- a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_divide.c +++ /dev/null @@ -1,8 +0,0 @@ -#include - -vector2d vector2d_divide(vector2d vec0, vector2d vec1) { - return (vector2d) { - vec0.x / vec1.x, - vec0.y / vec1.y - }; -} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_dot_product.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_dot_product.c deleted file mode 100644 index 8c10610c..00000000 --- a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_dot_product.c +++ /dev/null @@ -1,5 +0,0 @@ -#include - -coordinate vector2d_dot_product(vector2d vec0, vector2d vec1) { - return vec0.x * vec1.x + vec0.y * vec1.y; -} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_extrapolate.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_extrapolate.c deleted file mode 100644 index 2d380912..00000000 --- a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_extrapolate.c +++ /dev/null @@ -1,8 +0,0 @@ -#include - -vector2d vector2d_extrapolate(vector2d vec0, vector2d vec1, coordinate scale) { - return (vector2d) { - ((vec0.x + vec1.x) * scale) + vec0.x, - ((vec0.y + vec1.y) * scale) + vec0.y - }; -} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_interpolate.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_interpolate.c deleted file mode 100644 index b46b1bfd..00000000 --- a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_interpolate.c +++ /dev/null @@ -1,12 +0,0 @@ -#include - -vector2d vector2d_interpolate(vector2d vec0, vector2d vec1, coordinate scale) { - // 1) find the absolute x_distance and y_distance - coordinate x_distance = vector2d_abs(vec0.x - vec1.x); - coordinate y_distance = vector2d_abs(vec0.y - vec1.y); - // 2) interpolate between components with a scale starting from the first vector - return (vector2d) { - ((x_distance) * scale) + vec0.x, - ((y_distance) * scale) + vec0.y - };; -} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_length.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_length.c deleted file mode 100644 index 38a0cdc8..00000000 --- a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_length.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -coordinate vector2d_length(vector2d vec) { - float sum = powf(vec.x, 2) + powf(vec.y, 2); - return powf(sum, 0.5); -} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_normalize.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_normalize.c deleted file mode 100644 index e9ac795e..00000000 --- a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_normalize.c +++ /dev/null @@ -1,5 +0,0 @@ -#include - -vector2d vector2d_normalize(vector2d vec) { - return vector2d_scalar_divide(vec, vector2d_length(vec)); -} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_polar.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_polar.c deleted file mode 100644 index f5999b0f..00000000 --- a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_polar.c +++ /dev/null @@ -1,5 +0,0 @@ -#include - -coordinate vector2d_polar(vector2d vec) { - return vector2d_atan2(vec.y, vec.x); -} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_product.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_product.c deleted file mode 100644 index 12b4c039..00000000 --- a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_product.c +++ /dev/null @@ -1,8 +0,0 @@ -#include - -vector2d vector2d_product(vector2d vec0, vector2d vec1) { - return (vector2d) { - vec0.x * vec1.x, - vec0.y * vec1.y - }; -} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_scalar_add.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_scalar_add.c deleted file mode 100644 index 5dbd23db..00000000 --- a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_scalar_add.c +++ /dev/null @@ -1,7 +0,0 @@ -#include - -vector2d vector2d_scalar_add(vector2d vec, coordinate scalar) { - vec.x += scalar; - vec.y += scalar; - return vec; -} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_scalar_divide.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_scalar_divide.c deleted file mode 100644 index 2de75086..00000000 --- a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_scalar_divide.c +++ /dev/null @@ -1,7 +0,0 @@ -#include - -vector2d vector2d_scalar_divide(vector2d vec, coordinate scalar) { - vec.x /= scalar; - vec.y /= scalar; - return vec; -} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_scalar_moduluo.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_scalar_moduluo.c deleted file mode 100644 index 8ded3955..00000000 --- a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_scalar_moduluo.c +++ /dev/null @@ -1,7 +0,0 @@ -#include - -vector2d vector2f_scalar_moduluo(vector2d vec, coordinate scalar) { - vec.x = ((mod_coordinate) vec.x) % ((mod_coordinate) scalar); - vec.y = ((mod_coordinate) vec.y) % ((mod_coordinate) scalar); - return vec; -} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_scalar_multiply.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_scalar_multiply.c deleted file mode 100644 index a6b4e627..00000000 --- a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_scalar_multiply.c +++ /dev/null @@ -1,7 +0,0 @@ -#include - -vector2d vector2d_scalar_multiply(vector2d vec, coordinate scalar) { - vec.x *= scalar; - vec.y *= scalar; - return vec; -} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_scalar_subtract.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_scalar_subtract.c deleted file mode 100644 index 52acdc64..00000000 --- a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_scalar_subtract.c +++ /dev/null @@ -1,7 +0,0 @@ -#include - -vector2d vector2d_scalar_subtract(vector2d vec, coordinate scalar) { - vec.x -= scalar; - vec.y -= scalar; - return vec; -} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_subtract.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_subtract.c deleted file mode 100644 index 210c072d..00000000 --- a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector2d/vector2d_subtract.c +++ /dev/null @@ -1,8 +0,0 @@ -#include - -vector2d vector2d_subtract(vector2d vec0, vector2d vec1) { - return (vector2d) { - vec0.x - vec1.x, - vec0.y - vec1.y - }; -} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_abs.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_abs.c new file mode 100644 index 00000000..e41496a8 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_abs.c @@ -0,0 +1,14 @@ +#include +#include + +status_code vec3d_abs(vector3d in, vector3d *out, vec3d_processors *procs) { + if (NULL == out) { + return EUNDEFINEDBUFFER; + } + + out->x = vector2d_abs(in.x); + out->y = vector2d_abs(in.y); + out->z = vector2d_abs(in.z); + + return PASS; +} \ No newline at end of file diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_add.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_add.c new file mode 100644 index 00000000..24847a06 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_add.c @@ -0,0 +1,44 @@ +#include +#include + +status_code vec3d_add(vector3d v0, vector3d v1, vector3d *out, + vec3d_processors *processors) { + if (rvalue(out) == NULL) { + return EUNDEFINEDBUFFER; + } + + vector2d v0_xy = { + .x = v0.x, + .y = v0.y, + }; + vector2d v0_z = { + .y = v0.z, + }; + + vector2d v1_xy = { + .x = v1.x, + .y = v1.y + }; + vector2d v1_z = { + .y = v1.z, + }; + status_code __code; + vector2d xy_out; + vector2d z_out; + + __code = vec2d_add(v0_xy, v1_xy, &xy_out, NULL); + if (PASS != __code) { + return __code; + } + + __code = vec2d_add(v0_z, v1_z, &z_out, NULL); + if (PASS != __code) { + return __code; + } + + out->x = xy_out.x; + out->y = xy_out.y; + out->z = z_out.y; + + return PASS; +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_are_equal.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_are_equal.c new file mode 100644 index 00000000..c268d183 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_are_equal.c @@ -0,0 +1,17 @@ +#include +#include + +status_code vec3d_are_equal(vector3d v0, vector3d v1, vec3d_processors *proc) { + if (!(v0.x == v1.x && v0.y == v1.y && v0.z == v1.z)) { + if (NULL != proc && NULL != proc->on_op_failed) { + proc->on_op_failed(&vec3d_are_equal, ASSERTION_FAILURE); + } + return ASSERTION_FAILURE; + } + + if (NULL != proc && NULL != proc->on_op_success) { + proc->on_op_success(&vec3d_are_equal, v0); + } + + return PASS; +} \ No newline at end of file diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_component.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_component.c new file mode 100644 index 00000000..e06e98f9 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_component.c @@ -0,0 +1,29 @@ +#include +#include + +vector3d VEC3_X_COMPONENT = { + .x = 1, + .y = 0, + .z = 0 +}; + +vector3d VEC3_Y_COMPONENT = { + .x = 0, + .y = 1, + .z = 0 +}; + +vector3d VEC3_Z_COMPONENT = { + .x = 0, + .y = 0, + .z = 1 +}; + +status_code vec3d_component(vector3d v, vector3d comp, + vector3d *out, vec3d_processors *processors) { + if (rvalue(out) == NULL) { + return EUNDEFINEDBUFFER; + } + + return vec3d_product(v, comp, out, processors); +} \ No newline at end of file diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_divide.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_divide.c new file mode 100644 index 00000000..a1e5c8d8 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_divide.c @@ -0,0 +1,44 @@ +#include +#include + +status_code vec3d_divide(vector3d v0, vector3d v1, + vector3d *out, vec3d_processors *processors) { + if (rvalue(out) == NULL) { + return EUNDEFINEDBUFFER; + } + + vector2d v0_xy = { + .x = v0.x, + .y = v0.y + }; + vector2d v0_z = { + .y = v0.z, + }; + + vector2d v1_xy = { + .x = v1.x, + .y = v1.y + }; + vector2d v1_z = { + .y = v1.z, + }; + status_code __code; + vector2d xy_out; + vector2d z_out; + + __code = vec2d_divide(v0_xy, v1_xy, &xy_out, NULL); + if (PASS != __code) { + return __code; + } + + __code = vec2d_divide(v0_z, v1_z, &z_out, NULL); + if (PASS != __code) { + return __code; + } + + out->x = xy_out.x; + out->y = xy_out.y; + out->z = z_out.y; + + return PASS; +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_extrapolate.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_extrapolate.c new file mode 100644 index 00000000..9f846dba --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_extrapolate.c @@ -0,0 +1,46 @@ +#include +#include + +status_code vec3d_extrapolate(vector3d v0, vector3d v1, + vec_component scale, vector3d *out, + vec3d_processors *processors) { + if (rvalue(out) == NULL) { + return EUNDEFINEDBUFFER; + } + + status_code __code; + vector2d extrapolated_vec; + + vector2d v0_xy = { + .x = v0.x, + .y = v0.y, + }; + vector2d v0_z = { + .y = v0.z, + }; + + vector2d v1_xy = { + .x = v1.x, + .y = v1.y, + }; + vector2d v1_z = { + .y = v1.z, + }; + + __code = vec2d_extrapolate(v0_xy, v1_xy, scale, &extrapolated_vec, NULL); + if (PASS != __code) { + return __code; + } + + out->x = extrapolated_vec.x; + out->y = extrapolated_vec.y; + + __code = vec2d_extrapolate(v0_z, v1_z, scale, &extrapolated_vec, NULL); + if (PASS != __code) { + return __code; + } + + out->z = extrapolated_vec.y; + + return PASS; +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_interpolate.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_interpolate.c new file mode 100644 index 00000000..c22aeaad --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_interpolate.c @@ -0,0 +1,46 @@ +#include +#include + +status_code vec3d_interpolate(vector3d v0, vector3d v1, + vec_component scale, vector3d *out, + vec3d_processors *processors) { + if (rvalue(out) == NULL) { + return EUNDEFINEDBUFFER; + } + + status_code __code; + vector2d interpolated_vec; + + vector2d v0_xy = { + .x = v0.x, + .y = v0.y, + }; + vector2d v0_z = { + .y = v0.z, + }; + + vector2d v1_xy = { + .x = v1.x, + .y = v1.y, + }; + vector2d v1_z = { + .y = v1.z, + }; + + __code = vec2d_interpolate(v0_xy, v1_xy, scale, &interpolated_vec, NULL); + if (PASS != __code) { + return __code; + } + + out->x = interpolated_vec.x; + out->y = interpolated_vec.y; + + __code = vec2d_interpolate(v0_z, v1_z, scale, &interpolated_vec, NULL); + if (PASS != __code) { + return __code; + } + + out->z = interpolated_vec.y; + + return PASS; +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_length.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_length.c new file mode 100644 index 00000000..c0b0ce40 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_length.c @@ -0,0 +1,31 @@ +#include +#include + +status_code vec3d_length(vector3d v, vec_component *out, + vec3d_processors *processors) { + if (rvalue(out) == NULL) { + return EUNDEFINEDBUFFER; + } + + status_code __code; + + vector2d v_xy = { + .x = v.x, + .y = v.y, + }; + vector2d v_z = { + .y = v.z, + }; + + __code = vec2d_length(v_xy, &(v_z.x), NULL); + if (PASS != __code) { + return __code; + } + + __code = vec2d_length(v_z, out, NULL); + if (PASS != __code) { + return __code; + } + + return PASS; +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_normalize.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_normalize.c new file mode 100644 index 00000000..18fb1aea --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_normalize.c @@ -0,0 +1,16 @@ +#include +#include + +status_code vec3d_normalize(vector3d v, vector3d *out, vec3d_processors *processors) { + if (rvalue(out) == NULL) { + return EUNDEFINEDBUFFER; + } + + vec_component length; + status_code __code = vec3d_length(v, &length, processors); + if (PASS != __code) { + return __code; + } + + return vec3d_scalar_divide(v, length, out, processors); +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_product.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_product.c new file mode 100644 index 00000000..f6bb3011 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_product.c @@ -0,0 +1,44 @@ +#include +#include + +status_code vec3d_product(vector3d v0, vector3d v1, vector3d *out, + vec3d_processors *processors) { + if (rvalue(out) == NULL) { + return EUNDEFINEDBUFFER; + } + + vector2d v0_xy = { + .x = v0.x, + .y = v0.y + }; + vector2d v0_z = { + .y = v0.z, + }; + + vector2d v1_xy = { + .x = v1.x, + .y = v1.y + }; + vector2d v1_z = { + .y = v1.z, + }; + status_code __code; + vector2d xy_out; + vector2d z_out; + + __code = vec2d_product(v0_xy, v1_xy, &xy_out, NULL); + if (PASS != __code) { + return __code; + } + + __code = vec2d_product(v0_z, v1_z, &z_out, NULL); + if (PASS != __code) { + return __code; + } + + out->x = xy_out.x; + out->y = xy_out.y; + out->z = z_out.y; + + return PASS; +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_retrieve_polar.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_retrieve_polar.c new file mode 100644 index 00000000..37f40828 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_retrieve_polar.c @@ -0,0 +1,48 @@ +#include +#include + +status_code vec3d_retrieve_polar(vector3d v, vec3d_polar *out, + vec3d_processors *processors) { + if (rvalue(out) == NULL) { + return EUNDEFINEDBUFFER; + } + + vec2d_polar polar_vector; + status_code __code; + + vector2d v_xy = { + .x = v.x, + .y = v.y, + }; + vector2d v_z = { + .y = v.z, + }; + + __code = vec3d_length(v, &(out->r), processors); + if (PASS != __code) { + return __code; + } + + __code = vec2d_retrieve_polar(v_xy, &polar_vector, NULL); + if (PASS != __code) { + return __code; + } + + out->phi = polar_vector.phi; + + // find the resultant vector component of the XY plane + // put the result into the v_z (x component) + __code = vec2d_length(v_xy, &(v_z.x), NULL); + if (PASS != __code) { + return __code; + } + + __code = vec2d_retrieve_polar(v_z, &polar_vector, NULL); + if (PASS != __code) { + return __code; + } + + out->theta = polar_vector.phi; + + return PASS; +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_rotate.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_rotate.c new file mode 100644 index 00000000..c048b970 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_rotate.c @@ -0,0 +1,343 @@ +#include +#include +#include + +struct rotation_metadata { + matrix *in_orientation; + matrix *out_orientation; +}; + +typedef enum { + GIMBAL_X = (INT16_MAX >> 8) ^ INT16_MAX, + GIMBAL_Y = GIMBAL_X - 1, + GIMBAL_Z = GIMBAL_Y - 1 +} vector_gimbal; + +static inline void preprocess_orientator(vector3d *v, vector3d *axis) { + + // create a column vector matrix + vec_component axis_x[1] = {0,}; + vec_component axis_y[1] = {0,}; + vec_component axis_z[1] = {0,}; + vec_component *axis_comps[3] = {axis_x, axis_y, axis_z}; + matrix __axis = { + .element = axis_comps, + .m = 3, + .n = 1 + }; + + mat_processors procs = { + }; + mat_create_from_vector3d(*axis, &__axis, procs); + + // find the position of the orientation vectors + vec_component _axis_x[1] = {0,}; + vec_component _axis_y[1] = {0,}; + vec_component _axis_z[1] = {0,}; + vec_component *_axis_comps[3] = {_axis_x, _axis_y, _axis_z}; + matrix ___axis = { + .element = _axis_comps, + .m = 3, + .n = 1 + }; + mat_product(*(v->gimbal.orientation), __axis, &___axis, procs); + + axis->x = *(___axis.element[0]); + axis->y = *(___axis.element[1]); + axis->z = *(___axis.element[2]); +} + +static inline status_code __on_entry_iterated(mat_proc_sig proc_sig) { + struct rotation_metadata *metadata = proc_sig.metadata; + matrix *in_orientation = metadata->in_orientation; + matrix *out_orientation = metadata->out_orientation; + uint64_t row_index = proc_sig.row_index; + uint64_t col_index = proc_sig.col_index; + + out_orientation->element[row_index][col_index] = + in_orientation->element[row_index][col_index]; + + return PASS; +} + +static inline vector_gimbal get_vec_gimbal(vector3d *axis) { + if ((axis->x > ___ROTATION_MIN_THRESHOLD) && + ((axis->y >= 0) && (axis->y < 1)) && + ((axis->z >= 0) && (axis->z < 1))) { + + return GIMBAL_X; + } else if ((axis->y > ___ROTATION_MIN_THRESHOLD) && + ((axis->x >= 0) && (axis->x < 1)) && + ((axis->z >= 0) && (axis->z < 1))) { + + return GIMBAL_Y; + } else if ((axis->z > ___ROTATION_MIN_THRESHOLD) && + ((axis->y >= 0) && (axis->y < 1)) && + ((axis->x >= 0) && (axis->x < 1))) { + + return GIMBAL_Z; + } + return -1; +} + +static inline status_code init_rotator_gimbal(vector3d *axis, matrix *__rotator, + vec_component angle, + vec_component *angle1, + vec3d_gimbal *gimbal) { + if (get_vec_gimbal(axis) == GIMBAL_Z) { + // rotate around z-axis + // pre-processing automata + // Let the X-axis in the R(3) space be the X-axis in the 2D projection. + // Let the Y-axis in the R(3) space be the Y-axis in the 2D projection. + + // work in XY plane + __rotator->element[0][0] = vector2d_cos(angle); + __rotator->element[0][1] = -vector2d_sin(angle); + __rotator->element[1][0] = vector2d_sin(angle); + __rotator->element[1][1] = vector2d_cos(angle); + __rotator->element[2][2] = 1; + + gimbal->z_gimbal += angle; + *angle1 = gimbal->z_gimbal; + + } else if (get_vec_gimbal(axis) == GIMBAL_Y) { + // rotate around y-axis + // pre-processing automata + // Let the X-axis in the R(3) space be the X-axis in the 2D projection. + // Let the Z-axis in the R(3) space be the Y-axis in the 2D projection. + + // work in XZ plane + __rotator->element[0][0] = vector2d_cos(angle); + __rotator->element[0][2] = -vector2d_sin(angle); + __rotator->element[2][0] = vector2d_sin(angle); + __rotator->element[2][2] = vector2d_cos(angle); + __rotator->element[1][1] = 1; + + gimbal->y_gimbal += angle; + *angle1 = gimbal->y_gimbal; + } else if (get_vec_gimbal(axis) == GIMBAL_X) { + + // rotate around x-axis + // pre-processing automata + // Let the Z-axis in the R(3) space be the X-axis in the 2D projection. + // Let the Y-axis in the R(3) space be the Y-axis in the 2D projection. + + // work in ZY plane + __rotator->element[2][2] = vector2d_cos(angle); + __rotator->element[2][1] = -vector2d_sin(angle); + __rotator->element[1][2] = vector2d_sin(angle); + __rotator->element[1][1] = vector2d_cos(angle); + __rotator->element[0][0] = 1; + + gimbal->x_gimbal += angle; + *angle1 = gimbal->x_gimbal; + } else { + return EINCOMPATTYPE; + } + + return PASS; +} + +static inline status_code rotate_about_gimbal(matrix *__rotator, + matrix *__col_vec, + matrix *_col_vec, + vector3d *out, + vec3d_processors *procs) { + mat_processors mat_procs = { + }; + + status_code __code = mat_product(*__rotator, + *__col_vec, + _col_vec, mat_procs); + if (PASS != __code) { + if (NULL != procs && NULL != procs->on_op_failed) { + procs->on_op_failed(&vec3d_rotate, __code); + } + return __code; + } + + out->x = _col_vec->element[0][0]; + out->y = _col_vec->element[1][0]; + out->z = _col_vec->element[2][0]; + + return PASS; +} + +static inline status_code rotate_gimbal(vector3d *axis, vec_component angle1, + matrix *__rotator, + vec3d_gimbal *in_gimbal, + vec3d_gimbal *out_gimbal, + vec3d_processors *procs) { + if (get_vec_gimbal(axis) == GIMBAL_Z) { + __rotator->element[0][0] = vector2d_cos(angle1); + __rotator->element[0][1] = -vector2d_sin(angle1); + __rotator->element[1][0] = vector2d_sin(angle1); + __rotator->element[1][1] = vector2d_cos(angle1); + __rotator->element[2][2] = 1; + } else if (get_vec_gimbal(axis) == GIMBAL_Y) { + __rotator->element[0][0] = vector2d_cos(angle1); + __rotator->element[0][2] = -vector2d_sin(angle1); + __rotator->element[2][0] = vector2d_sin(angle1); + __rotator->element[2][2] = vector2d_cos(angle1); + __rotator->element[1][1] = 1; + } else if (get_vec_gimbal(axis) == GIMBAL_X) { + __rotator->element[2][2] = vector2d_cos(angle1); + __rotator->element[2][1] = -vector2d_sin(angle1); + __rotator->element[1][2] = vector2d_sin(angle1); + __rotator->element[1][1] = vector2d_cos(angle1); + __rotator->element[0][0] = 1; + } else { + return EINCOMPATTYPE; + } + + // init the output orientation matrix + vec_component _orient_x[3] = {0, 0, 0,}; + vec_component _orient_y[3] = {0, 0, 0,}; + vec_component _orient_z[3] = {0, 0, 0,}; + vec_component *_orient_comps[3] = {_orient_x, _orient_y, _orient_z}; + matrix __orient = { + .element = _orient_comps, + .m = 3, + .n = 3 + }; + + mat_processors mat_procs = { + }; + + status_code __code = + mat_product(*__rotator, + *(in_gimbal->orientation), + &__orient, mat_procs); + if (PASS != __code) { + if (NULL != procs && NULL != procs->on_op_failed) { + procs->on_op_failed(&vec3d_rotate, __code); + } + return __code; + } + + struct rotation_metadata metadata = { + .in_orientation = &__orient, + .out_orientation = out_gimbal->orientation + }; + + mat_procs.on_entry_iterated = &__on_entry_iterated; + mat_procs.metadata = &metadata; + + __code = mat_iterate_elements(__orient, ROW_CONVENTION_ITERATOR, mat_procs); + if (PASS != __code) { + if (NULL != procs && NULL != procs->on_op_failed) { + procs->on_op_failed(&vec3d_rotate, __code); + } + return __code; + } + + if (get_vec_gimbal(axis) == GIMBAL_Z) { + out_gimbal->z_gimbal = 0; + } else if (get_vec_gimbal(axis) == GIMBAL_Y) { + out_gimbal->y_gimbal = 0; + } else { + out_gimbal->x_gimbal = 0; + } + + return PASS; +} + +status_code vec3d_rotate(vector3d v, vector3d axis, vec_component angle, + vector3d *out, vec3d_processors *procs) { + + if (NULL == v.gimbal.orientation || + NULL == v.gimbal.orientation->element) { + return EUNDEFINEDBUFFER; + } + + if (NULL == out || + NULL == out->gimbal.orientation) { + return EUNDEFINEDBUFFER; + } + + if (v.gimbal.orientation->m != v.gimbal.orientation->n || + out->gimbal.orientation->m != out->gimbal.orientation->n || + v.gimbal.orientation->m != out->gimbal.orientation->m || + v.gimbal.orientation->m != 3) { + return EBUFFERTURNCATION; + } + + // preprocessing automata -- initialize the input column vector + vec_component __vec_x[1] = {v.x,}; + vec_component __vec_y[1] = {v.y,}; + vec_component __vec_z[1] = {v.z,}; + vec_component *__vec_comps[3] = {__vec_x, __vec_y, __vec_z}; + matrix __col_vec = { + .element = __vec_comps, + .m = 3, + .n = 1 + }; + + // init the output buffer + vec_component _vec_x[1] = {0,}; + vec_component _vec_y[1] = {0,}; + vec_component _vec_z[1] = {0,}; + vec_component *_vec_comps[3] = {_vec_x, _vec_y, _vec_z}; + matrix _col_vec = { + .element = _vec_comps, + .m = 3, + .n = 1 + }; + + // init the rotation matrix + vec_component __rotate_x[3] = {0, 0, 0,}; + vec_component __rotate_y[3] = {0, 0, 0,}; + vec_component __rotate_z[3] = {0, 0, 0,}; + vec_component *__rotate_comps[3] = {__rotate_x, __rotate_y, __rotate_z}; + matrix __rotator = { + .element = __rotate_comps, + .m = 3, + .n = 3, + }; + + status_code __code; + vec_component angle1 = 0; + + preprocess_orientator(&v, &axis); + vec3d_abs(axis, &axis, NULL); + + __code = init_rotator_gimbal(&axis, &__rotator, angle, + &angle1, &out->gimbal); + + if (PASS != __code) { + if (NULL != procs && NULL != procs->on_op_failed) { + procs->on_op_failed(&vec3d_rotate, __code); + } + return __code; + } + + __code = rotate_about_gimbal(&__rotator, + &__col_vec, + &_col_vec, out, procs); + if (PASS != __code) { + if (NULL != procs && NULL != procs->on_op_failed) { + procs->on_op_failed(&vec3d_rotate, __code); + } + return __code; + } + + if (vector2d_abs(vector2d_cos(angle1)) <= ___ROTATION_MIN_THRESHOLD + && vector2d_abs(vector2d_sin(angle1)) == 1) { + // rotate the gimbals axes (the orientation) + __code = rotate_gimbal(&axis, angle1, &__rotator, + &(v.gimbal), + &out->gimbal, procs); + if (PASS != __code) { + if (NULL != procs && NULL != procs->on_op_failed) { + procs->on_op_failed(&vec3d_rotate, __code); + } + return __code; + } + } + + if (NULL != procs && NULL != procs->on_op_success) { + procs->on_op_success(&vec3d_rotate, *out); + } + + return __code; +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_rotate_temp.temp b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_rotate_temp.temp new file mode 100644 index 00000000..2d5208ad --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_rotate_temp.temp @@ -0,0 +1,284 @@ +#include +#include +#include + +struct rotation_metadata { + matrix *in_orientation; + matrix *out_orientation; +}; + +typedef enum { + GIMBAL_X = 200, + GIMBAL_Y = GIMBAL_X - 1, + GIMBAL_Z = GIMBAL_Y - 1 +} vector_gimbal; + +static inline void preprocess_orientator(vector3d *v, vector3d *axis) { + + // create a column vector matrix + vec_component axis_x[1] = {0,}; + vec_component axis_y[1] = {0,}; + vec_component axis_z[1] = {0,}; + vec_component *axis_comps[3] = {axis_x, axis_y, axis_z}; + matrix __axis = { + .element = axis_comps, + .m = 3, + .n = 1 + }; + + mat_processors procs = { + }; + mat_create_from_vector3d(*axis, &__axis, procs); + + // find the position of the orientation vectors + vec_component _axis_x[1] = {0,}; + vec_component _axis_y[1] = {0,}; + vec_component _axis_z[1] = {0,}; + vec_component *_axis_comps[3] = {_axis_x, _axis_y, _axis_z}; + matrix ___axis = { + .element = _axis_comps, + .m = 3, + .n = 1 + }; + mat_product(*(v->gimbal.orientation), __axis, &___axis, procs); + + axis->x = *(___axis.element[0]); + axis->y = *(___axis.element[1]); + axis->z = *(___axis.element[2]); +} + +static inline status_code __on_entry_iterated(mat_proc_sig proc_sig) { + struct rotation_metadata *metadata = proc_sig.metadata; + matrix *in_orientation = metadata->in_orientation; + matrix *out_orientation = metadata->out_orientation; + uint64_t row_index = proc_sig.row_index; + uint64_t col_index = proc_sig.col_index; + + out_orientation->element[row_index][col_index] = + in_orientation->element[row_index][col_index]; + + return PASS; +} + +static inline vector_gimbal get_vec_gimbal(vector3d axis) { + if ((axis.x > ___ROTATION_MIN_THRESHOLD) && + ((axis.y >= 0) && (axis.y < 1)) && + ((axis.z >= 0) && (axis.z < 1))) { + + return GIMBAL_X; + } else if ((axis.y > ___ROTATION_MIN_THRESHOLD) && + ((axis.x >= 0) && (axis.x < 1)) && + ((axis.z >= 0) && (axis.z < 1))) { + + return GIMBAL_Y; + } else if ((axis.z > ___ROTATION_MIN_THRESHOLD) && + ((axis.y >= 0) && (axis.y < 1)) && + ((axis.x >= 0) && (axis.x < 1))) { + + return GIMBAL_Z; + } + return -1; +} + +status_code vec3d_rotate(vector3d v, vector3d axis, vec_component angle, + vector3d *out, vec3d_processors *procs) { + + if (NULL == v.gimbal.orientation || + NULL == v.gimbal.orientation->element) { + return EUNDEFINEDBUFFER; + } + + if (NULL == out || + NULL == out->gimbal.orientation) { + return EUNDEFINEDBUFFER; + } + + if (v.gimbal.orientation->m != v.gimbal.orientation->n || + out->gimbal.orientation->m != out->gimbal.orientation->n || + v.gimbal.orientation->m != out->gimbal.orientation->m || + v.gimbal.orientation->m != 3) { + return EBUFFERTURNCATION; + } + + // preprocessing automata -- initialize the input column vector + vec_component __vec_x[1] = {v.x,}; + vec_component __vec_y[1] = {v.y,}; + vec_component __vec_z[1] = {v.z,}; + vec_component *__vec_comps[3] = {__vec_x, __vec_y, __vec_z}; + matrix __col_vec = { + .element = __vec_comps, + .m = 3, + .n = 1 + }; + + // init the output buffer + vec_component _vec_x[1] = {0,}; + vec_component _vec_y[1] = {0,}; + vec_component _vec_z[1] = {0,}; + vec_component *_vec_comps[3] = {_vec_x, _vec_y, _vec_z}; + matrix _col_vec = { + .element = _vec_comps, + .m = 3, + .n = 1 + }; + + // init the output orientation matrix + vec_component _orient_x[3] = {0, 0, 0,}; + vec_component _orient_y[3] = {0, 0, 0,}; + vec_component _orient_z[3] = {0, 0, 0,}; + vec_component *_orient_comps[3] = {_orient_x, _orient_y, _orient_z}; + matrix __orient = { + .element = _orient_comps, + .m = 3, + .n = 3 + }; + + // init the rotation matrix + vec_component __rotate_x[3] = {0, 0, 0,}; + vec_component __rotate_y[3] = {0, 0, 0,}; + vec_component __rotate_z[3] = {0, 0, 0,}; + vec_component *__rotate_comps[3] = {__rotate_x, __rotate_y, __rotate_z}; + matrix __rotator = { + .element = __rotate_comps, + .m = 3, + .n = 3, + }; + + status_code __code; + vec_component angle1 = 0; + + preprocess_orientator(&v, &axis); + vec3d_abs(axis, &axis, NULL); + + if (get_vec_gimbal(axis) == GIMBAL_Z) { + fprintf(stdout, "Order rotation around Z\n"); + // rotate around z-axis + // pre-processing automata + // Let the X-axis in the R(3) space be the X-axis in the 2D projection. + // Let the Y-axis in the R(3) space be the Y-axis in the 2D projection. + + // work in XY plane + __rotator.element[0][0] = vector2d_cos(angle); + __rotator.element[0][1] = -vector2d_sin(angle); + __rotator.element[1][0] = vector2d_sin(angle); + __rotator.element[1][1] = vector2d_cos(angle); + __rotator.element[2][2] = 1; + + out->gimbal.z_gimbal += angle; + angle1 = out->gimbal.z_gimbal; + + } else if (get_vec_gimbal(axis) == GIMBAL_Y) { + fprintf(stdout, "Order rotation around Y\n"); + // rotate around y-axis + // pre-processing automata + // Let the X-axis in the R(3) space be the X-axis in the 2D projection. + // Let the Z-axis in the R(3) space be the Y-axis in the 2D projection. + + // work in XZ plane + __rotator.element[0][0] = vector2d_cos(angle); + __rotator.element[0][2] = -vector2d_sin(angle); + __rotator.element[2][0] = vector2d_sin(angle); + __rotator.element[2][2] = vector2d_cos(angle); + __rotator.element[1][1] = 1; + + out->gimbal.y_gimbal += angle; + angle1 = out->gimbal.y_gimbal; + } else if (get_vec_gimbal(axis) == GIMBAL_X) { + fprintf(stdout, "Order rotation around X\n"); + + // rotate around x-axis + // pre-processing automata + // Let the Z-axis in the R(3) space be the X-axis in the 2D projection. + // Let the Y-axis in the R(3) space be the Y-axis in the 2D projection. + + // work in ZY plane + __rotator.element[2][2] = vector2d_cos(angle); + __rotator.element[2][1] = -vector2d_sin(angle); + __rotator.element[1][2] = vector2d_sin(angle); + __rotator.element[1][1] = vector2d_cos(angle); + __rotator.element[0][0] = 1; + + out->gimbal.x_gimbal += angle; + angle1 = out->gimbal.x_gimbal; + } else { + return EINCOMPATTYPE; + } + + mat_processors mat_procs = { + }; + + __code = mat_product(__rotator, __col_vec, &_col_vec, mat_procs); + if (PASS != __code) { + if (NULL != procs && NULL != procs->on_op_failed) { + procs->on_op_failed(&vec3d_rotate, __code); + } + return __code; + } + + out->x = _col_vec.element[0][0]; + out->y = _col_vec.element[1][0]; + out->z = _col_vec.element[2][0]; + + if (vector2d_abs(vector2d_cos(angle1)) <= ___ROTATION_MIN_THRESHOLD + && vector2d_abs(vector2d_sin(angle1)) == 1) { + // rotate the gimbals axes (the orientation) + + if (get_vec_gimbal(axis) == GIMBAL_Z) { + __rotator.element[0][0] = vector2d_cos(angle1); + __rotator.element[0][1] = -vector2d_sin(angle1); + __rotator.element[1][0] = vector2d_sin(angle1); + __rotator.element[1][1] = vector2d_cos(angle1); + __rotator.element[2][2] = 1; + } else if (get_vec_gimbal(axis) == GIMBAL_Y) { + __rotator.element[0][0] = vector2d_cos(angle1); + __rotator.element[0][2] = -vector2d_sin(angle1); + __rotator.element[2][0] = vector2d_sin(angle1); + __rotator.element[2][2] = vector2d_cos(angle1); + __rotator.element[1][1] = 1; + } else { + __rotator.element[2][2] = vector2d_cos(angle1); + __rotator.element[2][1] = -vector2d_sin(angle1); + __rotator.element[1][2] = vector2d_sin(angle1); + __rotator.element[1][1] = vector2d_cos(angle1); + __rotator.element[0][0] = 1; + } + + __code = mat_product(__rotator, *(v.gimbal.orientation), &__orient, mat_procs); + if (PASS != __code) { + if (NULL != procs && NULL != procs->on_op_failed) { + procs->on_op_failed(&vec3d_rotate, __code); + } + return __code; + } + + struct rotation_metadata metadata = { + .in_orientation = &__orient, + .out_orientation = out->gimbal.orientation + }; + + mat_procs.on_entry_iterated = &__on_entry_iterated; + mat_procs.metadata = &metadata; + + __code = mat_iterate_elements(__orient, ROW_CONVENTION_ITERATOR, mat_procs); + if (PASS != __code) { + if (NULL != procs && NULL != procs->on_op_failed) { + procs->on_op_failed(&vec3d_rotate, __code); + } + return __code; + } + + if (get_vec_gimbal(axis) == GIMBAL_Z) { + out->gimbal.z_gimbal = 0; + } else if (get_vec_gimbal(axis) == GIMBAL_Y) { + out->gimbal.y_gimbal = 0; + } else { + out->gimbal.x_gimbal = 0; + } + } + + if (NULL != procs && NULL != procs->on_op_success) { + procs->on_op_success(&vec3d_rotate, *out); + } + + return __code; +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_scalar_add.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_scalar_add.c new file mode 100644 index 00000000..abfe93a1 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_scalar_add.c @@ -0,0 +1,37 @@ +#include +#include + +status_code vec3d_scalar_add(vector3d v, vec_component scalar, vector3d *out, + vec3d_processors *processors) { + if (rvalue(out) == NULL) { + return EUNDEFINEDBUFFER; + } + + vector2d v_xy = { + .x = v.x, + .y = v.y, + }; + vector2d v_z = { + .y = v.z, + }; + + status_code __code; + vector2d xy_out; + vector2d z_out; + + __code = vec2d_scalar_add(v_xy, scalar, &xy_out, NULL); + if (PASS != __code) { + return __code; + } + + __code = vec2d_scalar_add(v_z, scalar, &z_out, NULL); + if (PASS != __code) { + return __code; + } + + out->x = xy_out.x; + out->y = xy_out.y; + out->z = z_out.y; + + return PASS; +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_scalar_divide.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_scalar_divide.c new file mode 100644 index 00000000..a1727837 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_scalar_divide.c @@ -0,0 +1,38 @@ +#include +#include + +status_code vec3d_scalar_divide(vector3d v, vec_component scalar, + vector3d *out, vec3d_processors *processors) { + if (rvalue(out) == NULL) { + return EUNDEFINEDBUFFER; + } + + vector2d v_xy = { + .x = v.x, + .y = v.y, + }; + vector2d v_z = { + + .y = v.z, + }; + + status_code __code; + vector2d xy_out; + vector2d z_out; + + __code = vec2d_scalar_divide(v_xy, scalar, &xy_out, NULL); + if (PASS != __code) { + return __code; + } + + __code = vec2d_scalar_divide(v_z, scalar, &z_out, NULL); + if (PASS != __code) { + return __code; + } + + out->x = xy_out.x; + out->y = xy_out.y; + out->z = z_out.y; + + return PASS; +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_scalar_multiply.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_scalar_multiply.c new file mode 100644 index 00000000..237d8a9d --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_scalar_multiply.c @@ -0,0 +1,37 @@ +#include +#include + +status_code vec3d_scalar_multiply(vector3d v, vec_component scalar, + vector3d *out, vec3d_processors *processors) { + if (rvalue(out) == NULL) { + return EUNDEFINEDBUFFER; + } + + vector2d v_xy = { + .x = v.x, + .y = v.y, + }; + vector2d v_z = { + .y = v.z, + }; + + status_code __code; + vector2d xy_out; + vector2d z_out; + + __code = vec2d_scalar_multiply(v_xy, scalar, &xy_out, NULL); + if (PASS != __code) { + return __code; + } + + __code = vec2d_scalar_multiply(v_z, scalar, &z_out, NULL); + if (PASS != __code) { + return __code; + } + + out->x = xy_out.x; + out->y = xy_out.y; + out->z = z_out.y; + + return PASS; +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_scalar_subtract.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_scalar_subtract.c new file mode 100644 index 00000000..5ad22eb0 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_scalar_subtract.c @@ -0,0 +1,7 @@ +#include +#include + +status_code vec3d_scalar_subtract(vector3d v, vec_component scalar, + vector3d *out, vec3d_processors *processors) { + return vec3d_scalar_add(v, -scalar, out, processors); +} diff --git a/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_subtract.c b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_subtract.c new file mode 100644 index 00000000..dd8da314 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-core/src/libs/electrostatic-primer/electronetsoft/algorithm/arithmos/vector3d/vec3d_subtract.c @@ -0,0 +1,25 @@ +#include +#include + +status_code vec3d_subtract(vector3d v0, vector3d v1, + vector3d *out, vec3d_processors *processors) { + if (rvalue(out) == NULL) { + return EUNDEFINEDBUFFER; + } + // find the negation of v1 + status_code __code; + vector3d neg_v1; + vector3d neg_unit = { + .x = (vec_component) -1, + .y = (vec_component) -1, + .z = (vec_component) -1 + }; + + __code = vec3d_product(v1, neg_unit, &neg_v1, processors); + if (PASS != __code) { + return __code; + } + // calculate the addition primitive op. + + return vec3d_add(v0, neg_v1, out, processors); +} diff --git a/electrostatic-sandbox-framework/electrostatic-examples/src/hello_vector2d.c b/electrostatic-sandbox-framework/electrostatic-examples/src/hello_vector2d.c index f7a649bd..3545e267 100644 --- a/electrostatic-sandbox-framework/electrostatic-examples/src/hello_vector2d.c +++ b/electrostatic-sandbox-framework/electrostatic-examples/src/hello_vector2d.c @@ -8,21 +8,82 @@ vector2d vec0 = { 4, - 6}; + 6 +}; vector2d vec1 = { 2, - 3}; + 3 +}; + +void on_op_completed(void *caller, vector2d result) { + // hardware OK! + // simulator OK! + // + +} + +void on_op_failed(void *caller, status_code err) { + +} int main() { - printf("Summation = [%f, %f] \n", vector2d_add(vec0, vec1).x, vector2d_add(vec0, vec1).y); - printf("Subtraction = [%f, %f] \n", vector2d_subtract(vec0, vec1).x, vector2d_subtract(vec0, vec1).y); - printf("Product = [%f, %f] \n", vector2d_product(vec0, vec1).x, vector2d_product(vec0, vec1).y); - printf("Cross Product = [%f] \n", vector2d_cross_product(vec0, vec1)); - printf("Distance = [%f] \n", vector2d_distance(vec0, vec1)); - printf("Are perpendicular = %u \n", vector2d_are_perpendicular(vec0, vec1)); - printf("Extrapolate to 1/2 after the last vector = [%f, %f] \n", vector2d_extrapolate(vec0, vec1, 0.5).x, vector2d_extrapolate(vec0, vec1, 0.5).y); - printf("Interpolate into 1/2 = [%f, %f] \n", vector2d_interpolate(vec1, vec0, 0.5).x, vector2d_interpolate(vec1, vec0, 0.5).y); + vector2d out = {}; + vec_component scalar; + status_code __code; + + vec2d_processors proc = { + .on_op_success = &on_op_completed, + .on_op_failed = &on_op_failed, + }; + + __code = vec2d_add(vec0, vec1, &out, &proc); + if (PASS != __code) { + } + printf("Summation = [%f, %f] \n", out.x, out.y); + + __code = vec2d_subtract(vec0, vec1, &out, NULL); + if (PASS != __code) { + } + printf("Subtraction = [%f, %f] \n", out.x, out.y); + + __code = vec2d_product(vec0, vec1, &out, NULL); + if (PASS != __code) { + } + printf("Product = [%f, %f] \n", out.x, out.y); + + + __code = vec2d_divide(vec0, vec1, &out, NULL); + if (PASS != __code) { + } + printf("Division = [%f, %f] \n", out.x, out.y); + + + __code = vec2d_distance(vec0, vec1, &scalar, NULL); + if (PASS != __code) { + } + printf("Distance = [%f] \n", scalar); + + __code = vec2d_cross_product(vec0, vec1, &scalar, NULL); + if (PASS != __code) { + } + printf("Cross Product = [%f] \n", scalar); + + __code = vec2d_interpolate(vec0, vec1, 0.5f, &out, NULL); + if (PASS != __code) { + } + printf("Interpolate into 1/2 = [%f, %f] \n", out.x, out.y); + + + __code = vec2d_component(vec0, VEC2_X_COMPONENT, &out, NULL); + if (PASS != __code) { + } + printf("Vector X Component = [%f, %f] \n", out.x, out.y); + +// printf("Cross Product = [%f] \n", vector2d_cross_product(vec0, vec1)); +// printf("Distance = [%f] \n", vector2d_distance(vec0, vec1)); +// printf("Are perpendicular = %u \n", vector2d_are_perpendicular(vec0, vec1)); +// printf("Extrapolate to 1/2 after the last vector = [%f, %f] \n", vector2d_extrapolate(vec0, vec1, 0.5).x, vector2d_extrapolate(vec0, vec1, 0.5).y); return 0; } diff --git a/electrostatic-sandbox-framework/electrostatic-examples/src/test_mat_product.c b/electrostatic-sandbox-framework/electrostatic-examples/src/test_mat_product.c new file mode 100644 index 00000000..ebd951a6 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-examples/src/test_mat_product.c @@ -0,0 +1,95 @@ +#include +#include +#include +#include +#include + +void on_op_success(mat_proc_sig proc_sig) { + matrix mat = proc_sig.mat; + + fprintf(stdout, "Elementary Success\n"); + fprintf(stdout, "Elementary Op Output = %f\n", + mat.element[proc_sig.row_index][proc_sig.col_index]); +} +status_code on_binary_op_preprocessor(mat_binary_op_sig binary_sig) { + matrix m0 = binary_sig.m0; + matrix m1 = binary_sig.m1; + uint64_t row = binary_sig.row_index; + uint64_t col = binary_sig.col_index; + +// m0.element[row][col] = m0.element[row][col] * 2; + return PASS; +} + +status_code on_elementary_op_postprocessor(mat_proc_sig proc_sig) { + matrix mat = proc_sig.mat; + uint64_t row = proc_sig.row_index; + uint64_t column = proc_sig.col_index; + + fprintf(stdout, "Elementary Op Output = %f\n", + mat.element[row][column]); + return PASS; +} + +int main() { + matrix mat0 = { + .element = malloc(((3 * 2) * sizeof (vec_component *))), + .m = 3, + .n = 2 + }; + + matrix mat1 = { + .element = malloc(((2 * 1) * sizeof (vec_component *))), + .m = 2, + .n = 1 + }; + + matrix out = { + .element = malloc(((3 * 1) * sizeof (vec_component *))), + .m = 3, + .n = 1 + }; + + mat_processors processors = { + .on_op_success = &on_op_success, + .on_elementary_op_postprocessor = &on_elementary_op_postprocessor, + .on_binary_op_preprocessor = &on_binary_op_preprocessor + }; + + memset(mat0.element, '\0', ((3 * 2) * sizeof (vec_component *))); + memset(mat1.element, '\0', ((2 * 1) * sizeof (vec_component *))); + memset(out.element, '\0', ((3 * 1) * sizeof (vec_component *))); + + vec_component c0[2] = {1, 2}; + vec_component c1[2] = {3, 4}; + vec_component c2[2] = {200, 6}; + + vec_component c02[1] = {3,}; + vec_component c12[1] = {5,}; + + vec_component c_out0[1] = {0,}; + vec_component c_out1[1] = {0,}; + vec_component c_out2[1] = {0,}; + + mat0.element[0] = &c0[0]; + mat0.element[1] = &c1[0]; + mat0.element[2] = &c2[0]; + + mat1.element[0] = &c02[0]; + mat1.element[1] = &c12[0]; + + out.element[0] = &c_out0[0]; + out.element[1] = &c_out1[0]; + out.element[2] = &c_out2[0]; + + status_code __code = mat_product(mat0, mat1, &out, processors); + if (PASS != __code) { + fprintf(stderr, "Error: %d\n", __code); + } + + free(mat0.element); + free(mat1.element); + free(out.element); + + return 0; +} \ No newline at end of file diff --git a/electrostatic-sandbox-framework/electrostatic-examples/src/test_matrix_addition.c b/electrostatic-sandbox-framework/electrostatic-examples/src/test_matrix_addition.c new file mode 100644 index 00000000..180bf95c --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-examples/src/test_matrix_addition.c @@ -0,0 +1,81 @@ +#include +#include +#include +#include +#include + +void on_op_success(mat_proc_sig proc_sig) { + matrix mat = proc_sig.mat; + + fprintf(stdout, "Elementary Success = %f %lu\n", + mat.element[0][0], sizeof (mat.element[0][0])); +} + +status_code on_binary_op_preprocessor(mat_binary_op_sig binary_sig) { + matrix m0 = binary_sig.m0; + matrix m1 = binary_sig.m1; + uint64_t row = binary_sig.row_index; + uint64_t col = binary_sig.col_index; + + m1.element[row][col] = m1.element[row][col] * 2; + return PASS; +} + +status_code on_elementary_op_postprocessor(mat_proc_sig proc_sig) { + matrix mat = proc_sig.mat; + uint64_t row = proc_sig.row_index; + uint64_t column = proc_sig.col_index; + + fprintf(stdout, "Elementary Op Output = %f\n", + mat.element[row][column]); + return PASS; +} + +int main() { + matrix mat0 = { + .element = malloc(((3 * 2) * sizeof (vec_component *))), + .m = 3, + .n = 2 + }; + + matrix mat1 = { + .element = malloc(((3 * 2) * sizeof (vec_component *))), + .m = 3, + .n = 2 + }; + + mat_processors processors = { + .on_op_success = &on_op_success, + .on_elementary_op_postprocessor = &on_elementary_op_postprocessor, + .on_binary_op_preprocessor = &on_binary_op_preprocessor + }; + + memset(mat0.element, '\0', ((3 * 2) * sizeof (vec_component *))); + memset(mat1.element, '\0', ((3 * 2) * sizeof (vec_component *))); + + vec_component c0[2] = {1, 2}; + vec_component c1[2] = {3, 4}; + vec_component c2[2] = {200, 6}; + + vec_component c02[2] = {3, 4}; + vec_component c12[2] = {5, 6}; + vec_component c22[2] = {7, 8}; + + mat0.element[0] = &c0[0]; + mat0.element[1] = &c1[0]; + mat0.element[2] = &c2[0]; + + mat1.element[0] = &c02[0]; + mat1.element[1] = &c12[0]; + mat1.element[2] = &c22[0]; + + status_code __code = mat_add(mat0, mat1, &mat0, processors); + if (PASS != __code) { + fprintf(stderr, "Error: %d\n", __code); + } + + free(mat0.element); + free(mat1.element); + + return 0; +} \ No newline at end of file diff --git a/electrostatic-sandbox-framework/electrostatic-examples/src/test_matrix_iteration.c b/electrostatic-sandbox-framework/electrostatic-examples/src/test_matrix_iteration.c new file mode 100644 index 00000000..ca8b7821 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-examples/src/test_matrix_iteration.c @@ -0,0 +1,70 @@ +#include +#include +#include +#include +#include + +status_code on_column_iterated(mat_proc_sig proc_sig) { + matrix mat = proc_sig.mat; + uint64_t column = proc_sig.col_index; + + if (is_last_column(mat, column)) { + fprintf(stdout, "Column: %f\n", mat.element[0][column]); + return PASS; + } + fprintf(stdout, "Column: %f\n", mat.element[column][0]); + return PASS; +} + +status_code on_row_iterated(mat_proc_sig proc_sig) { + matrix mat = proc_sig.mat; + uint64_t row = proc_sig.row_index; + + fprintf(stdout, "Row: %f\n", mat.element[row][0]); + return PASS; +} + +status_code on_entry_iterated(mat_proc_sig proc_sig) { + matrix mat = proc_sig.mat; + uint64_t row = proc_sig.row_index; + uint64_t column = proc_sig.col_index; + + fprintf(stdout, "Element = %f\n", + mat.element[row][column]); + return PASS; +} + +int main() { + + matrix mat = { + .element = malloc(((3 * 2) * sizeof (vec_component *))), + .m = 3, + .n = 2 + }; + + mat_processors processors = { + .on_entry_iterated = &on_entry_iterated, + .on_row_iterated = &on_row_iterated, + .on_column_iterated = &on_column_iterated + }; + + memset(mat.element, '\0', ((3 * 2) * sizeof (vec_component *))); + + vec_component c0[2] = {1, 2}; + vec_component c1[2] = {3, 4}; + vec_component c2[2] = {5, 6}; + + mat.element[0] = &c0[0]; + mat.element[1] = &c1[0]; + mat.element[2] = &c2[0]; + + status_code __code = + mat_iterate_elements(mat, ROW_CONVENTION_ITERATOR, processors); + if (PASS != __code) { + fprintf(stderr, "Error: %d\n", __code); + } + + free(mat.element); + + return 0; +}; diff --git a/electrostatic-sandbox-framework/electrostatic-examples/src/test_matrix_subtraction.c b/electrostatic-sandbox-framework/electrostatic-examples/src/test_matrix_subtraction.c new file mode 100644 index 00000000..a39ebbe3 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-examples/src/test_matrix_subtraction.c @@ -0,0 +1,81 @@ +#include +#include +#include +#include +#include + +void on_op_success(mat_proc_sig proc_sig) { + matrix mat = proc_sig.mat; + + fprintf(stdout, "Elementary Success = %f\n", + mat.element[0][0]); +} + +status_code on_binary_op_preprocessor(mat_binary_op_sig binary_sig) { + matrix m0 = binary_sig.m0; + matrix m1 = binary_sig.m1; + uint64_t row = binary_sig.row_index; + uint64_t col = binary_sig.col_index; + + m1.element[row][col] = m1.element[row][col] * 2; + return PASS; +} + +status_code on_elementary_op_postprocessor(mat_proc_sig proc_sig) { + matrix mat = proc_sig.mat; + uint64_t row = proc_sig.row_index; + uint64_t column = proc_sig.col_index; + + fprintf(stdout, "Elementary Op Output = %f\n", + mat.element[row][column]); + return PASS; +} + +int main() { + matrix mat0 = { + .element = malloc(((3 * 2) * sizeof (vec_component *))), + .m = 3, + .n = 2 + }; + + matrix mat1 = { + .element = malloc(((3 * 2) * sizeof (vec_component *))), + .m = 3, + .n = 2 + }; + + mat_processors processors = { + .on_op_success = &on_op_success, + .on_elementary_op_postprocessor = &on_elementary_op_postprocessor, + .on_binary_op_preprocessor = &on_binary_op_preprocessor + }; + + memset(mat0.element, '\0', ((3 * 2) * sizeof (vec_component *))); + memset(mat1.element, '\0', ((3 * 2) * sizeof (vec_component *))); + + vec_component c0[2] = {1, 2}; + vec_component c1[2] = {3, 4}; + vec_component c2[2] = {200, 6}; + + vec_component c02[2] = {3, 4}; + vec_component c12[2] = {5, 6}; + vec_component c22[2] = {7, 8}; + + mat0.element[0] = &c0[0]; + mat0.element[1] = &c1[0]; + mat0.element[2] = &c2[0]; + + mat1.element[0] = &c02[0]; + mat1.element[1] = &c12[0]; + mat1.element[2] = &c22[0]; + + status_code __code = mat_subtract(mat0, mat1, &mat0, processors); + if (PASS != __code) { + fprintf(stderr, "Error: %d\n", __code); + } + + free(mat0.element); + free(mat1.element); + + return 0; +} \ No newline at end of file diff --git a/electrostatic-sandbox-framework/electrostatic-examples/src/test_vec2d_rotation.c b/electrostatic-sandbox-framework/electrostatic-examples/src/test_vec2d_rotation.c new file mode 100644 index 00000000..b4ebefa5 --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-examples/src/test_vec2d_rotation.c @@ -0,0 +1,43 @@ +#include +#include + +int main() { + + vec_component x_comp[2] = {1, 0}; + vec_component y_comp[2] = {0, 1}; + + vec_component *comps[2] = {x_comp, y_comp}; + + matrix orientator = { + .element = comps, + .m = 2, + .n = 2 + }; + + vector2d v = { + .x = 2, + .y = 3, + .orientation = &orientator + }; + + vector2d rotated = { + .orientation = &orientator + }; + + struct vec2d_processors processors = { + }; + + fprintf(stdout, "Vx Orientation = (%f, %f)\n", rotated.orientation->element[0][0], rotated.orientation->element[1][0]); + fprintf(stdout, "Vy Orientation = (%f, %f)\n", rotated.orientation->element[0][1], rotated.orientation->element[1][1]); + + status_code __code = vec2d_rotate(v, VEC2_X_COMPONENT, M_PI/2, &rotated, &processors); + if (__code != PASS) { + fprintf(stderr, "Error: %d\n", __code); + } + + fprintf(stdout, "Vx Orientation = (%f, %f)\n", rotated.orientation->element[0][0], rotated.orientation->element[1][0]); + fprintf(stdout, "Vy Orientation = (%f, %f)\n", rotated.orientation->element[0][1], rotated.orientation->element[1][1]); + + return 0; +} + diff --git a/electrostatic-sandbox-framework/electrostatic-examples/src/test_vec3d_rotation.c b/electrostatic-sandbox-framework/electrostatic-examples/src/test_vec3d_rotation.c new file mode 100644 index 00000000..1ba30d6c --- /dev/null +++ b/electrostatic-sandbox-framework/electrostatic-examples/src/test_vec3d_rotation.c @@ -0,0 +1,119 @@ +#include +#include + +int main() { + + vec_component x_comp[3] = {1, 0, 0}; + vec_component y_comp[3] = {0, 1, 0}; + vec_component z_comp[3] = {0, 0, 1}; + + vec_component *comps[3] = {x_comp, y_comp, z_comp}; + + matrix orientator = { + .element = comps, + .m = 3, + .n = 3 + }; + + vector3d v = { + .x = 2, + .y = 3, + .z = 4, + .gimbal = (vec3d_gimbal) { + .x_gimbal = 0, + .y_gimbal = 0, + .z_gimbal = 0, + .orientation = &orientator + } + }; + + struct vec3d_processors processors = { + }; + + fprintf(stdout, "%f\n", ___ROTATION_MIN_THRESHOLD); + + fprintf(stdout, "Vx Orientation = (%f, %f, %f)\n", v.gimbal.orientation->element[0][0], v.gimbal.orientation->element[1][0], v.gimbal.orientation->element[2][0]); + fprintf(stdout, "Vy Orientation = (%f, %f, %f)\n", v.gimbal.orientation->element[0][1], v.gimbal.orientation->element[1][1], v.gimbal.orientation->element[2][1]); + fprintf(stdout, "Vz Orientation = (%f, %f, %f)\n", v.gimbal.orientation->element[0][2], v.gimbal.orientation->element[1][2], v.gimbal.orientation->element[2][2]); + + status_code __code = vec3d_rotate(v, VEC3_Y_COMPONENT, M_PI/2, &v, &processors); + if (__code != PASS) { + fprintf(stderr, "Error: %d\n", __code); + } + + fprintf(stdout, "Vx Orientation = (%f, %f, %f)\n", v.gimbal.orientation->element[0][0], v.gimbal.orientation->element[1][0], v.gimbal.orientation->element[2][0]); + fprintf(stdout, "Vy Orientation = (%f, %f, %f)\n", v.gimbal.orientation->element[0][1], v.gimbal.orientation->element[1][1], v.gimbal.orientation->element[2][1]); + fprintf(stdout, "Vz Orientation = (%f, %f, %f)\n", v.gimbal.orientation->element[0][2], v.gimbal.orientation->element[1][2], v.gimbal.orientation->element[2][2]); + + __code = vec3d_rotate(v, VEC3_Y_COMPONENT, M_PI/4, &v, &processors); + if (__code != PASS) { + fprintf(stderr, "Error: %d\n", __code); + } + + + fprintf(stdout, "Vx Orientation = (%f, %f, %f)\n", v.gimbal.orientation->element[0][0], v.gimbal.orientation->element[1][0], v.gimbal.orientation->element[2][0]); + fprintf(stdout, "Vy Orientation = (%f, %f, %f)\n", v.gimbal.orientation->element[0][1], v.gimbal.orientation->element[1][1], v.gimbal.orientation->element[2][1]); + fprintf(stdout, "Vz Orientation = (%f, %f, %f)\n", v.gimbal.orientation->element[0][2], v.gimbal.orientation->element[1][2], v.gimbal.orientation->element[2][2]); + + __code = vec3d_rotate(v, VEC3_Y_COMPONENT, M_PI/4, &v, &processors); + if (__code != PASS) { + fprintf(stderr, "Error: %d\n", __code); + } + + + fprintf(stdout, "Vx Orientation = (%f, %f, %f)\n", v.gimbal.orientation->element[0][0], v.gimbal.orientation->element[1][0], v.gimbal.orientation->element[2][0]); + fprintf(stdout, "Vy Orientation = (%f, %f, %f)\n", v.gimbal.orientation->element[0][1], v.gimbal.orientation->element[1][1], v.gimbal.orientation->element[2][1]); + fprintf(stdout, "Vz Orientation = (%f, %f, %f)\n", v.gimbal.orientation->element[0][2], v.gimbal.orientation->element[1][2], v.gimbal.orientation->element[2][2]); + + + __code = vec3d_rotate(v, VEC3_Y_COMPONENT, M_PI/4, &v, &processors); + if (__code != PASS) { + fprintf(stderr, "Error: %d\n", __code); + } + + + fprintf(stdout, "Vx Orientation = (%f, %f, %f)\n", v.gimbal.orientation->element[0][0], v.gimbal.orientation->element[1][0], v.gimbal.orientation->element[2][0]); + fprintf(stdout, "Vy Orientation = (%f, %f, %f)\n", v.gimbal.orientation->element[0][1], v.gimbal.orientation->element[1][1], v.gimbal.orientation->element[2][1]); + fprintf(stdout, "Vz Orientation = (%f, %f, %f)\n", v.gimbal.orientation->element[0][2], v.gimbal.orientation->element[1][2], v.gimbal.orientation->element[2][2]); + + + __code = vec3d_rotate(v, VEC3_Y_COMPONENT, M_PI/4, &v, &processors); + if (__code != PASS) { + fprintf(stderr, "Error: %d\n", __code); + } + fprintf(stdout, "Vx Orientation = (%f, %f, %f)\n", v.gimbal.orientation->element[0][0], v.gimbal.orientation->element[1][0], v.gimbal.orientation->element[2][0]); + fprintf(stdout, "Vy Orientation = (%f, %f, %f)\n", v.gimbal.orientation->element[0][1], v.gimbal.orientation->element[1][1], v.gimbal.orientation->element[2][1]); + fprintf(stdout, "Vz Orientation = (%f, %f, %f)\n", v.gimbal.orientation->element[0][2], v.gimbal.orientation->element[1][2], v.gimbal.orientation->element[2][2]); + + __code = vec3d_rotate(v, VEC3_Z_COMPONENT, M_PI/2, &v, &processors); + if (__code != PASS) { + fprintf(stderr, "Error: %d\n", __code); + } + fprintf(stdout, "Vx Orientation = (%f, %f, %f)\n", v.gimbal.orientation->element[0][0], v.gimbal.orientation->element[1][0], v.gimbal.orientation->element[2][0]); + fprintf(stdout, "Vy Orientation = (%f, %f, %f)\n", v.gimbal.orientation->element[0][1], v.gimbal.orientation->element[1][1], v.gimbal.orientation->element[2][1]); + fprintf(stdout, "Vz Orientation = (%f, %f, %f)\n", v.gimbal.orientation->element[0][2], v.gimbal.orientation->element[1][2], v.gimbal.orientation->element[2][2]); + +// + __code = vec3d_rotate(v, VEC3_X_COMPONENT, M_PI/4, &v, &processors); + if (__code != PASS) { + fprintf(stderr, "Error: %d\n", __code); + } + + + fprintf(stdout, "Vx Orientation = (%f, %f, %f)\n", v.gimbal.orientation->element[0][0], v.gimbal.orientation->element[1][0], v.gimbal.orientation->element[2][0]); + fprintf(stdout, "Vy Orientation = (%f, %f, %f)\n", v.gimbal.orientation->element[0][1], v.gimbal.orientation->element[1][1], v.gimbal.orientation->element[2][1]); + fprintf(stdout, "Vz Orientation = (%f, %f, %f)\n", v.gimbal.orientation->element[0][2], v.gimbal.orientation->element[1][2], v.gimbal.orientation->element[2][2]); + + + __code = vec3d_rotate(v, VEC3_X_COMPONENT, M_PI/4, &v, &processors); + if (__code != PASS) { + fprintf(stderr, "Error: %d\n", __code); + } + + + fprintf(stdout, "Vx Orientation = (%f, %f, %f)\n", v.gimbal.orientation->element[0][0], v.gimbal.orientation->element[1][0], v.gimbal.orientation->element[2][0]); + fprintf(stdout, "Vy Orientation = (%f, %f, %f)\n", v.gimbal.orientation->element[0][1], v.gimbal.orientation->element[1][1], v.gimbal.orientation->element[2][1]); + fprintf(stdout, "Vz Orientation = (%f, %f, %f)\n", v.gimbal.orientation->element[0][2], v.gimbal.orientation->element[1][2], v.gimbal.orientation->element[2][2]); + + return 0; +} \ No newline at end of file