diff --git a/CMakeLists.txt b/CMakeLists.txt index 2141d2b9..1758a0d0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -111,6 +111,7 @@ install( ) if(JUNO_TESTS) + add_definitions(-DUNITY_INCLUDE_DOUBLE) set(CMAKE_BUILD_TYPE Debug) enable_testing() add_library(unity ${juno_SOURCE_DIR}/deps/unity/src/unity.c) diff --git a/include/juno/math/juno_la.h b/include/juno/math/juno_la.h deleted file mode 100644 index 6369788a..00000000 --- a/include/juno/math/juno_la.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef JUNO_MATH_VEC_H -#define JUNO_MATH_VEC_H - -#include "juno/module.h" -#include "juno/types.h" -#include -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct JUNO_MATH_MAT_API_T JUNO_MATH_MAT_API_T; -JUNO_MODULE_DECLARE(JUNO_MATH_MAT_T); - -typedef struct JUNO_MATH_MAT_ROOT_TAG JUNO_MODULE_ROOT(JUNO_MATH_MAT_API_T, - size_t iNDim; - size_t iMDim; -) JUNO_MATH_MAT_ROOT_T; - -typedef struct JUNO_MATH_MAT_NxM_TAG JUNO_MODULE_DERIVE(JUNO_MATH_MAT_ROOT_T, - float tMat[]; -) JUNO_MATH_MAT_NxM_T; - -#define JUNO_MATH_MAT_NxM(TYPE_NAME_T, N, M) \ -typedef struct TYPE_NAME_T JUNO_MODULE_DERIVE(JUNO_MATH_MAT_ROOT_T, \ - float tMat[N][M]; \ -) TYPE_NAME_T; - -struct JUNO_MATH_MAT_API_T -{ - JUNO_RESULT_BOOL_T (*Equals)(JUNO_MATH_MAT_T *ptMat1, JUNO_MATH_MAT_T *ptMat2); -}; - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/juno/math/juno_math.h b/include/juno/math/juno_math.h index 1fe4f13b..46c299ae 100644 --- a/include/juno/math/juno_math.h +++ b/include/juno/math/juno_math.h @@ -1,12 +1,224 @@ -#ifndef JUNO_MATH_H -#define JUNO_MATH_H +#ifndef JUNO_H +#define JUNO_H -#include "juno_la.h" +#include "juno_math_types.h" +#include #ifdef __cplusplus extern "C" { #endif +/** + Add two vecf's together +*/ +static inline JUNO_VEC2_F64_T Juno_Vec2_f64_Add(JUNO_VEC2_F64_T tVec0, JUNO_VEC2_F64_T tVec1) +{ + tVec0.arr[0] += tVec1.arr[0]; + tVec0.arr[1] += tVec1.arr[1]; + return tVec0; +} + + +/** + Subtract to vec2f's + @param tVec0 The vec to subtract from + @param tVec1 The vec to subtract +*/ +static inline JUNO_VEC2_F64_T Juno_Vec2_f64_Sub(JUNO_VEC2_F64_T tVec0, JUNO_VEC2_F64_T tVec1) +{ + tVec0.arr[0] -= tVec1.arr[0]; + tVec0.arr[1] -= tVec1.arr[1]; + return tVec0; +} + +/** + Multiply scalar with vec2f's +*/ +static inline JUNO_VEC2_F64_T Juno_Vec2_f64_Mult(JUNO_VEC2_F64_T tVec0, double dScalar) +{ + tVec0.arr[0] *= dScalar; + tVec0.arr[1] *= dScalar; + return tVec0; +} + +/** + Dot product of two vec2f's +*/ +static inline double Juno_Vec2_f64_Dot(JUNO_VEC2_F64_T tVec0, JUNO_VEC2_F64_T tVec1) +{ + return tVec0.arr[0] * tVec1.arr[0] + tVec0.arr[1] * tVec1.arr[1]; +} + +/** + The cross product of two vec2f's. + The result is a psedoscalar +*/ +static inline double Juno_Vec2_f64_Cross(JUNO_VEC2_F64_T tVec0, JUNO_VEC2_F64_T tVec1) +{ + return tVec0.arr[0] * tVec1.arr[1] - tVec0.arr[1] * tVec1.arr[0]; +} + +/// Add two vec2i's +static inline JUNO_VEC2_I32_T Juno_Vec2_i32_Add(JUNO_VEC2_I32_T tVec0, JUNO_VEC2_I32_T tVec1) +{ + tVec0.arr[0] += tVec1.arr[0]; + tVec0.arr[1] += tVec1.arr[1]; + return tVec0; +} + + +/** + Subtract to vec2i's + @param tVec0 The vec to subtract from + @param tVec1 The vec to subtract +*/ +static inline JUNO_VEC2_I32_T Juno_Vec2_i32_Sub(JUNO_VEC2_I32_T tVec0, JUNO_VEC2_I32_T tVec1) +{ + tVec0.arr[0] -= tVec1.arr[0]; + tVec0.arr[1] -= tVec1.arr[1]; + return tVec0; +} + +/** + Multiply scalar with vec2f's +*/ +static inline JUNO_VEC2_I32_T Juno_Vec2_i32_Mult(JUNO_VEC2_I32_T tVec0, int32_t dScalar) +{ + tVec0.arr[0] *= dScalar; + tVec0.arr[1] *= dScalar; + return tVec0; +} + +/** + Dot product of two vec2i's +*/ +static inline int32_t Juno_Vec2_i32_Dot(JUNO_VEC2_I32_T tVec0, JUNO_VEC2_I32_T tVec1) +{ + return tVec0.arr[0] * tVec1.arr[0] + tVec0.arr[1] * tVec1.arr[1]; +} + +/** + The cross product of two vec2i's. + The result is a psedoscalar +*/ +static inline int32_t Juno_Vec2_i32_Cross(JUNO_VEC2_I32_T tVec0, JUNO_VEC2_I32_T tVec1) +{ + return tVec0.arr[0] * tVec1.arr[1] - tVec0.arr[1] * tVec1.arr[0]; +} + +/** + Add two vecf's together +*/ +static inline JUNO_VEC3_F64_T Juno_Vec3_f64_Add(JUNO_VEC3_F64_T tVec0, JUNO_VEC3_F64_T tVec1) +{ + tVec0.arr[0] += tVec1.arr[0]; + tVec0.arr[1] += tVec1.arr[1]; + tVec0.arr[2] += tVec1.arr[2]; + return tVec0; +} + + +/** + Subtract to vec2f's + @param tVec0 The vec to subtract from + @param tVec1 The vec to subtract +*/ +static inline JUNO_VEC3_F64_T Juno_Vec3_f64_Sub(JUNO_VEC3_F64_T tVec0, JUNO_VEC3_F64_T tVec1) +{ + tVec0.arr[0] -= tVec1.arr[0]; + tVec0.arr[1] -= tVec1.arr[1]; + tVec0.arr[2] -= tVec1.arr[2]; + return tVec0; +} + +/** + Multiply scalar with vec2f's +*/ +static inline JUNO_VEC3_F64_T Juno_Vec3_f64_Mult(JUNO_VEC3_F64_T tVec0, double dScalar) +{ + tVec0.arr[0] *= dScalar; + tVec0.arr[1] *= dScalar; + tVec0.arr[2] *= dScalar; + return tVec0; +} + +/** + Dot product of two vec2f's +*/ +static inline double Juno_Vec3_f64_Dot(JUNO_VEC3_F64_T tVec0, JUNO_VEC3_F64_T tVec1) +{ + return tVec0.arr[0] * tVec1.arr[0] + tVec0.arr[1] * tVec1.arr[1] + tVec0.arr[2] * tVec1.arr[2]; +} + +/** + The cross product of two vec2f's. + The result is a psedoscalar +*/ +static inline JUNO_VEC3_F64_T Juno_Vec3_f64_Cross(JUNO_VEC3_F64_T tVec0, JUNO_VEC3_F64_T tVec1) +{ + JUNO_VEC3_F64_T tRes = { + .arr[0] = tVec0.arr[1] * tVec1.arr[2] - tVec0.arr[2] * tVec1.arr[1], + .arr[1] = tVec0.arr[2] * tVec1.arr[0] - tVec0.arr[0] * tVec1.arr[2], + .arr[2] = tVec0.arr[0] * tVec1.arr[1] - tVec0.arr[1] * tVec1.arr[0] + }; + return tRes; +} + +/// Add two vec2i's +static inline JUNO_VEC3_I32_T Juno_Vec3_i32_Add(JUNO_VEC3_I32_T tVec0, JUNO_VEC3_I32_T tVec1) +{ + tVec0.arr[0] += tVec1.arr[0]; + tVec0.arr[1] += tVec1.arr[1]; + tVec0.arr[2] += tVec1.arr[2]; + return tVec0; +} + + +/** + Subtract to vec2i's + @param tVec0 The vec to subtract from + @param tVec1 The vec to subtract +*/ +static inline JUNO_VEC3_I32_T Juno_Vec3_i32_Sub(JUNO_VEC3_I32_T tVec0, JUNO_VEC3_I32_T tVec1) +{ + tVec0.arr[0] -= tVec1.arr[0]; + tVec0.arr[1] -= tVec1.arr[1]; + tVec0.arr[2] -= tVec1.arr[2]; + return tVec0; +} + +/** + Multiply scalar with vec2f's +*/ +static inline JUNO_VEC3_I32_T Juno_Vec3_i32_Mult(JUNO_VEC3_I32_T tVec0, int32_t dScalar) +{ + tVec0.arr[0] *= dScalar; + tVec0.arr[1] *= dScalar; + tVec0.arr[2] *= dScalar; + return tVec0; +} + +/** + Dot product of two vec2i's +*/ +static inline int32_t Juno_Vec3_i32_Dot(JUNO_VEC3_I32_T tVec0, JUNO_VEC3_I32_T tVec1) +{ + return tVec0.arr[0] * tVec1.arr[0] + tVec0.arr[1] * tVec1.arr[1] + tVec0.arr[2] * tVec1.arr[2]; +} + +/** + The cross product of two vec2i's. + The result is a psedoscalar +*/ +static inline JUNO_VEC3_I32_T Juno_Vec3_i32_Cross(JUNO_VEC3_I32_T tVec0, JUNO_VEC3_I32_T tVec1) +{ + JUNO_VEC3_I32_T tRes = { + .arr[0] = tVec0.arr[1] * tVec1.arr[2] - tVec0.arr[2] * tVec1.arr[1], + .arr[1] = tVec0.arr[2] * tVec1.arr[0] - tVec0.arr[0] * tVec1.arr[2], + .arr[2] = tVec0.arr[0] * tVec1.arr[1] - tVec0.arr[1] * tVec1.arr[0] + }; + return tRes; +} #ifdef __cplusplus } diff --git a/include/juno/math/juno_math_constants.h b/include/juno/math/juno_math_constants.h new file mode 100644 index 00000000..f5a2b946 --- /dev/null +++ b/include/juno/math/juno_math_constants.h @@ -0,0 +1,18 @@ +#ifndef JUNO_CONST_H +#define JUNO_CONST_H + +#include "juno/module.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define JUNO_PI 3.141592653589793 +#define JUNO_HALF_PI 1.5707963267948966 +#define JUNO_QUART_PI 0.7853981633974483 +#define JUNO_E 2.718281828459045 + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/include/juno/math/juno_math_types.h b/include/juno/math/juno_math_types.h new file mode 100644 index 00000000..af121a4b --- /dev/null +++ b/include/juno/math/juno_math_types.h @@ -0,0 +1,492 @@ +#ifndef JUNO_TYPES_H +#define JUNO_TYPES_H + +#include "juno/module.h" +#ifdef __cplusplus +extern "C" { +#endif +#include + +#ifndef JUNO_INT_TYPE +#define JUNO_INT_TYPE int64_t +#endif + +#ifndef JUNO_FLOAT_TYPE +#define JUNO_FLOAT_TYPE double +#endif +/** + * @struct JUNO_VEC2_F64_POLAR_TAG + * @brief 2D vector in polar coordinates (double precision). + * + * Contains radial distance and angle in radians. + */ +typedef struct JUNO_VEC2_F64_POLAR_TAG +{ + struct { + double r; /**< Radial distance from the origin. */ + double phi; /**< Angle in radians from the x-axis. */ + }; +} JUNO_VEC2_F64_POLAR_T; + +/** + * @struct JUNO_VEC2_F64_CART_TAG + * @brief 2D vector in Cartesian coordinates (double precision). + * + * Contains x and y components. + */ +typedef struct JUNO_VEC2_F64_CART_TAG +{ + struct { + double x; /**< X component. */ + double y; /**< Y component. */ + }; +} JUNO_VEC2_F64_CART_T; + +/** + * @union JUNO_VEC2_F64_TAG + * @brief 2D vector union supporting Cartesian, polar, and array access (double precision). + * + * - tCart: Cartesian form. + * - tPolar: Polar form. + * - arr: Raw component array [0]=x/r, [1]=y/phi. + */ +typedef union JUNO_VEC2_F64_TAG +{ + JUNO_VEC2_F64_CART_T tCart; /**< Cartesian coordinates. */ + JUNO_VEC2_F64_POLAR_T tPolar; /**< Polar coordinates. */ + double arr[2]; /**< Raw component array. */ +} JUNO_VEC2_F64_T; + +/** + * @typedef JUNO_VEC2_F64_POLAR_RESULT_T + * @brief Result type for functions returning JUNO_VEC2_F64_POLAR_T. + */ +JUNO_MODULE_RESULT(JUNO_VEC2_F64_POLAR_RESULT_T, JUNO_VEC2_F64_POLAR_T); + +/** + * @typedef JUNO_VEC2_F64_CART_RESULT_T + * @brief Result type for functions returning JUNO_VEC2_F64_CART_T. + */ +JUNO_MODULE_RESULT(JUNO_VEC2_F64_CART_RESULT_T, JUNO_VEC2_F64_CART_T); + +/** + * @typedef JUNO_VEC2_F64_RESULT_T + * @brief Result type for functions returning JUNO_VEC2_F64_T. + */ +JUNO_MODULE_RESULT(JUNO_VEC2_F64_RESULT_T, JUNO_VEC2_F64_T); + +/** + * @struct JUNO_VEC2_I32_POLAR_TAG + * @brief 2D vector in polar coordinates (32-bit integer). + * + * Contains radial distance and angle. + */ +typedef struct JUNO_VEC2_I32_POLAR_TAG +{ + struct { + int32_t r; /**< Radial distance from the origin. */ + int32_t phi; /**< Angle unit (e.g., degrees or custom). */ + }; +} JUNO_VEC2_I32_POLAR_T; + +/** + * @struct JUNO_VEC2_I32_CART_TAG + * @brief 2D vector in Cartesian coordinates (32-bit integer). + * + * Contains x and y components. + */ +typedef struct JUNO_VEC2_I32_CART_TAG +{ + struct { + int32_t x; /**< X component. */ + int32_t y; /**< Y component. */ + }; +} JUNO_VEC2_I32_CART_T; + +/** + * @union JUNO_VEC2_I32_TAG + * @brief 2D vector union supporting Cartesian, polar, and array access (32-bit integer). + * + * - tCart: Cartesian form. + * - tPolar: Polar form. + * - arr: Raw component array [0]=x/r, [1]=y/phi. + */ +typedef union JUNO_VEC2_I32_TAG +{ + JUNO_VEC2_I32_CART_T tCart; /**< Cartesian coordinates. */ + JUNO_VEC2_I32_POLAR_T tPolar; /**< Polar coordinates. */ + int32_t arr[2]; /**< Raw component array. */ +} JUNO_VEC2_I32_T; + +/** + * @typedef JUNO_VEC2_I32_POLAR_RESULT_T + * @brief Result type for functions returning JUNO_VEC2_I32_POLAR_T. + */ +JUNO_MODULE_RESULT(JUNO_VEC2_I32_POLAR_RESULT_T, JUNO_VEC2_I32_POLAR_T); + +/** + * @typedef JUNO_VEC2_I32_CART_RESULT_T + * @brief Result type for functions returning JUNO_VEC2_I32_CART_T. + */ +JUNO_MODULE_RESULT(JUNO_VEC2_I32_CART_RESULT_T, JUNO_VEC2_I32_CART_T); + +/** + * @typedef JUNO_VEC2_I32_RESULT_T + * @brief Result type for functions returning JUNO_VEC2_I32_T. + */ +JUNO_MODULE_RESULT(JUNO_VEC2_I32_RESULT_T, JUNO_VEC2_I32_T); + +/** + * @struct JUNO_VEC3_F64_POLAR_TAG + * @brief 3D vector in spherical coordinates (double precision). + * + * Contains radius, azimuthal angle (phi), and polar angle (theta). + */ +typedef struct JUNO_VEC3_F64_POLAR_TAG +{ + struct { + double r; /**< Radial distance from the origin. */ + double phi; /**< Azimuthal angle in radians. */ + double theta; /**< Polar angle in radians. */ + }; +} JUNO_VEC3_F64_POLAR_T; + +/** + * @struct JUNO_VEC3_F64_CART_TAG + * @brief 3D vector in Cartesian coordinates (double precision). + * + * Contains x, y, and z components. + */ +typedef struct JUNO_VEC3_F64_CART_TAG +{ + struct { + double x; /**< X component. */ + double y; /**< Y component. */ + double z; /**< Z component. */ + }; +} JUNO_VEC3_F64_CART_T; + +/** + * @union JUNO_VEC3_F64_TAG + * @brief 3D vector union supporting Cartesian, spherical, and array access (double precision). + * + * - tCart: Cartesian form. + * - tPolar: Spherical form. + * - arr: Raw component array [0]=x/r, [1]=y/phi, [2]=z/theta. + */ +typedef union JUNO_VEC3_F64_TAG +{ + JUNO_VEC3_F64_CART_T tCart; /**< Cartesian coordinates. */ + JUNO_VEC3_F64_POLAR_T tPolar; /**< Spherical coordinates. */ + double arr[3]; /**< Raw component array. */ +} JUNO_VEC3_F64_T; + +/** + * @typedef JUNO_VEC3_F64_POLAR_RESULT_T + * @brief Result type for functions returning JUNO_VEC3_F64_POLAR_T. + */ +JUNO_MODULE_RESULT(JUNO_VEC3_F64_POLAR_RESULT_T, JUNO_VEC3_F64_POLAR_T); + +/** + * @typedef JUNO_VEC3_F64_CART_RESULT_T + * @brief Result type for functions returning JUNO_VEC3_F64_CART_T. + */ +JUNO_MODULE_RESULT(JUNO_VEC3_F64_CART_RESULT_T, JUNO_VEC3_F64_CART_T); + +/** + * @typedef JUNO_VEC3F_RESULT_T + * @brief Result type for functions returning JUNO_VEC3_F64_T. + */ +JUNO_MODULE_RESULT(JUNO_VEC3F_RESULT_T, JUNO_VEC3_F64_T); + +/** + * @struct JUNO_VEC3_I32_POLAR_TAG + * @brief 3D vector in spherical coordinates (32-bit integer). + * + * Contains radius, azimuthal angle, and polar angle. + */ +typedef struct JUNO_VEC3_I32_POLAR_TAG +{ + struct { + int32_t r; /**< Radial distance from the origin. */ + int32_t phi; /**< Azimuthal angle unit. */ + int32_t theta; /**< Polar angle unit. */ + }; +} JUNO_VEC3_I32_POLAR_T; + +/** + * @struct JUNO_VEC3_I32_CART_TAG + * @brief 3D vector in Cartesian coordinates (32-bit integer). + * + * Contains x, y, and z components. + */ +typedef struct JUNO_VEC3_I32_CART_TAG +{ + struct { + int32_t x; /**< X component. */ + int32_t y; /**< Y component. */ + int32_t z; /**< Z component. */ + }; +} JUNO_VEC3_I32_CART_T; + +/** + * @union JUNO_VEC3_I32_TAG + * @brief 3D vector union supporting Cartesian, spherical, and array access (32-bit integer). + * + * - tCart: Cartesian form. + * - tPolar: Spherical form. + * - arr: Raw component array [0]=x/r, [1]=y/phi, [2]=z/theta. + */ +typedef union JUNO_VEC3_I32_TAG +{ + JUNO_VEC3_I32_CART_T tCart; /**< Cartesian coordinates. */ + JUNO_VEC3_I32_POLAR_T tPolar; /**< Spherical coordinates. */ + int32_t arr[3]; /**< Raw component array. */ +} JUNO_VEC3_I32_T; + +/** + * @typedef JUNO_VEC3_I32_POLAR_RESULT_T + * @brief Result type for functions returning JUNO_VEC3_I32_POLAR_T. + */ +JUNO_MODULE_RESULT(JUNO_VEC3_I32_POLAR_RESULT_T, JUNO_VEC3_I32_POLAR_T); + +/** + * @typedef JUNO_VEC3_I32_CART_RESULT_T + * @brief Result type for functions returning JUNO_VEC3_I32_CART_T. + */ +JUNO_MODULE_RESULT(JUNO_VEC3_I32_CART_RESULT_T, JUNO_VEC3_I32_CART_T); + +/** + * @typedef JUNO_VEC3_I32_RESULT_T + * @brief Result type for functions returning JUNO_VEC3_I32_T. + */ +JUNO_MODULE_RESULT(JUNO_VEC3_I32_RESULT_T, JUNO_VEC3_I32_T); + +/** + * @struct JUNO_VEC4_F64_POLAR_TAG + * @brief 4D vector in hyperspherical coordinates (double precision). + * + * Contains radial distance and three angles. + */ +typedef struct JUNO_VEC4_F64_POLAR_TAG +{ + struct { + double r; /**< Radial distance from the origin. */ + double phi; /**< First angular coordinate. */ + double theta; /**< Second angular coordinate. */ + double rho; /**< Third angular coordinate. */ + }; +} JUNO_VEC4_F64_POLAR_T; + +/** + * @struct JUNO_VEC4_F64_CART_TAG + * @brief 4D vector in Cartesian coordinates (double precision). + * + * Contains x, y, z, and w components. + */ +typedef struct JUNO_VEC4_F64_CART_TAG +{ + struct { + double x; /**< X component. */ + double y; /**< Y component. */ + double z; /**< Z component. */ + double w; /**< W component. */ + }; +} JUNO_VEC4_F64_CART_T; + +/** + * @union JUNO_VEC4_F64_TAG + * @brief 4D vector union supporting Cartesian, hyperspherical, and array access (double precision). + * + * - tCart: Cartesian form. + * - tPolar: Hyperspherical form. + * - arr: Raw component array [0]=x/r, [1]=y/phi, [2]=z/theta, [3]=w/rho. + */ +typedef union JUNO_VEC4_F64_TAG +{ + JUNO_VEC4_F64_CART_T tCart; /**< Cartesian coordinates. */ + JUNO_VEC4_F64_POLAR_T tPolar; /**< Hyperspherical coordinates. */ + double arr[4]; /**< Raw component array. */ +} JUNO_VEC4_F64_T; + +/** + * @typedef JUNO_VEC4F_RESULT_T + * @brief Result type for functions returning JUNO_VEC3_F64_T (per original macro invocation). + */ +JUNO_MODULE_RESULT(JUNO_VEC4F_RESULT_T, JUNO_VEC3_F64_T); + +/** + * @struct JUNO_VEC4_I32_POLAR_TAG + * @brief 4D vector in hyperspherical coordinates (32-bit integer). + * + * Contains radial distance and three angles. + */ +typedef struct JUNO_VEC4_I32_POLAR_TAG +{ + struct { + int32_t r; /**< Radial distance from the origin. */ + int32_t phi; /**< First angular coordinate. */ + int32_t theta; /**< Second angular coordinate. */ + int32_t rho; /**< Third angular coordinate. */ + }; +} JUNO_VEC4_I32_POLAR_T; + +/** + * @struct JUNO_VEC4_I32_CART_TAG + * @brief 4D vector in Cartesian coordinates (32-bit integer). + * + * Contains x, y, z, and w components. + */ +typedef struct JUNO_VEC4_I32_CART_TAG +{ + struct { + int32_t x; /**< X component. */ + int32_t y; /**< Y component. */ + int32_t z; /**< Z component. */ + int32_t w; /**< W component. */ + }; +} JUNO_VEC4_I32_CART_T; + +/** + * @union JUNO_VEC4_I32_TAG + * @brief 4D vector union supporting Cartesian, hyperspherical, and array access (32-bit integer). + * + * - tCart: Cartesian form. + * - tPolar: Hyperspherical form. + * - arr: Raw component array [0]=x/r, [1]=y/phi, [2]=z/theta, [3]=w/rho. + */ +typedef union JUNO_VEC4_I32_TAG +{ + JUNO_VEC4_I32_CART_T tCart; /**< Cartesian coordinates. */ + JUNO_VEC4_I32_POLAR_T tPolar; /**< Hyperspherical coordinates. */ + int32_t arr[4]; /**< Raw component array. */ +} JUNO_VEC4_I32_T; + +/** + * @typedef JUNO_VEC4_I32_POLAR_RESULT_T + * @brief Result type for functions returning JUNO_VEC4_I32_POLAR_T. + */ +JUNO_MODULE_RESULT(JUNO_VEC4_I32_POLAR_RESULT_T, JUNO_VEC4_I32_POLAR_T); + +/** + * @typedef JUNO_VEC4_I32_CART_RESULT_T + * @brief Result type for functions returning JUNO_VEC4_I32_CART_T. + */ +JUNO_MODULE_RESULT(JUNO_VEC4_I32_CART_RESULT_T, JUNO_VEC4_I32_CART_T); + +/** + * @typedef JUNO_VEC4_I32_RESULT_T + * @brief Result type for functions returning JUNO_VEC4_I32_T. + */ +JUNO_MODULE_RESULT(JUNO_VEC4_I32_RESULT_T, JUNO_VEC4_I32_T); + +/** + * @struct JUNO_M3X3_F64_TAG + * @brief 3×3 matrix of double-precision values. + */ +typedef struct JUNO_M3X3_F64_TAG +{ + double mat[3][3]; /**< Row-major 3×3 matrix. */ +} JUNO_M3X3_F64_T; + +/** + * @typedef JUNO_M3X3F_RESULT_T + * @brief Result type for functions returning JUNO_M3X3_F64_T. + */ +JUNO_MODULE_RESULT(JUNO_M3X3F_RESULT_T, JUNO_M3X3_F64_T); + +/** + * @struct JUNO_M4X4_F64_TAG + * @brief 4×4 matrix of double-precision values. + */ +typedef struct JUNO_M4X4_F64_TAG +{ + double mat[4][4]; /**< Row-major 4×4 matrix. */ +} JUNO_M4X4_F64_T; + +/** + * @typedef JUNO_M4X4F_RESULT_T + * @brief Result type for functions returning JUNO_M4X4_F64_T. + */ +JUNO_MODULE_RESULT(JUNO_M4X4F_RESULT_T, JUNO_M4X4_F64_T); + +/** + * @struct JUNO_M3X3_I32_TAG + * @brief 3×3 matrix of 32-bit integers. + */ +typedef struct JUNO_M3X3_I32_TAG +{ + int32_t mat[3][3]; /**< Row-major 3×3 matrix. */ +} JUNO_M3X3_I32_T; + +/** + * @typedef JUNO_M3X3I_RESULT_T + * @brief Result type for functions returning JUNO_M3X3_I32_T. + */ +JUNO_MODULE_RESULT(JUNO_M3X3I_RESULT_T, JUNO_M3X3_I32_T); + +/** + * @struct JUNO_M4X4_I32_TAG + * @brief 4×4 matrix of 32-bit integers. + */ +typedef struct JUNO_M4X4_I32_TAG +{ + int32_t mat[4][4]; /**< Row-major 4×4 matrix. */ +} JUNO_M4X4_I32_T; + +/** + * @typedef JUNO_M4X4I_RESULT_T + * @brief Result type for functions returning JUNO_M4X4_I32_T. + */ +JUNO_MODULE_RESULT(JUNO_M4X4I_RESULT_T, JUNO_M4X4_I32_T); + +/** + * @union JUNO_RQUAT_F64_TAG + * @brief Right-handed quaternion (double precision). + * + * Can be accessed as individual components or raw array. + */ +typedef union JUNO_RQUAT_F64_TAG +{ + struct { + double s; /**< Scalar part. */ + double i; /**< First vector part. */ + double j; /**< Second vector part. */ + double k; /**< Third vector part. */ + }; + double quat[4]; /**< Raw quaternion array [s,i,j,k]. */ +} JUNO_RQUAT_F64_T; + +/** + * @typedef JUNO_RQUATF_RESULT_T + * @brief Result type for functions returning JUNO_RQUAT_F64_T. + */ +JUNO_MODULE_RESULT(JUNO_RQUATF_RESULT_T, JUNO_RQUAT_F64_T); + +/** + * @union JUNO_RQUAT_I32_TAG + * @brief Right-handed quaternion (32-bit integer). + * + * Can be accessed as individual components or raw array. + */ +typedef union JUNO_RQUAT_I32_TAG +{ + struct { + int32_t s; /**< Scalar part. */ + int32_t i; /**< First vector part. */ + int32_t j; /**< Second vector part. */ + int32_t k; /**< Third vector part. */ + }; + int32_t quat[4]; /**< Raw quaternion array [s,i,j,k]. */ +} JUNO_RQUAT_I32_T; + +/** + * @typedef JUNO_RQUATI_RESULT_T + * @brief Result type for functions returning JUNO_RQUAT_I32_T. + */ +JUNO_MODULE_RESULT(JUNO_RQUATI_RESULT_T, JUNO_RQUAT_I32_T); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/juno/module.h b/include/juno/module.h index c4ca0901..d07dcfbc 100644 --- a/include/juno/module.h +++ b/include/juno/module.h @@ -206,16 +206,31 @@ */ #define JUNO_MODULE_GET_API(ptModule, ROOT_T) ((const ROOT_T *)ptModule)->ptApi -#define JUNO_MODULE_RESULT(SUCCESS_T) \ + +/** + * @def JUNO_MODULE_RESULT(NAME_T, SUCCESS_T) + * @brief Defines a result type combining a status and a success payload. + * @param NAME_T Name of the result struct to define. + * @param SUCCESS_T Type of the success payload contained in the result. + */ +#define JUNO_MODULE_RESULT(NAME_T, SUCCESS_T) \ +typedef struct NAME_T \ { \ JUNO_STATUS_T tStatus; \ SUCCESS_T tSuccess; \ -} +} NAME_T -#define JUNO_MODULE_OPTION(SOME_T) \ +/** + * @def JUNO_MODULE_OPTION(NAME_T, SUCCESS_T) + * @brief Defines an option type combining a flag to indicate some and a success payload. + * @param NAME_T Name of the result struct to define. + * @param SUCCESS_T Type of the success payload contained in the result. + */ +#define JUNO_MODULE_OPTION(NAME_T, SOME_T) \ +typedef struct NAME_T \ { \ bool bIsSome; \ SOME_T tSome; \ -} +} NAME_T; #endif // JUNO_MODULE_H diff --git a/include/juno/types.h b/include/juno/types.h index cb4a871e..7fd6f898 100644 --- a/include/juno/types.h +++ b/include/juno/types.h @@ -7,8 +7,10 @@ extern "C" #endif #include #include +#include -typedef struct JUNO_RESULT_BOOL_TAG JUNO_MODULE_RESULT(bool) JUNO_RESULT_BOOL_T; +JUNO_MODULE_RESULT(JUNO_RESULT_BOOL_T, bool); +JUNO_MODULE_RESULT(JUNO_RESULT_UINT32_T, uint32_t); #ifdef __cplusplus } diff --git a/tests/test_la.c b/tests/test_la.c index 4255862e..892e26bb 100644 --- a/tests/test_la.c +++ b/tests/test_la.c @@ -1,9 +1,10 @@ -#include "juno/memory/memory_api.h" +#include "juno/math/juno_math_types.h" #include "unity.h" #include "unity_internals.h" #include #include -#include "juno/math/juno_la.h" +#include +#include "juno/math/juno_math.h" void setUp(void) { @@ -13,26 +14,248 @@ void tearDown(void) { } -JUNO_MATH_MAT_NxM(MAT_3x3, 3, 3); -static void test_mat_index(void) +static void test_vec2_f64_add(void) { - MAT_3x3 tMat3x3 = {.tRoot = {.iNDim = 3, .iMDim = 3}, .tMat = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}}}; - float tTruth[3][3] ={{0, 1, 2}, {3, 4, 5}, {6, 7, 8}}; - for(size_t i = 0; i < 3; i++) + JUNO_VEC2_F64_T tVec1 = {1, 2}; + JUNO_VEC2_F64_T tVec2 = {4, 5}; + JUNO_VEC2_F64_T tRes = Juno_Vec2_f64_Add(tVec1, tVec2); + JUNO_VEC2_F64_T tTruth = {5, 7}; + for(uint8_t i = 0; i < 2; i++) { - for(size_t j = 0; j < 3; j++) - { - TEST_ASSERT_EQUAL_FLOAT(tTruth[i][j], tMat3x3.tMat[i][j]); - JUNO_MATH_MAT_NxM_T *ptMatNxM = (JUNO_MATH_MAT_NxM_T*) &tMat3x3; - TEST_ASSERT_EQUAL_FLOAT(tTruth[i][j], ptMatNxM->tMat[i*ptMatNxM->tRoot.iMDim + j]); - } + TEST_ASSERT_EQUAL_DOUBLE(tTruth.arr[i], tRes.arr[i]); + } +} + +static void test_vec2_f64_sub(void) +{ + JUNO_VEC2_F64_T tVec1 = {1, 2}; + JUNO_VEC2_F64_T tVec2 = {4, 5}; + JUNO_VEC2_F64_T tRes = Juno_Vec2_f64_Sub(tVec1, tVec2); + JUNO_VEC2_F64_T tTruth = {-3, -3}; + for(uint8_t i = 0; i < 2; i++) + { + TEST_ASSERT_EQUAL_DOUBLE(tTruth.arr[i], tRes.arr[i]); + } +} + +static void test_vec2_f64_mult(void) +{ + JUNO_VEC2_F64_T tVec1 = {1, 2}; + JUNO_VEC2_F64_T tRes = Juno_Vec2_f64_Mult(tVec1, 2); + JUNO_VEC2_F64_T tTruth = {2, 4}; + for(uint8_t i = 0; i < 2; i++) + { + TEST_ASSERT_EQUAL_DOUBLE(tTruth.arr[i], tRes.arr[i]); + } +} + +static void test_vec2_f64_dot(void) +{ + JUNO_VEC2_F64_T tVec1 = {1, 2}; + JUNO_VEC2_F64_T tVec2 = {4, 5}; + double tRes = Juno_Vec2_f64_Dot(tVec1, tVec2); + double tTruth = 14; + TEST_ASSERT_EQUAL_DOUBLE(tTruth, tRes); +} + +static void test_vec2_f64_cross(void) +{ + JUNO_VEC2_F64_T tVec1 = {1, 2}; + JUNO_VEC2_F64_T tVec2 = {4, 5}; + double tRes = Juno_Vec2_f64_Cross(tVec1, tVec2); + double tTruth = -3; + TEST_ASSERT_EQUAL_DOUBLE(tTruth, tRes); +} + +static void test_vec2_i32_add(void) +{ + JUNO_VEC2_I32_T tVec1 = {1, 2}; + JUNO_VEC2_I32_T tVec2 = {4, 5}; + JUNO_VEC2_I32_T tRes = Juno_Vec2_i32_Add(tVec1, tVec2); + JUNO_VEC2_I32_T tTruth = {5, 7}; + for(uint8_t i = 0; i < 2; i++) + { + TEST_ASSERT_EQUAL_DOUBLE(tTruth.arr[i], tRes.arr[i]); + } +} + +static void test_vec2_i32_sub(void) +{ + JUNO_VEC2_I32_T tVec1 = {1, 2}; + JUNO_VEC2_I32_T tVec2 = {4, 5}; + JUNO_VEC2_I32_T tRes = Juno_Vec2_i32_Sub(tVec1, tVec2); + JUNO_VEC2_I32_T tTruth = {-3, -3}; + for(uint8_t i = 0; i < 2; i++) + { + TEST_ASSERT_EQUAL_DOUBLE(tTruth.arr[i], tRes.arr[i]); + } +} + +static void test_vec2_i32_mult(void) +{ + JUNO_VEC2_I32_T tVec1 = {1, 2}; + JUNO_VEC2_I32_T tRes = Juno_Vec2_i32_Mult(tVec1, 2); + JUNO_VEC2_I32_T tTruth = {2, 4}; + for(uint8_t i = 0; i < 2; i++) + { + TEST_ASSERT_EQUAL_DOUBLE(tTruth.arr[i], tRes.arr[i]); + } +} + +static void test_vec2_i32_dot(void) +{ + JUNO_VEC2_I32_T tVec1 = {1, 2}; + JUNO_VEC2_I32_T tVec2 = {4, 5}; + int32_t tRes = Juno_Vec2_i32_Dot(tVec1, tVec2); + int32_t tTruth = 14; + TEST_ASSERT_EQUAL_DOUBLE(tTruth, tRes); +} + +static void test_vec2_i32_cross(void) +{ + JUNO_VEC2_I32_T tVec1 = {1, 2}; + JUNO_VEC2_I32_T tVec2 = {4, 5}; + int32_t tRes = Juno_Vec2_i32_Cross(tVec1, tVec2); + int32_t tTruth = -3; + TEST_ASSERT_EQUAL_DOUBLE(tTruth, tRes); +} + + +static void test_vec3_f64_add(void) +{ + JUNO_VEC3_F64_T tVec1 = {1, 2, 3}; + JUNO_VEC3_F64_T tVec2 = {4, 5, 6}; + JUNO_VEC3_F64_T tRes = Juno_Vec3_f64_Add(tVec1, tVec2); + JUNO_VEC3_F64_T tTruth = {5, 7, 9}; + for(uint8_t i = 0; i < 3; i++) + { + TEST_ASSERT_EQUAL_DOUBLE(tTruth.arr[i], tRes.arr[i]); + } +} + +static void test_vec3_f64_sub(void) +{ + JUNO_VEC3_F64_T tVec1 = {1, 2, 3}; + JUNO_VEC3_F64_T tVec2 = {4, 5, 6}; + JUNO_VEC3_F64_T tRes = Juno_Vec3_f64_Sub(tVec1, tVec2); + JUNO_VEC3_F64_T tTruth = {-3, -3, -3}; + for(uint8_t i = 0; i < 3; i++) + { + TEST_ASSERT_EQUAL_DOUBLE(tTruth.arr[i], tRes.arr[i]); + } +} + +static void test_vec3_f64_mult(void) +{ + JUNO_VEC3_F64_T tVec1 = {1, 2, 3}; + JUNO_VEC3_F64_T tRes = Juno_Vec3_f64_Mult(tVec1, 2); + JUNO_VEC3_F64_T tTruth = {2, 4, 6}; + for(uint8_t i = 0; i < 3; i++) + { + TEST_ASSERT_EQUAL_DOUBLE(tTruth.arr[i], tRes.arr[i]); + } +} + +static void test_vec3_f64_dot(void) +{ + JUNO_VEC3_F64_T tVec1 = {1, 2, 3}; + JUNO_VEC3_F64_T tVec2 = {4, 5, 6}; + double tRes = Juno_Vec3_f64_Dot(tVec1, tVec2); + double tTruth = 32; + TEST_ASSERT_EQUAL_DOUBLE(tTruth, tRes); +} + +static void test_vec3_f64_cross(void) +{ + JUNO_VEC3_F64_T tVec1 = {1, 2, 3}; + JUNO_VEC3_F64_T tVec2 = {4, 5, 6}; + JUNO_VEC3_F64_T tRes = Juno_Vec3_f64_Cross(tVec1, tVec2); + JUNO_VEC3_F64_T tTruth = {-3, 6, -3}; + for(uint8_t i = 0; i < 3; i++) + { + TEST_ASSERT_EQUAL_DOUBLE(tTruth.arr[i], tRes.arr[i]); + } +} + +static void test_vec3_i32_add(void) +{ + JUNO_VEC3_I32_T tVec1 = {1, 2, 3}; + JUNO_VEC3_I32_T tVec2 = {4, 5, 6}; + JUNO_VEC3_I32_T tRes = Juno_Vec3_i32_Add(tVec1, tVec2); + JUNO_VEC3_I32_T tTruth = {5, 7, 9}; + for(uint8_t i = 0; i < 3; i++) + { + TEST_ASSERT_EQUAL_DOUBLE(tTruth.arr[i], tRes.arr[i]); + } +} + +static void test_vec3_i32_sub(void) +{ + JUNO_VEC3_I32_T tVec1 = {1, 2, 3}; + JUNO_VEC3_I32_T tVec2 = {4, 5, 6}; + JUNO_VEC3_I32_T tRes = Juno_Vec3_i32_Sub(tVec1, tVec2); + JUNO_VEC3_I32_T tTruth = {-3, -3, -3}; + for(uint8_t i = 0; i < 3; i++) + { + TEST_ASSERT_EQUAL_DOUBLE(tTruth.arr[i], tRes.arr[i]); + } +} + +static void test_vec3_i32_mult(void) +{ + JUNO_VEC3_I32_T tVec1 = {1, 2, 3}; + JUNO_VEC3_I32_T tRes = Juno_Vec3_i32_Mult(tVec1, 2); + JUNO_VEC3_I32_T tTruth = {2, 4, 6}; + for(uint8_t i = 0; i < 3; i++) + { + TEST_ASSERT_EQUAL_DOUBLE(tTruth.arr[i], tRes.arr[i]); + } +} + +static void test_vec3_i32_dot(void) +{ + JUNO_VEC3_I32_T tVec1 = {1, 2, 3}; + JUNO_VEC3_I32_T tVec2 = {4, 5, 6}; + double tRes = Juno_Vec3_i32_Dot(tVec1, tVec2); + double tTruth = 32; + TEST_ASSERT_EQUAL_DOUBLE(tTruth, tRes); +} + +static void test_vec3_i32_cross(void) +{ + JUNO_VEC3_I32_T tVec1 = {1, 2, 3}; + JUNO_VEC3_I32_T tVec2 = {4, 5, 6}; + JUNO_VEC3_I32_T tRes = Juno_Vec3_i32_Cross(tVec1, tVec2); + JUNO_VEC3_I32_T tTruth = {-3, 6, -3}; + for(uint8_t i = 0; i < 3; i++) + { + TEST_ASSERT_EQUAL_DOUBLE(tTruth.arr[i], tRes.arr[i]); } } int main(void) { UNITY_BEGIN(); - RUN_TEST(test_mat_index); + RUN_TEST(test_vec2_f64_add); + RUN_TEST(test_vec2_f64_sub); + RUN_TEST(test_vec2_f64_mult); + RUN_TEST(test_vec2_f64_dot); + RUN_TEST(test_vec2_f64_cross); + RUN_TEST(test_vec2_i32_add); + RUN_TEST(test_vec2_i32_sub); + RUN_TEST(test_vec2_i32_mult); + RUN_TEST(test_vec2_i32_dot); + RUN_TEST(test_vec2_i32_cross); + RUN_TEST(test_vec3_f64_add); + RUN_TEST(test_vec3_f64_sub); + RUN_TEST(test_vec3_f64_mult); + RUN_TEST(test_vec3_f64_dot); + RUN_TEST(test_vec3_f64_cross); + RUN_TEST(test_vec3_i32_add); + RUN_TEST(test_vec3_i32_sub); + RUN_TEST(test_vec3_i32_mult); + RUN_TEST(test_vec3_i32_dot); + RUN_TEST(test_vec3_i32_cross); return UNITY_END(); }