1/*
2 * Copyright 2017, Data61
3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
4 * ABN 41 687 119 230.
5 *
6 * This software may be distributed and modified according to the terms of
7 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
8 * See "LICENSE_BSD2.txt" for details.
9 *
10 * @TAG(DATA61_BSD)
11 */
12
13/* A simple vector math library
14 *
15 * This file provides the macro VECTOR_2D_DEFINITION(name, T)
16 * which expands into a vector math library with vectors represented
17 * by tuples of type "T", and generated symbols (type and function
18 * names) prefixed with "name".
19 *
20 * Also provided in this file are 2 default implementations:
21 * vector_2d_long_int (long int)
22 * vector_2d_double (double)
23 *
24 * e.g.
25 * VECTOR_2D_DEFINITION(vector_2d_int, long int)
26 * would expand to
27 *
28 * typedef struct {
29 *     long int x;
30 *     long int y;
31 * } vector_2d_int_t;
32 * static inline void vector_2d_int_add(vector_2d_int_t *a, vector_2d_int_t *b, vector_2d_int_t *result) {
33 *     result->x = a->x + b->x;
34 *     result->y = a->y + b->y;
35 * }
36 * static inline void vector_2d_int_subtract(vector_2d_int_t *a, vector_2d_int_t *b, vector_2d_int_t *result) {
37 * ...etc
38 */
39
40#pragma once
41
42#include <math.h>
43
44#define VECTOR_2D_DEFINITION(name, T) \
45typedef struct {        \
46    T x;                \
47    T y;                \
48} name##_t;             \
49static inline void name##_add(name##_t *a, name##_t *b, name##_t *result) {\
50    result->x = a->x + b->x;\
51    result->y = a->y + b->y;\
52}\
53static inline void name##_subtract(name##_t *a, name##_t *b, name##_t *result) {\
54    result->x = a->x - b->x;\
55    result->y = a->y - b->y;\
56}\
57static inline void name##_scalar_multiply(name##_t *a, T scalar, name##_t *result) {\
58    result->x = a->x * scalar;\
59    result->y = a->y * scalar;\
60}\
61static inline double name##_length(name##_t *a) {\
62    return sqrt(a->x*a->x + a->y*a->y);\
63}\
64static inline double name##_angle(name##_t *a) {\
65    return atan2(a->y, a->x);\
66}\
67static inline void name##_from_cartesian(T x, T y, name##_t *result) {\
68    result->x = x;\
69    result->y = y;\
70}\
71static inline void name##_from_polar(double length, double radians, name##_t  *result) {\
72    result->x = length * cos(radians);\
73    result->y = length * sin(radians);\
74}
75
76/* Default implementations for long int and double */
77VECTOR_2D_DEFINITION(vector_2d_long_int, long int)
78VECTOR_2D_DEFINITION(vector_2d_double, double)
79