Introduction:
1- OpenGL screen setup:
gluOrtho2D(0.0,screen_width,screen_height,0.0);
Figure 1: OpenGL screen setup
The “virtual” bounding box
Figure 2: the bounding box represents by its four corners
struct ROT_RECT
{
POINT Pa,Pb,Pc,Pd;
};
Figure 3: calculating the bounding box with taking the rotation angle into account
Now we are going to implement a function that will take rot (rotation angle of the text Figure 3), a(x,y) (the coordinate of the text), the wid ( the width of the text) and hgt (the height of the text), the function will return ROT_RECT, it is the rectangle which is drawn around the text ( the bounding box of the text) with its four corner points. The function code is:
ROT_RECT buildRectangle(GLfloat rot,GLfloat x,GLfloat y,GLfloat wid,GLfloat hgt)
{
//This function calculates the bounding box for the text
//rot is the rotation angle of the text
//x,y is the position of the text
//wid, hgt is width/height of the text
ROT_RECT temp_rect;
const float piover180 = 0.0174532925f;
GLfloat bx,by,cx,cy,dx,dy;
bx=x+wid*cos(rot*piover180);by=y+wid*sin(rot*piover180); //rot is angular in OpenGL
cx=x+wid*cos(rot*piover180)-hgt*sin(rot*piover180);cy=y+hgt*cos(rot*piover180)+wid*sin(rot*piover180);
dx=x-hgt*sin(rot*piover180);dy=y+hgt*cos(rot*piover180);
// Implement the rectangle
temp_rect.Pa.x=x;temp_rect.Pa.y=y;
temp_rect.Pb.x=bx;temp_rect.Pb.y=by;
temp_rect.Pc.x=cx;temp_rect.Pc.y=cy;
temp_rect.Pd.x=dx;temp_rect.Pd.y=dy;
return temp_rect;
}
3- The cursor/text collision detection
Figure4: the intersection of the line from the cursor with the bounding box of the text
In Figure 4, the cursor is outside the rectangle (not over the text), to calculate this by programming, we need to detect the “cross” between the line Cur-Cent.(the green line) and ALL the rectangle edges, i.e. lines a-b, b-c, c-d, and d-a. If we found an intersection between the line and one of the rectangle edges this means the cursor is outside the rectangle. If there is no intersection, this means the cursor is over the text.
Figure 5: The intersection of two lines.
The intersection point (Red point in Figure 4) coordinates will be calculated. We are going to build a function that will return that point whenever there is an intersection otherwise it will return NULL, the implementation is as follow:
POINT* intersection(POINT p1, POINT p2, POINT p3, POINT p4)
{
// Given two lines, the first line is p1-p2
//the second line is p3-p4
float x1 = p1.x, x2 = p2.x, x3 = p3.x, x4 = p4.x;
float y1 = p1.y, y2 = p2.y, y3 = p3.y, y4 = p4.y;
float d = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
// If d is zero, there is no intersection
if (d == 0) return NULL;
// Get the x and y
float pre = (x1*y2 - y1*x2), post = (x3*y4 - y3*x4);
float x = ( pre * (x3 - x4) - (x1 - x2) * post ) / d;
float y = ( pre * (y3 - y4) - (y1 - y2) * post ) / d;
// Check if the x and y coordinates are within both lines
if ( x < min(x1, x2) || x > max(x1, x2) ||
x < min(x3, x4) || x > max(x3, x4) ) return NULL;
if ( y < min(y1, y2) || y > max(y1, y2) ||
y < min(y3, y4) || y > max(y3, y4) ) return NULL;
sprintf(string,"CrossX: %d ",x);
drawText(string,10,60);
sprintf(string,"CrossY: %d ",y);
drawText(string,10,50);
// Return the point of intersection
POINT* ret= new POINT;
ret->x = x;
ret->y = y;
return ret;
}
3.2 Rectangle-Cursor Collision
bool isCursorInside(ROT_RECT rect,POINT cursor_pos)
{
//calculate the center point of the rectangle
//in is the intersection point for the four corners
POINT center=intersectionPoint(rect.Pa,rect.Pc,rect.Pb,rect.Pd);
//check intersection of line from cursor to the center
//of the rectangle with a-b edge
if(intersection(cursor_pos,center,rect.Pa,rect.Pb) != NULL)return true;
//with b-c edge
if(intersection(cursor_pos,center,rect.Pb,rect.Pc) != NULL)return true;
//with c-d edge
if(intersection(cursor_pos,center,rect.Pc,rect.Pd) != NULL)return true;
//with d-a
if(intersection(cursor_pos,center,rect.Pd,rect.Pa) != NULL)return true;
return false;
}
POINT intersectionPoint(POINT p1, POINT p2, POINT p3, POINT p4)
{
// Given two lines, the first line is p1-p2
//the second line is p3-p4
float x1 = p1.x, x2 = p2.x, x3 = p3.x, x4 = p4.x;
float y1 = p1.y, y2 = p2.y, y3 = p3.y, y4 = p4.y;
float d = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
// Get the x and y
float pre = (x1*y2 - y1*x2), post = (x3*y4 - y3*x4);
float x = ( pre * (x3 - x4) - (x1 - x2) * post ) / d;
float y = ( pre * (y3 - y4) - (y1 - y2) * post ) / d;
// Return the point of intersection
POINT ret;
ret.x = x;
ret.y = y;
return ret;
}
OpenGL Line/Rectangle Intersection Sample Code:
You can Download the Sample code for the above OpenGL Article and check for Instructions on how to run the OpenGL Program.