Posted By: 3run
Rect vs. circle intersection test - 01/08/18 11:38
Hi there!
Thx to this article and MasterQ32's idea, I was able to get rectangular vs circle collision / intersection test.
I'm going to use this for detecting if character was smashed with a door, elevator or any other moving props on the level.
Here it is (also contains bbox drawing helper functions):
Best regards!
Thx to this article and MasterQ32's idea, I was able to get rectangular vs circle collision / intersection test.
I'm going to use this for detecting if character was smashed with a door, elevator or any other moving props on the level.
Here it is (also contains bbox drawing helper functions):
Code:
#define PRAGMA_POINTER void draw_line_3d(VECTOR *s, VECTOR *e, COLOR *c, var a){ draw_line3d(&s->x, NULL, a); draw_line3d(&s->x, c, a); draw_line3d(&e->x, c, a); } void draw_bbox_3d(ENTITY *ent, COLOR *c, var a){ VECTOR pos[8]; vec_set(&pos[0], vector(ent->min_x, ent->min_y, ent->min_z)); vec_rotate(&pos[0], &ent->pan); vec_add(&pos[0], &ent->x); vec_set(&pos[1], vector(ent->min_x, ent->max_y, ent->min_z)); vec_rotate(&pos[1], &ent->pan); vec_add(&pos[1], &ent->x); vec_set(&pos[2], vector(ent->max_x, ent->max_y, ent->min_z)); vec_rotate(&pos[2], &ent->pan); vec_add(&pos[2], &ent->x); vec_set(&pos[3], vector(ent->max_x, ent->min_y, ent->min_z)); vec_rotate(&pos[3], &ent->pan); vec_add(&pos[3], &ent->x); vec_set(&pos[4], vector(ent->min_x, ent->min_y, ent->max_z)); vec_rotate(&pos[4], &ent->pan); vec_add(&pos[4], &ent->x); vec_set(&pos[5], vector(ent->min_x, ent->max_y, ent->max_z)); vec_rotate(&pos[5], &ent->pan); vec_add(&pos[5], &ent->x); vec_set(&pos[6], vector(ent->max_x, ent->max_y, ent->max_z)); vec_rotate(&pos[6], &ent->pan); vec_add(&pos[6], &ent->x); vec_set(&pos[7], vector(ent->max_x, ent->min_y, ent->max_z)); vec_rotate(&pos[7], &ent->pan); vec_add(&pos[7], &ent->x); draw_line_3d(&pos[0], &pos[1], c, a); draw_line_3d(&pos[1], &pos[2], c, a); draw_line_3d(&pos[2], &pos[3], c, a); draw_line_3d(&pos[3], &pos[0], c, a); draw_line_3d(&pos[0], &pos[4], c, a); draw_line_3d(&pos[1], &pos[5], c, a); draw_line_3d(&pos[2], &pos[6], c, a); draw_line_3d(&pos[3], &pos[7], c, a); draw_line_3d(&pos[4], &pos[5], c, a); draw_line_3d(&pos[5], &pos[6], c, a); draw_line_3d(&pos[6], &pos[7], c, a); draw_line_3d(&pos[7], &pos[4], c, a); } function rect_vs_circle_check(ENTITY *rect, ENTITY* circle){ VECTOR pos; vec_diff(&pos, &circle->x, &rect->x); vec_rotateback(&pos, &rect->pan); vec_add(&pos, &rect->x); var delta_x = pos.x - maxv(rect->x + rect->min_x, minv(pos.x, rect->x + rect->max_x)); var delta_y = pos.y - maxv(rect->y + rect->min_y, minv(pos.y, rect->y + rect->max_y)); var delta_z = pos.z - maxv(rect->z + rect->min_z, minv(pos.z, rect->z + rect->max_z)); var rect_delta = (delta_x * delta_x) + (delta_y * delta_y) + (delta_z * delta_z); if(rect_delta < (circle->max_x * circle->max_x)){ return(1); } return(0); } void main(){ warn_level = 6; fps_max = 60; level_load(""); wait(3); mouse_mode = 4; sun_light = 0; camera->arc = 5; set(camera, ISOMETRIC); vec_set(&camera->x, vector(0, 0, 128)); vec_set(&camera->pan, vector(0, -90, 0)); ENTITY *rect = ent_create(CUBE_MDL, vector(0, 0, 0), NULL); set(rect, TRANSLUCENT | LIGHT | UNLIT); vec_set(&rect->scale_x, vector(1, 0.5, 1)); c_setminmax(rect); ENTITY *circle = ent_create(SPHERE_MDL, vector(0, 16, 0), NULL); set(circle, TRANSLUCENT | LIGHT | UNLIT); vec_set(&circle->scale_x, vector(0.5, 0.5, 0.5)); c_setminmax(circle); while(rect){ VECTOR temp; vec_set(&temp, vector(mouse_pos.x, mouse_pos.y, 128)); vec_for_screen(&temp, camera); vec_set(&circle->x, &temp); rect->pan += 5 * time_step; vec_set(&rect->blue, COLOR_GREEN); vec_set(&circle->blue, COLOR_GREEN); draw_bbox_3d(rect, COLOR_WHITE, 100); draw_bbox_3d(circle, COLOR_WHITE, 100); if(rect_vs_circle_check(rect, circle) == 1){ vec_set(&rect->blue, COLOR_RED); vec_set(&circle->blue, COLOR_RED); } if(mouse_left){ time_factor = 0.5; } else{ time_factor = 1; } wait(1); } }
Best regards!