#ifndef GEOMETRY_H #define GEOMETRY_H #include static inline double max(const double a, const double b) { return a > b ? a : b; } static inline double min(const double a, const double b) { return a < b ? a : b; } typedef struct vector {double x; double y;} vector; static inline vector scalar(const double k) { return (vector){.x = k, .y = k}; } static inline vector add(const vector u, const vector v) { return (vector){.x = u.x + v.x, .y = u.y + v.y}; } static inline vector subtract(const vector u, const vector v) { return (vector){.x = v.x - u.x, .y = v.y - u.y}; } static inline vector multiply(const vector u, const vector v) { return (vector){.x = u.x * v.x, .y = u.y * v.y}; } static inline vector divide(const vector u, const vector v) { return (vector){.x = u.x / v.x, .y = u.y / v.y}; } #define radians(DEGREES) (((DEGREES) / 180.0) * M_PI) static inline double cosine(const double angle) { return cos(radians(angle)); } static inline double sine(const double angle) { return sin(radians(angle)); } static inline double tangent(const double angle) { return tan(radians(angle)); } #undef radians typedef struct polar { double distance; double angle; } polar; static inline vector cartesian(const polar coordinate) { return (vector){ .x = coordinate.distance * cosine(coordinate.angle), .y = coordinate.distance * sine(coordinate.angle), }; } static inline polar move(const polar turtle, const polar direction) { return (polar){ .distance = direction.distance, .angle = remainder(turtle.angle + direction.angle, 360.0) }; } typedef struct matrix { double a; double b; double c; double d; double tx; double ty; } matrix; static inline matrix identity(void) { return (matrix){1.0, 0.0, 0.0, 1.0, 0.0, 0.0}; } static inline matrix concatenate(const matrix A, const matrix B) { return (matrix){ (A.a * B.a) + (A.b * B.c), (A.a * B.b) + (A.b * B.d), (A.c * B.a) + (A.d * B.c), (A.c * B.b) + (A.d * B.d), (A.tx * B.a) + (A.ty * B.c) + B.tx, (A.tx * B.b) + (A.ty * B.d) + B.ty }; } static inline matrix rotate(const double angle, const matrix A) { return concatenate((matrix){ cosine(angle), sine(angle), -sine(angle), cosine(angle), 0.0, 0.0 }, A); } static inline matrix scale(const vector S, const matrix A) { return concatenate((matrix){S.x, 0.0, 0.0, S.y, 0.0, 0.0}, A); } static inline matrix translate(const vector t, const matrix A) { return concatenate((matrix){1.0, 0.0, 0.0, 1.0, t.x, t.y}, A); } static inline vector transform(const vector v, const matrix A) { return (vector){ .x = (A.a * v.x) + (A.c * v.y) + A.tx, .y = (A.b * v.x) + (A.d * v.y) + A.ty }; } #endif