Add line-AABB collision check function

scene_man
En Yi 2023-06-20 22:23:32 +08:00
parent c27fa632a2
commit 7767b38221
3 changed files with 82 additions and 0 deletions

View File

@ -49,3 +49,45 @@ bool point_in_AABB(Vector2 point, Rectangle box)
&& point.y < box.y + box.height
);
}
bool line_in_AABB(Vector2 p1, Vector2 p2, Rectangle box)
{
float A = p2.y - p1.y;
float B = p1.x - p2.x;
float C = (p2.x * p1.y) - (p1.x * p2.y);
Vector2 corners[3] =
{
{box.x + box.width - 1, box.y},
{box.x + box.width - 1, box.y + box.height - 1},
{box.x, box.y + box.height - 1},
};
float F = (A * box.x + B * box.y + C);
uint8_t last_mode = 0;
if (fabs(F) < 1e-3)
{
last_mode = 0;
}
else
{
last_mode = (F > 0) ? 1 : 2;
}
for (uint8_t i = 0; i < 3; ++i)
{
F = (A * corners[i].x + B * corners[i].y + C);
uint8_t mode = 0;
if (fabs(F) < 1e-3)
{
mode = 0;
}
else
{
mode = (F > 0) ? 1 : 2;
}
if (mode != last_mode) return true;
last_mode = mode;
}
return false;
}

View File

@ -6,4 +6,5 @@
uint8_t find_1D_overlap(Vector2 l1, Vector2 l2, float* overlap);
uint8_t find_AABB_overlap(const Vector2 tl1, const Vector2 sz1, const Vector2 tl2, const Vector2 sz2, Vector2* overlap);
bool point_in_AABB(Vector2 point, Rectangle box);
bool line_in_AABB(Vector2 p1, Vector2 p2, Rectangle box);
#endif // __AABB_H

View File

@ -6,6 +6,44 @@
#include <setjmp.h>
#include <cmocka.h>
static void test_line_AABB(void **state)
{
(void) state;
Vector2 p1 = {0, 0};
Vector2 p2 = {20, 20};
Rectangle box = {5, 0, 10, 20};
assert_true(line_in_AABB(p1, p2, box));
p1.y = 20;
assert_false(line_in_AABB(p1, p2, box));
p1.y = 19;
p2 = (Vector2){19, 19};
assert_true(line_in_AABB(p1, p2, box));
p1.y = 0;
p2.y = 0;
assert_true(line_in_AABB(p1, p2, box));
p1 = (Vector2){5, 0};
p2 = (Vector2){5, 10};
assert_true(line_in_AABB(p1, p2, box));
p1 = (Vector2){14, 0};
p2 = (Vector2){14, 10};
assert_true(line_in_AABB(p1, p2, box));
p1 = (Vector2){15, 0};
p2 = (Vector2){15, 10};
assert_false(line_in_AABB(p1, p2, box));
p1 = (Vector2){0, 30};
p2 = (Vector2){6, 35};
assert_false(line_in_AABB(p1, p2, box));
}
static void test_point_AABB(void **state)
{
(void) state;
@ -86,6 +124,7 @@ int main(void)
cmocka_unit_test(test_1D_overlap),
cmocka_unit_test(test_AABB_overlap),
cmocka_unit_test(test_point_AABB),
cmocka_unit_test(test_line_AABB),
};
return cmocka_run_group_tests(tests, NULL, NULL);