Add line-AABB collision check function
parent
c27fa632a2
commit
7767b38221
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue