]> git.lizzy.rs Git - nothing.git/blob - src/math/point.c
(#658) Introduce vec_sub
[nothing.git] / src / math / point.c
1 #include "system/stacktrace.h"
2 #include <math.h>
3
4 #include "point.h"
5
6 Vec vec(float x, float y)
7 {
8     Vec result = {
9         .x = x,
10         .y = y
11     };
12     return result;
13 }
14
15 Vec vec_from_polar(float arg, float mag)
16 {
17     return vec_scala_mult(
18         vec(cosf(arg), sinf(arg)),
19         mag);
20 }
21
22 Vec vec_from_ps(Point p1, Point p2)
23 {
24     Vec result = {
25         .x = p2.x - p1.x,
26         .y = p2.y - p1.y
27     };
28     return result;
29 }
30
31 float vec_arg(Vec v)
32 {
33     return atan2f(v.y, v.x);
34 }
35
36 float vec_mag(Vec v)
37 {
38     return sqrtf(v.x * v.x + v.y * v.y);
39 }
40
41 Vec vec_sum(Vec v1, Vec v2)
42 {
43     Vec result = {
44         .x = v1.x + v2.x,
45         .y = v1.y + v2.y
46     };
47     return result;
48 }
49
50 Vec vec_sub(Vec v1, Vec v2)
51 {
52     Vec result = {
53         .x = v1.x - v2.x,
54         .y = v1.y - v2.y
55     };
56     return result;
57 }
58
59 Vec vec_neg(Vec v)
60 {
61     Vec result = {
62         .x = -v.x,
63         .y = -v.y
64     };
65
66     return result;
67 }
68
69 float vec_length(Vec v)
70 {
71     return sqrtf(v.x * v.x + v.y * v.y);
72 }
73
74 void vec_add(Vec *v1, Vec v2)
75 {
76     v1->x += v2.x;
77     v1->y += v2.y;
78 }
79
80 Vec vec_scala_mult(Vec v, float scalar)
81 {
82     Vec result = {
83         .x = v.x * scalar,
84         .y = v.y * scalar
85     };
86     return result;
87 }
88
89 Vec vec_entry_mult(Vec v1, Vec v2)
90 {
91     Vec result = {
92         .x = v1.x * v2.x,
93         .y = v1.y * v2.y
94     };
95
96     return result;
97 }
98
99 Vec vec_entry_div(Vec v1, Vec v2)
100 {
101     Vec result = {
102         .x = v1.x / v2.x,
103         .y = v1.y / v2.y
104     };
105
106     return result;
107 }
108
109 float rad_to_deg(float a)
110 {
111     return 180 / PI * a;
112 }
113
114 Point point_mat3x3_product(Point p, mat3x3 m)
115 {
116     /* Convert p to Homogeneous coordinates */
117     const float homo_p[3] = {p.x, p.y, 1};
118
119     /* Transform p with matrix m */
120     const float trans_p[3] = {
121         homo_p[0] * m.M[0][0] + homo_p[1] * m.M[0][1] + homo_p[2] * m.M[0][2],
122         homo_p[0] * m.M[1][0] + homo_p[1] * m.M[1][1] + homo_p[2] * m.M[1][2],
123         homo_p[0] * m.M[2][0] + homo_p[1] * m.M[2][1] + homo_p[2] * m.M[2][2]
124     };
125
126     /* Convert p back to Cartesian coordinates */
127     const Point result_p = {
128         .x = trans_p[0] / trans_p[2],
129         .y = trans_p[1] / trans_p[2]
130     };
131
132     return result_p;
133 }
134
135 Vec vec_norm(Vec v)
136 {
137     // TODO(#657): math/point/vec_norm: using vec_length is too expensive
138     //   It involves multiplication and sqrt. We can just check if its components are close to 0.0f.
139
140     const float l = vec_length(v);
141
142     if (l < 1e-6) {
143         return vec(0.0f, 0.0f);
144     }
145
146     return vec(v.x / l, v.y / l);
147 }
148
149 float vec_sqr_norm(Vec v)
150 {
151     return v.x * v.x + v.y * v.y;
152 }