Useful and quick Collision detection between simple shapes
Posted: Fri May 24, 2013 9:16 pm
First of all,
Hello everyone
Anyways, recently I've been a bit bored when doing my practicum so I started making functions in C++ then decided to make them to C of GE.. though I still have a some work to do..
So put this in your global:
In the next few post I will provide a GED example and how to use this... I guess for now look at poorly written code?
Hello everyone
Anyways, recently I've been a bit bored when doing my practicum so I started making functions in C++ then decided to make them to C of GE.. though I still have a some work to do..
So put this in your global:
- Code: Select all
#define bool int
#define true 1
#define false 0
double M_Clamp(double value, double min_range, double max_range)
{
return min(max_range, max(value, min_range));
}
double M_Square(double value)
{
return value * value;
}
double M_1Distance(double a, double b)
{
double answer = a-b;
//Iz answer < 0?
//if so return -answer
//otherwise return answer
return answer < 0?-answer:answer;
}
double M_2Distance(double x1, double y1, double x2, double y2)
{
return sqrt(M_Square(x2-x1) + M_Square(y2-y1));
}
double M_2Distance_Squared(double x1, double y1, double x2, double y2)
{
return (M_Square(x2-x1) + M_Square(y2-y1));
}
double Col_Value_Range(double Value, double Range_Start, double Range_End, bool Include_End, bool Include_Start)
{
if (Value < Range_Start || (Value == Range_Start && !Include_Start))
return -1;//Value is to the "left", or is lesser
if (Value > Range_End || (Value == Range_End && !Include_End))
return -2;//Value is to the "right", or is greater
return Value - Range_Start; //Return the offset of the collision in refference to the range
}
double Col_Range_Range(double Start1, double End1, double Start2, double End2, bool Include_End1, bool Include_Start1, bool Include_End2, bool Include_Start2)
{
if (End1 < Start2 || (End1 == Start2 && (!Include_End1 || !Include_Start2)))
return -1;//Range is to the "left", or is lesser
if (Start1 > End2 || (Start1 == End2 && (!Include_Start1 || !Include_End2)))
return -2;//Range is to the "right", or is lesser
return End1 - Start2; //Return the offset of the collision in refference to the second range
}
bool Col_Point_Box(double x1, double y1, double x2, double y2, double width2, double height2)
{
//double bx1_ax = x1;
//double bx1_bx = x1;
//double bx1_ay = y1;
//double bx1_by = y1;
double bx2_ax = x2 - width2*0.5;
double bx2_bx = x2 + width2*0.5;
double bx2_ay = y2 - height2*0.5;
double bx2_by = y2 + height2*0.5;
if ( Col_Value_Range( x1, bx2_ax, bx2_bx, true, true) >= 0 && Col_Value_Range( y1, bx2_ay, bx2_by, true, true) >= 0)
return true;
return false;
}
bool Col_Box_Box(double x1, double y1, double width1, double height1, double x2, double y2, double width2, double height2)
{
double bx1_ax = x1 - width1*0.5;
double bx1_bx = x1 + width1*0.5;
double bx1_ay = y1 - height1*0.5;
double bx1_by = y1 + height1*0.5;
double bx2_ax = x2 - width2*0.5;
double bx2_bx = x2 + width2*0.5;
double bx2_ay = y2 - height2*0.5;
double bx2_by = y2 + height2*0.5;
if ( Col_Range_Range( bx1_ax, bx1_bx, bx2_ax, bx2_bx, true, false, true, false) >= 0 && Col_Range_Range( bx1_ay, bx1_by, bx2_ay, bx2_by, true, false, true, false) >= 0)
return true;
return false;
}
bool Col_Point_Circle(double x1, double y1, double x2, double y2, double radius2)
{
if( M_2Distance_Squared( x1, y1, x2, y2) < M_Square(radius2 + 0.5) )
return true;
return false;
}
bool Col_Circle_Circle(double x1, double y1, double radius1, double x2, double y2, double radius2)
{
if( M_2Distance_Squared( x1, y1, x2, y2) < M_Square(radius1 + radius2) )
return true;
return false;
}
bool Col_Box_Circle(double x1, double y1, double width1, double height1, double x2, double y2, double radius2)
{
double bx_ax;
double bx_bx;
double bx_ay;
double bx_by;
double clp_x;
double clp_y;
//If they're not even close, don't bother doing complicated collision!
if (!Col_Box_Box( x1, y1, width1, height1, x2, y2, radius2 * 2, radius2 * 2))
return false;
bx_ax = x1 - width1*0.5;
bx_bx = x1 + width1*0.5;
bx_ay = y1 - height1*0.5;
bx_by = y1 + height1*0.5;
clp_x = M_Clamp(x2, bx_ax, bx_bx);
clp_y = M_Clamp(y2, bx_ay, bx_by);
if( Col_Point_Circle( clp_x, clp_y, x2,y2, radius2))
return true;
return false;
}
bool Col_Point_Triangle(double x1, double y1, double x2, double y2, double width2, double height2, char * facing)
{
double tr_ax;
double tr_bx;
double tr_ay;
double tr_by;
if(!Col_Point_Box( x1, y1, x2, y2, width2, height2) )
return false;
tr_ax = x2 - width2*0.5;
tr_bx = x2 + width2*0.5;
tr_ay = y2 - height2*0.5;
tr_by = y2 + height2*0.5;
if( strcmp(facing,"TL") == 0)
{
double d = (x1 - tr_ax) / (tr_bx - tr_ax);
double y = tr_by - (d * (tr_by - tr_ay));
if( y1 > y)
return true;
return false;
}
if( strcmp(facing,"TR") == 0)
{
double d = 1 - ((x1 - tr_ax) / (tr_bx - tr_ax));
double y = tr_by - (d * (tr_by - tr_ay));
if( y1 > y)
return true;
return false;
}
if( strcmp(facing,"BL") == 0)
{
double d = (x1 - tr_ax) / (tr_bx - tr_ax);
double y = tr_ay + (d * (tr_by - tr_ay));
if( y1 < y)
return true;
return false;
}
if( strcmp(facing, "BR") == 0)
{
double d = 1 - ((x1 - tr_ax) / (tr_bx - tr_ax));
double y = tr_ay + (d * (tr_by - tr_ay));
if( y1 < y)
return true;
return false;
}
return false;
}
bool Col_Box_Triangle(double x1, double y1, double width1, double height1, double x2, double y2, double width2, double height2, char * facing)
{
double bx_ax;
double bx_bx;
double bx_ay;
double bx_by;
double tr_ax;
double tr_bx;
double tr_ay;
double tr_by;
if(!Col_Box_Box( x1, y1, width1, height1, x2, y2, width2, height2) )
return false;
bx_ax = x1 - width*0.5;
bx_bx = x1 + width*0.5;
bx_ay = y1 - height*0.5;
bx_by = y1 + height*0.5;
tr_ax = x2 - width2*0.5;
tr_bx = x2 + width2*0.5;
tr_ay = y2 - height2*0.5;
tr_by = y2 + height2*0.5;
if( strcmp(facing,"TL") == 0)
{
double d = (bx_bx - tr_ax) / (tr_bx - tr_ax);
double y = tr_by - (d * (tr_by - tr_ay));
if( bx_by > y)
return true;
return false;
}
if( strcmp(facing,"TR") == 0)
{
double d = 1 - ((bx_ax - tr_ax) / (tr_bx - tr_ax));
double y = tr_by - (d * (tr_by - tr_ay));
if( bx_by > y)
return true;
return false;
}
if( strcmp(facing,"BL") == 0)
{
double d = (bx_bx - tr_ax) / (tr_bx - tr_ax);
double y = tr_ay + (d * (tr_by - tr_ay));
if( bx_ay < y)
return true;
return false;
}
if( strcmp(facing, "BR") == 0)
{
double d = 1 - ((bx_ax - tr_ax) / (tr_bx - tr_ax));
double y = tr_ay + (d * (tr_by - tr_ay));
if( bx_ay < y)
return true;
return false;
}
return false;
}
bool Col_Circle_Triangle(double x1, double y1, double radius1, double x2, double y2, double width2, double height2, char * facing)
{
//Constant to get the position at 45 degree on the circle's radius
double Circle_Corner = 0.70710678118654752440084436210485 * radius1;
double tr_ax;
double tr_bx;
double tr_ay;
double tr_by;
if(!Col_Box_Circle( x2, y2, width2, height2, x1, y1, radius1) )
return false;
tr_ax = x2 - width2*0.5;
tr_bx = x2 + width2*0.5;
tr_ay = y2 - height2*0.5;
tr_by = y2 + height2*0.5;
if( strcmp(facing,"TL") == 0)
{
double d = ((x1 + Circle_Corner) - tr_ax) / (tr_bx - tr_ax);
double y = tr_by - (d * (tr_by - tr_ay));
if( (y1 + Circle_Corner) > y)
return true;
return false;
}
if( strcmp(facing,"TR") == 0)
{
double d = 1 - (((x1 - Circle_Corner) - tr_ax) / (tr_bx - tr_ax));
double y = tr_by - (d * (tr_by - tr_ay));
if( (y1 + Circle_Corner) > y)
return true;
return false;
}
if( strcmp(facing,"BL") == 0)
{
double d = ((x1 + Circle_Corner) - tr_ax) / (tr_bx - tr_ax);
double y = tr_ay + (d * (tr_by - tr_ay));
if( (y1 - Circle_Corner) < y)
return true;
return false;
}
if( strcmp(facing, "BR") == 0)
{
double d = 1 - (((x1 - Circle_Corner) - tr_ax) / (tr_bx - tr_ax));
double y = tr_ay + (d * (tr_by - tr_ay));
if( (y1 - Circle_Corner) < y)
return true;
return false;
}
return false;
}
bool Col_Triangle_Triangle(double x1, double y1, double width1, double height1, char * facing1, double x2, double y2, double width2, double height2, char * facing2)
{
double tr1_ax;
double tr1_bx;
double tr1_ay;
double tr1_by;
double tr2_ax;
double tr2_bx;
double tr2_ay;
double tr2_by;
if(!Col_Box_Box( x1, y1, width1, height1, x2, y2, width2, height2))
return false;
tr1_ax = x1 - width2*0.5;
tr1_bx = x1 + width2*0.5;
tr1_ay = y1 - height2*0.5;
tr1_by = y1 + height2*0.5;
tr2_ax = x2 - width2*0.5;
tr2_bx = x2 + width2*0.5;
tr2_ay = y2 - height2*0.5;
tr2_by = y2 + height2*0.5;
if( strcmp(facing1, "BR") == 0)
{
if( strcmp(facing2, "TL") == 0)
{
double d = (tr1_ax - tr2_ax) / (tr2_bx - tr2_ax);
double y = tr2_by - (d * (tr2_by - tr2_ay));
if( tr1_by > y)
return true;
return false;
}
}
if( strcmp(facing1, "BL") == 0)
{
if( strcmp(facing2, "TR") == 0)
{
double d = 1 - ((tr1_bx - tr2_ax) / (tr2_bx - tr2_ax));
double y = tr2_by - (d * (tr2_by - tr2_ay));
if( tr1_by > y)
return true;
return false;
}
}
if( strcmp(facing1, "TR") == 0)
{
if( strcmp(facing2, "BL") == 0)
{
double d = (tr1_ax - tr2_ax) / (tr2_bx - tr2_ax);
double y = tr2_ay + (d * (tr2_by - tr2_ay));
if( tr1_ay < y)
return true;
return false;
}
}
if( strcmp(facing1, "TL") == 0)
{
if( strcmp(facing2, "BR") == 0)
{
double d = 1 - ((tr1_bx - tr2_ax) / (tr2_bx - tr2_ax));
double y = tr2_ay + (d * (tr2_by - tr2_ay));
if( tr1_ay < y)
return true;
return false;
}
}
if( Col_Box_Triangle( x1, y1, width1, height1, x2, y2, width2, height2, facing2) &&
Col_Box_Triangle( x2, y2, width2, height2, x1, y1, width1, height1, facing1))
return true;
return false;
}
In the next few post I will provide a GED example and how to use this... I guess for now look at poorly written code?