]> git.lizzy.rs Git - nothing.git/blob - src/math/rect.h
Wire up pp to level loop
[nothing.git] / src / math / rect.h
1 #ifndef RECT_H_
2 #define RECT_H_
3
4 #include <SDL.h>
5 #include <math.h>
6 #include <stdbool.h>
7
8 #include "math/vec.h"
9 #include "system/stacktrace.h"
10
11 typedef enum Rect_side {
12     RECT_SIDE_TOP = 0,
13     RECT_SIDE_LEFT,
14     RECT_SIDE_BOTTOM,
15     RECT_SIDE_RIGHT,
16
17     RECT_SIDE_N
18 } Rect_side;
19
20 typedef struct Rect {
21     float x, y, w, h;
22 } Rect;
23
24 typedef struct Line {
25     Vec2f p1;
26     Vec2f p2;
27 } Line;
28
29 Rect horizontal_thicc_line(float x1, float x2, float y, float thiccness);
30 Rect vertical_thicc_line(float y1, float y2, float x, float thiccness);
31
32 Rect rect(float x, float y, float w, float h);
33 Rect rect_from_vecs(Vec2f position, Vec2f size);
34 Rect rect_from_points(Vec2f p1, Vec2f p2);
35 Rect rect_from_sdl(const SDL_Rect *rect);
36
37 Rect rects_overlap_area(Rect rect1, Rect rect2);
38
39 static inline
40 Rect rect_boundary2(Rect rect1, Rect rect2)
41 {
42     return rect_from_points(
43         vec(
44             fminf(rect1.x, rect2.x),
45             fminf(rect1.y, rect2.y)),
46         vec(
47             fmaxf(rect1.x + rect1.w, rect2.x + rect2.w),
48             fmaxf(rect1.y + rect1.h, rect2.y + rect2.h)));
49 }
50
51 static inline Vec2f rect_position(Rect rect)
52 {
53     return vec(rect.x, rect.y);
54 }
55
56 static inline Vec2f rect_position2(Rect rect)
57 {
58     return vec(rect.x + rect.w, rect.y + rect.h);
59 }
60
61 static inline Rect rect_pad(Rect rect, float d)
62 {
63     rect.x -= d;
64     rect.y -= d;
65     rect.w += d * 2.0f;
66     rect.h += d * 2.0f;
67     return rect;
68 }
69
70 int rect_contains_point(Rect rect, Vec2f p);
71
72 int rects_overlap(Rect rect1, Rect rect2);
73
74 void rect_object_impact(Rect object,
75                         Rect obstacle,
76                         int *sides);
77
78 Line rect_side(Rect rect, Rect_side side);
79
80 Rect rect_from_point(Vec2f p, float w, float h);
81
82 float line_length(Line line);
83
84 SDL_Rect rect_for_sdl(Rect rect);
85
86 Vec2f rect_center(Rect rect);
87
88 Vec2f rect_snap(Rect pivot, Rect *rect);
89 Vec2f rect_impulse(Rect *r1, Rect *r2);
90
91 static inline
92 float rect_side_distance(Rect rect, Vec2f point, Rect_side side)
93 {
94     switch (side) {
95     case RECT_SIDE_LEFT: {
96         return fabsf(rect.x - point.x);
97     } break;
98
99     case RECT_SIDE_RIGHT: {
100         return fabsf((rect.x + rect.w) - point.x);
101     } break;
102
103     case RECT_SIDE_TOP: {
104         return fabsf(rect.y - point.y);
105     } break;
106
107     case RECT_SIDE_BOTTOM: {
108         return fabsf((rect.y + rect.h) - point.y);
109     } break;
110
111     case RECT_SIDE_N: {
112         trace_assert(0 && "Incorrect rect side");
113     } break;
114     }
115
116     return 0;
117 }
118
119 static inline
120 int segment_overlap(Vec2f a, Vec2f b)
121 {
122     if (a.x > a.y) {
123         float t = a.x;
124         a.x = a.y;
125         a.y = t;
126     }
127
128     if (b.x > b.y) {
129         float t = b.x;
130         b.x = b.y;
131         b.y = t;
132     }
133
134     return a.y >= b.x && b.y >= a.x;
135 }
136
137 static inline
138 int snap_var(float *x,        // the value we are snapping
139              float y,         // the target we are snapping x to
140              float xo,        // x offset
141              float yo,        // y offset
142              float st)        // snap threshold
143 {
144     if (fabsf((*x + xo) - (y + yo)) < st) {
145         *x = y + yo - xo;
146         return true;
147     }
148     return false;
149 }
150
151 static inline
152 int snap_var2seg(float *x, float y,
153                float xo, float yo,
154                float st)
155 {
156     // note: do not use || because we do *not* want short-circuiting, so use |.
157     return snap_var(x, y, xo,  0, st) | snap_var(x, y, xo, yo, st);
158 }
159
160 static inline
161 void snap_seg2seg(float *x, float y, float xo, float yo, float st)
162 {
163     snap_var(x, y,  0,  0, st);
164     snap_var(x, y,  0, yo, st);
165     snap_var(x, y, xo,  0, st);
166     snap_var(x, y, xo, yo, st);
167 }
168
169 #endif  // RECT_H_