#ifndef _COMMON_H #define _COMMON_H #define _GNU_SOURCE #include #include #include #include #include #include #include #include #define PROGRAM_NAME "Symulator pól elektromagnetycznych" #define con_printf printf // TODO? #define max2(a, b) ((a) > (b) ? (a) : (b)) #define max3(a, b, c) (max2(max2(a, b), c)) #define min2(a, b) ((a) < (b) ? (a) : (b)) #define min3(a, b, c) (min2(min2(a, b), c)) #define sq(x) ((x)*(x)) char *va(const char *fmt, ...); int64_t get_time(void); typedef float vec_t; typedef vec_t vec2_t[2]; typedef vec_t vec3_t[3]; typedef vec_t vec4_t[4]; typedef vec_t mst2_t[4]; /* mst2_t is a 3x3 scale&translate matrix (only 4 components are needed): * [ dw 0 dx ] * [ 0 dh dy ] * [ 0 0 1 ] */ static inline void v2_copy(vec_t *R, vec_t *A) { R[0] = A[0]; R[1] = A[1]; } static inline void v3_copy(vec_t *R, vec_t *A) { R[0] = A[0]; R[1] = A[1]; R[2] = A[2]; } static inline void v4_copy(vec_t *R, vec_t *A) { R[0] = A[0]; R[1] = A[1]; R[2] = A[2]; R[3] = A[3]; } static inline void v2_set(vec_t *R, vec_t a, vec_t b) { R[0] = a; R[1] = b; } static inline void v3_set(vec_t *R, vec_t a, vec_t b, vec_t c) { R[0] = a; R[1] = b; R[2] = c; } static inline void v2_add(vec_t *R, vec_t *A, vec_t *B) { R[0] = A[0] + B[0]; R[1] = A[1] + B[1]; } static inline void v2_sub(vec_t *R, vec_t *A, vec_t *B) { R[0] = A[0] - B[0]; R[1] = A[1] - B[1]; } static inline void v2_mul(vec_t *R, vec_t *A, vec_t b) { R[0] = A[0] * b; R[1] = A[1] * b; } static inline void v3_add(vec_t *R, vec_t *A, vec_t *B) { R[0] = A[0] + B[0]; R[1] = A[1] + B[1]; R[2] = A[2] + B[2]; } static inline void v3_acc(vec_t *R, vec_t *A) { R[0] += A[0]; R[1] += A[1]; R[2] += A[2]; } static inline void v3_sub(vec_t *R, vec_t *A, vec_t *B) { R[0] = A[0] - B[0]; R[1] = A[1] - B[1]; R[2] = A[2] - B[2]; } static inline void v3_mul(vec_t *R, vec_t *A, vec_t b) { R[0] = A[0] * b; R[1] = A[1] * b; R[2] = A[2] * b; } static inline void mst2_set_identity(mst2_t R) { R[0] = 0; R[1] = 0; R[2] = 1; R[3] = 1; } static inline void mst2_set(mst2_t R, vec_t dx, vec_t dy, vec_t dw, vec_t dh) { R[0] = dx; R[1] = dy; R[2] = dw; R[3] = dh; } static inline void mst2_inv(mst2_t R, mst2_t A) { mst2_t copy = {A[0], A[1], A[2], A[3]}; R[0] = -copy[0] / copy[2]; R[1] = -copy[1] / copy[3]; R[2] = 1 / copy[2]; R[3] = 1 / copy[3]; } static inline void v2_mul_mst2(vec_t *R, vec_t *A, mst2_t M) { R[0] = M[0] + A[0] * M[2]; R[1] = M[1] + A[1] * M[3]; } static inline void v2_div_mst2(vec_t *R, vec_t *A, mst2_t M) { mst2_t inv; mst2_inv(inv, M); v2_mul_mst2(R, A, inv); } // v2_mul_mst2 but without translation static inline void v2_mul_mst2_nt(vec_t *R, vec_t *A, mst2_t M) { R[0] = A[0] * M[2]; R[1] = A[1] * M[3]; } // v2_div_mst2 but without translation static inline void v2_div_mst2_nt(vec_t *R, vec_t *A, mst2_t M) { mst2_t inv; mst2_inv(inv, M); v2_mul_mst2_nt(R, A, inv); } static inline void mst2_dump(mst2_t M) { printf("[%f\t%f\t%f]\n", M[2], 0.0, M[0]); printf("[%f\t%f\t%f]\n", 0.0, M[3], M[1]); printf("[%f\t%f\t%f]\n", 0.0, 0.0, 1.0); } static inline float remap(float x, float a0, float b0, float a1, float b1) { return (x - a0) * (b1 - a1) / (b0 - a0) + a1; } #define DEG2RAD(x) ((x) / (180.0f / M_PI)) #endif // _COMMON_H