6 #include "system/stacktrace.h"
8 Rect rect(float x, float y, float w, float h)
20 Rect rect_from_vecs(Vec2f position, Vec2f size)
22 return rect(position.x, position.y, size.x, size.y);
25 Rect rect_from_points(Vec2f p1, Vec2f p2)
27 return rect_from_vecs(
28 vec(fminf(p1.x, p2.x),
30 vec(fabsf(p1.x - p2.x),
34 Rect rect_from_sdl(const SDL_Rect *rect)
46 Rect rects_overlap_area(Rect rect1, Rect rect2)
48 float x1 = fmaxf(rect1.x, rect2.x);
49 float y1 = fmaxf(rect1.y, rect2.y);
50 float x2 = fminf(rect1.x + rect1.w, rect2.x + rect2.w);
51 float y2 = fminf(rect1.y + rect1.h, rect2.y + rect2.h);
56 .w = fmaxf(0.0f, x2 - x1),
57 .h = fmaxf(0.0f, y2 - y1)
62 int rects_overlap(Rect rect1, Rect rect2)
64 return rect1.x + rect1.w > rect2.x
65 && rect2.x + rect2.w > rect1.x
66 && rect2.y + rect2.h > rect1.y
67 && rect1.y + rect1.h > rect2.y;
70 float line_length(Line line)
72 float dx = line.p1.x - line.p2.x;
73 float dy = line.p1.y - line.p2.y;
74 return sqrtf(dx * dx + dy * dy);
77 void rect_object_impact(Rect object, Rect obstacle, int *sides)
81 Rect int_area = rects_overlap_area(object, obstacle);
83 if (int_area.w * int_area.h > 0.0f) {
84 for (int side = 0; side < RECT_SIDE_N; ++side) {
85 Line object_side = rect_side(object, side);
86 Line int_side = rect_side(int_area, side);
88 if (line_length(int_side) > 10.0f) {
89 sides[side] = sides[side] ||
90 (fabs(object_side.p1.x - object_side.p2.x) < 1e-6
91 && fabs(object_side.p1.x - int_side.p1.x) < 1e-6
92 && fabs(object_side.p1.x - int_side.p2.x) < 1e-6)
93 || (fabs(object_side.p1.y - object_side.p2.y) < 1e-6
94 && fabs(object_side.p1.y - int_side.p1.y) < 1e-6
95 && fabs(object_side.p1.y - int_side.p2.y) < 1e-6);
101 Line rect_side(Rect rect, Rect_side side)
103 const float x1 = rect.x;
104 const float y1 = rect.y;
105 const float x2 = rect.x + rect.w;
106 const float y2 = rect.y + rect.h;
117 case RECT_SIDE_RIGHT:
129 case RECT_SIDE_BOTTOM:
141 Rect rect_from_point(Vec2f p, float w, float h)
153 int rect_contains_point(Rect rect, Vec2f p)
155 return rect.x <= p.x && p.x <= rect.x + rect.w
156 && rect.y <= p.y && p.y <= rect.y + rect.h;
159 SDL_Rect rect_for_sdl(Rect rect)
161 const SDL_Rect result = {
162 .x = (int) roundf(rect.x),
163 .y = (int) roundf(rect.y),
164 .w = (int) roundf(rect.w),
165 .h = (int) roundf(rect.h)
171 Vec2f rect_center(Rect rect)
173 return vec(rect.x + rect.w * 0.5f,
174 rect.y + rect.h * 0.5f);
177 Vec2f rect_snap(Rect pivot, Rect *r)
179 const Vec2f pivot_c = rect_center(pivot);
180 const Vec2f r_c = rect_center(*r);
182 const float sx = r_c.x < pivot_c.x ? -1.0f : 1.0f;
183 const float sy = r_c.y < pivot_c.y ? -1.0f : 1.0f;
184 const float cx = pivot_c.x + sx * (pivot.w + r->w) * 0.5f;
185 const float cy = pivot_c.y + sy * (pivot.h + r->h) * 0.5f;
187 if (fabsf(cx - r_c.x) < fabsf(cy - r_c.y)) {
188 *r = rect(cx - r->w * 0.5f, r->y, r->w, r->h);
189 return vec(0.0f, 1.0f);
191 *r = rect(r->x, cy - r->h * 0.5f, r->w, r->h);
192 return vec(1.0f, 0.0f);
196 Vec2f rect_impulse(Rect *r1, Rect *r2)
201 const Vec2f c1 = rect_center(*r1);
202 const Vec2f c2 = rect_center(*r2);
203 const Rect overlap = rects_overlap_area(*r1, *r2);
204 const Vec2f overlap_center = rect_center(overlap);
205 const float dx = overlap_center.x;
206 const float dy = overlap_center.y;
207 const float sx = c1.x < c2.x ? 1.0f : -1.0f;
208 const float sy = c1.y < c2.y ? 1.0f : -1.0f;
209 const float cx1 = dx - sx * r1->w * 0.5f;
210 const float cy1 = dy - sy * r1->h * 0.5f;
211 const float cx2 = dx + sx * r2->w * 0.5f;
212 const float cy2 = dy + sy * r2->h * 0.5f;
214 if (vec_sqr_norm(vec_sum(vec(cx1, c1.y), vec_neg(vec(cx2, c2.y)))) <
215 vec_sqr_norm(vec_sum(vec(c1.x, cy1), vec_neg(vec(c2.x, cy2))))) {
216 r1->x = cx1 - r1->w * 0.5f;
217 r2->x = cx2 - r2->w * 0.5f;
218 return vec(0.0f, 1.0f);
220 r1->y = cy1 - r1->h * 0.5f;
221 r2->y = cy2 - r2->h * 0.5f;
222 return vec(1.0f, 0.0f);
226 Rect horizontal_thicc_line(float x1, float x2, float y, float thiccness)
235 x1 - thiccness * 0.5f,
236 y - thiccness * 0.5f,
241 Rect vertical_thicc_line(float y1, float y2, float x, float thiccness)
250 x - thiccness * 0.5f,
251 y1 - thiccness * 0.5f,
253 y2 - y1 + thiccness);