summaryrefslogtreecommitdiffstatsci
path: root/src/vectors.h
blob: a84a23827549aaa66b6886d01fbfa39ceb2149e7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// Copyright (c) 2018-2026 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
//
// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
#ifndef VKVG_VECTORS_H
#define VKVG_VECTORS_H

#include "vkvg_internal.h"

typedef struct {
    float x;
    float y;
} vec2;

static const vec2 vec2_unit_x = {1.f, 0};
static const vec2 vec2_unit_y = {0, 1.f};

typedef struct {
    double x;
    double y;
} vec2d;

/*const vec2d vec2d_unit_x = {1.0,0};
const vec2d vec2d_unit_y = {0,1.0};*/

typedef struct {
    float x;
    float y;
    float z;
} vec3;

typedef struct {
    union {
        float x;
        float r;
        float xMin;
    };
    union {
        float y;
        float g;
        float yMin;
    };
    union {
        float z;
        float width;
        float b;
        float xMax;
    };
    union {
        float w;
        float height;
        float a;
        float yMax;
    };

} vec4;

typedef struct {
    uint16_t x;
    uint16_t y;
    uint16_t z;
    uint16_t w;
} vec4i16;

typedef struct {
    int16_t x;
    int16_t y;
} vec2i16;

typedef struct {
    vec2 row0;
    vec2 row1;
} mat2;

// compute length of float vector 2d
vkvg_inline float vec2_length(vec2 v) { return sqrtf(v.x * v.x + v.y * v.y); }
// compute normal direction vector from line defined by 2 points in double precision
vkvg_inline vec2d vec2d_line_norm(vec2d a, vec2d b) {
    vec2d  d  = {b.x - a.x, b.y - a.y};
    double md = sqrt(d.x * d.x + d.y * d.y);
    d.x /= md;
    d.y /= md;
    return d;
}
// compute normal direction vector from line defined by 2 points
vkvg_inline vec2 vec2_line_norm(vec2 a, vec2 b) {
    vec2  d  = {b.x - a.x, b.y - a.y};
    float md = sqrtf(d.x * d.x + d.y * d.y);
    d.x /= md;
    d.y /= md;
    return d;
}
// compute sum of two double precision vectors
vkvg_inline vec2d vec2d_add(vec2d a, vec2d b) { return (vec2d){a.x + b.x, a.y + b.y}; }
// compute subbstraction of two double precision vectors
vkvg_inline vec2d vec2d_sub(vec2d a, vec2d b) { return (vec2d){a.x - b.x, a.y - b.y}; }
// multiply 2d vector by scalar
vkvg_inline vec2d vec2d_mult_s(vec2d a, double m) { return (vec2d){a.x * m, a.y * m}; }
vkvg_inline vec2d vec2d_div_s(vec2d a, double m) { return (vec2d){a.x / m, a.y / m}; }
// compute length of double vector 2d
vkvg_inline double vec2d_length(vec2d v) { return sqrt(v.x * v.x + v.y * v.y); }
// normalize double vector
vkvg_inline vec2d vec2d_norm(vec2d a) {
    double m = sqrt(a.x * a.x + a.y * a.y);
    return (vec2d){a.x / m, a.y / m};
}
// compute perpendicular vector
vkvg_inline vec2d vec2d_perp(vec2d a) { return (vec2d){a.y, -a.x}; }
vkvg_inline bool  vec2d_isnan(vec2d v) { return (bool)(isnan(v.x) || isnan(v.y)); }

// test equality of two single precision vectors
vkvg_inline bool vec2_equ(vec2 a, vec2 b) { return (EQUF(a.x, b.x) & EQUF(a.y, b.y)); }
// compute sum of two single precision vectors
vkvg_inline vec2 vec2_add(vec2 a, vec2 b) { return (vec2){a.x + b.x, a.y + b.y}; }
// compute subbstraction of two single precision vectors
vkvg_inline vec2 vec2_sub(vec2 a, vec2 b) { return (vec2){a.x - b.x, a.y - b.y}; }
// multiply 2d vector by scalar
vkvg_inline vec2 vec2_mult_s(vec2 a, float m) { return (vec2){a.x * m, a.y * m}; }
// devide 2d vector by scalar
vkvg_inline vec2 vec2_div_s(vec2 a, float m) { return (vec2){a.x / m, a.y / m}; }
// normalize float vector
vkvg_inline vec2 vec2_norm(vec2 a) {
    float m = sqrtf(a.x * a.x + a.y * a.y);
    return (vec2){a.x / m, a.y / m};
}
// compute perpendicular vector
vkvg_inline vec2 vec2_perp(vec2 a) { return (vec2){a.y, -a.x}; }
// compute opposite of single precision vector
vkvg_inline void vec2_inv(vec2* v) {
    v->x = -v->x;
    v->y = -v->y;
}
// test if one component of float vector is nan
vkvg_inline bool vec2_isnan(vec2 v) { return (bool)(isnan(v.x) || isnan(v.y)); }
// test if one component of double vector is nan
vkvg_inline float vec2_dot(vec2 a, vec2 b) { return (a.x * b.x) + (a.y * b.y); }
vkvg_inline float vec2_det(vec2 a, vec2 b) { return a.x * b.y - a.y * b.x; }
vkvg_inline float vec2_slope(vec2 a, vec2 b) { return (b.y - a.y) / (b.x - a.x); }

// convert double precision vector to single precision
vkvg_inline vec2 vec2d_to_vec2(vec2d vd) { return (vec2){(float)vd.x, (float)vd.y}; }
vkvg_inline bool vec4_equ(vec4 a, vec4 b) {
    return (EQUF(a.x, b.x) & EQUF(a.y, b.y) & EQUF(a.z, b.z) & EQUF(a.w, b.w));
}
vkvg_inline vec2 mat2_mult_vec2(mat2 m, vec2 v) {
    return (vec2){(m.row0.x * v.x) + (m.row0.y * v.y), (m.row1.x * v.x) + (m.row1.y * v.y)};
}
vkvg_inline float mat2_det(mat2* m) { return (m->row0.x * m->row1.y) - (m->row0.y * m->row1.y); }

#endif