# Circle - Circle Collision

Hey, im new here, just like to say hello to you all before I begin my post about code

below is some basic openGl code which creates 2 circles on the screen, has them following a circluar path, im trying to get the circle - circle collision detection working (whict is almost does) and when the circles collide, i try and reverse the direction of the circles, only problem is the circles overlap each other and get stuckâ€¦ive tried everything here to get it working and the only reason i can see for it not working is the actual frame which the collision occursâ€¦as I think both circles are trying to change directions but because they are overlapping, they cannot break free of each other, any help pls? thanks

``````
#include<windows.h>
#include<gl/gl.h>
#include<gl/glu.h>
#include<math.h>

bool exiting = false;
long windowWidth = 800;
long windowHeight = 600;
long windowBits = 32;
bool fullscreen = false;
HDC hDC;

#define PI 3.14159

//-------------------------------------------------------------------------------------------------//
//-------------------------------------------------------------------------------------------------//
//-------------------------------------------------------------------------------------------------//

float x_1		= 2.0; // x position of circle 1
float x_2		= -2.0; // x position of circle 2

float y_1		= 2.0;  // y position of circle 1
float y_2		= -2.0;  // y position of circle 2

float length	= 4;    // used to set the length of the arc the looping circles create

float angle1	= 0.0;  // angle of first circle
float angle2	= 180.0;  // angle of second circle

float r1		= 0.5;  // radius of circle 1
float r2		= 0.5;  // radius of circle 2

float D			= 0.0; // to hold value of distance between the 2 circles centers

bool r			= false; // boolean to see if circles have collided

void DrawCircle(float radius, float R, float G, float B)
{
glBegin(GL_POLYGON);
glColor3f(R,G,B); // colour

// calculate each vertex on the circle
for (int vertex = 0; vertex < 50; vertex++)
{
// calculate the angle of the current vertex
float angle = (float)vertex * (2.0f * (float)PI)/50;

// draw the current vertex at the correct radius

} // end for

glEnd();

} // end DrawCircle()

//-------------------------------------------------------------------------------------------------//
//-------------------------------------------------------------------------------------------------//
//-------------------------------------------------------------------------------------------------//

void SetupPixelFormat(HDC hDC)
{
int pixelFormat;

PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),	// size
1,							// version
PFD_SUPPORT_OPENGL |		// OpenGL window
PFD_DRAW_TO_WINDOW |		// render to window
PFD_DOUBLEBUFFER,			// support double-buffering
PFD_TYPE_RGBA,				// color type
32,							// prefered color depth
0, 0, 0, 0, 0, 0,			// color bits (ignored)
0,							// no alpha buffer
0,							// alpha bits (ignored)
0,							// no accumulation buffer
0, 0, 0, 0,					// accum bits (ignored)
16,							// depth buffer
0,							// no stencil buffer
0,							// no auxiliary buffers
PFD_MAIN_PLANE,				// main layer
0,							// reserved
0, 0, 0,					// no layer, visible, damage masks
};

pixelFormat = ChoosePixelFormat(hDC, &pfd);
SetPixelFormat(hDC, pixelFormat, &pfd);
}

LRESULT CALLBACK MainWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static HDC hDC;
static HGLRC hRC;
int height, width;

// dispatch messages
switch (uMsg)
{
case WM_CREATE:			// window creation
hDC = GetDC(hWnd);
SetupPixelFormat(hDC);
//SetupPalette();
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);
break;

case WM_DESTROY:			// window destroy
case WM_QUIT:
case WM_CLOSE:					// windows is closing

// deselect rendering context and delete it
wglMakeCurrent(hDC, NULL);
wglDeleteContext(hRC);

// send WM_QUIT to message queue
PostQuitMessage(0);
break;

case WM_SIZE:
height = HIWORD(lParam);		// retrieve width and height
width = LOWORD(lParam);

break;

case WM_ACTIVATEAPP:		// activate app
break;

case WM_PAINT:				// paint
PAINTSTRUCT ps;
BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;

case WM_LBUTTONDOWN:		// left mouse button
break;

case WM_RBUTTONDOWN:		// right mouse button
break;

case WM_MOUSEMOVE:			// mouse movement
break;

case WM_LBUTTONUP:			// left button release
break;

case WM_RBUTTONUP:			// right button release
break;

case WM_KEYUP:
break;

case WM_KEYDOWN:
int fwKeys;
LPARAM keyData;
fwKeys = (int)wParam;    // virtual-key code
keyData = lParam;          // key data

switch(fwKeys)
{
case VK_ESCAPE:
PostQuitMessage(0);
break;

default:
break;
}

break;

default:
break;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
WNDCLASSEX windowClass;		// window class
HWND	   hwnd;			// window handle
MSG		   msg;				// message
DWORD	   dwExStyle;		// Window Extended Style
DWORD	   dwStyle;			// Window Style
RECT	   windowRect;

windowRect.left=(long)0;						// Set Left Value To 0
windowRect.right=(long)windowWidth;	// Set Right Value To Requested Width
windowRect.top=(long)0;							// Set Top Value To 0
windowRect.bottom=(long)windowHeight;	// Set Bottom Value To Requested Height

// fill out the window class structure
windowClass.cbSize			= sizeof(WNDCLASSEX);
windowClass.style			= CS_HREDRAW | CS_VREDRAW;
windowClass.lpfnWndProc		= MainWindowProc;
windowClass.cbClsExtra		= 0;
windowClass.cbWndExtra		= 0;
windowClass.hInstance		= hInstance;
windowClass.hIcon			= LoadIcon(NULL, IDI_APPLICATION);	// default icon
windowClass.hCursor			= LoadCursor(NULL, IDC_ARROW);		// default arrow
windowClass.hbrBackground	= NULL;								// don't need background
windowClass.lpszClassName	= "GLClass";
windowClass.hIconSm			= LoadIcon(NULL, IDI_WINLOGO);		// windows logo small icon

// register the windows class
if (!RegisterClassEx(&windowClass))
return 0;

if (fullscreen)								// fullscreen?
{
DEVMODE dmScreenSettings;					// device mode
memset(&dmScreenSettings,0,sizeof(dmScreenSettings));
dmScreenSettings.dmSize = sizeof(dmScreenSettings);
dmScreenSettings.dmPelsWidth = windowWidth;			// screen width
dmScreenSettings.dmPelsHeight = windowHeight;			// screen height
dmScreenSettings.dmBitsPerPel = windowBits;				// bits per pixel
dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;

//
if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
{
// setting display mode failed, switch to windowed
MessageBox(NULL, "Display mode failed", NULL, MB_OK);
fullscreen = FALSE;
}
}

if (fullscreen)								// Are We Still In Fullscreen Mode?
{
dwExStyle=WS_EX_APPWINDOW;					// Window Extended Style
dwStyle=WS_POPUP;						// Windows Style
ShowCursor(FALSE);						// Hide Mouse Pointer
}
else
{
dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;			// Window Extended Style
dwStyle=WS_OVERLAPPEDWINDOW;					// Windows Style
}

// class registered, so now create our window
hwnd = CreateWindowEx(NULL,									// extended style
"GLClass",							// class name
"Circle - Circle Collision",		// app name
dwStyle | WS_CLIPCHILDREN |
WS_CLIPSIBLINGS,
0, 0,								// x,y coordinate
windowRect.right - windowRect.left,
windowRect.bottom - windowRect.top, // width, height
NULL,									// handle to parent
hInstance,							// application instance
NULL);								// no extra params

hDC = GetDC(hwnd);

// check if window creation failed (hwnd would equal NULL)
if (!hwnd)
return 0;

ShowWindow(hwnd, SW_SHOW);			// display the window
UpdateWindow(hwnd);					// update the window

//----------------------------------------------------------------------------
//----------------------------------------------------------------------------

glViewport(0, 0, 800, 600);		// reset the viewport to new dimensions
glMatrixMode(GL_PROJECTION);			// set projection matrix current matrix

// calculate aspect ratio of window
gluPerspective(52.0f,(GLfloat)800/(GLfloat)600,1.0f,1000.0f);

glMatrixMode(GL_MODELVIEW);				// set modelview matrix

//----------------------------------------------------------------------------
//----------------------------------------------------------------------------

while (!exiting)
{

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);		// clear screen and depth buffer
gluLookAt(0.0, 10.0, 0.1, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

x_1		= cosf(angle1)*length; // assign new value to circle 1 x position
y_1		= sinf(angle1)*length; // assign new value to circle 1 y position

x_2		= cosf(angle2)*length; // assign new value to circle 2 x position
y_2		= sinf(angle2)*length; // assign new value to circle 2 y position

// calculate the distance between the two centers of the circles
D = sqrt((((x_2+r2)-(x_1+r1))*((x_2+r2)-(x_1+r1))) + (((y_2+r2)-(y_1+r1))*((y_2+r2)-(y_1+r1))));

// if the distance between the centers is less than the two circles
// radii summed up - we have a collision!!

if( D <= r1+r2 )
{
r = true;
}

if( D >= r1+r2)
{
r = false;
}

if( r )
{
angle1  -= 0.05; // increment angle for circle 1 in clockwise direction
angle2  += 0.05; // decrement angle for circle 2 in anti - clockwise direction
}

if( !r )
{
angle1  += 0.05; // increment angle for circle 1 in clockwise direction
angle2  -= 0.05; // decrement angle for circle 2 in anti - clockwise direction
}

//--------------------------------------------------------------------------------
//-------------------------------- CIRCLE 1---------------------------------------

// push matrix onto the stack
glPushMatrix();

// create new x and y position for circle 1
glTranslatef(x_1, 0, y_1);

// call circle function to draw it
DrawCircle(r1, 255, 0, 0);

// pop matrix off the stack
glPopMatrix();

//--------------------------------------------------------------------------------
//--------------------------------- CIRCLE 2--------------------------------------

// push matrix onto the stack
glPushMatrix();

// create new x and y position for circle 2
glTranslatef(x_2, 0, y_2);

// call circle function to draw it
DrawCircle(r2, 0, 0, 255);

// pop matrix off the stack
glPopMatrix();

//--------------------------------------------------------------------------------
//------------------------------------------------------------------------------

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

SwapBuffers(hDC);

while (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))
{
if (!GetMessage (&msg, NULL, 0, 0))
{
exiting = true;
break;
}

TranslateMessage (&msg);
DispatchMessage (&msg);
}
}

if (fullscreen)
{
ChangeDisplaySettings(NULL,0);					// If So Switch Back To The Desktop
ShowCursor(TRUE);						// Show Mouse Pointer
}

return (int)msg.wParam;
}
``````

Originally posted by johnnyp05:
[b]

``````// calculate the distance between the two centers of the circles
D = sqrt((((x_2+r2)-(x_1+r1))*((x_2+r2)-(x_1+r1))) + (((y_2+r2)-(y_1+r1))*((y_2+r2)-(y_1+r1))));
``````

[/b]
Why are you including the radii when you want the distance of the centers? This should be

``````D = sqrt((x_2-x_1)*(x_2-x_1) + (y_2-y_1)*(y_2-y_1));
``````

To your original problem: You are reversing the movement of your circles as long as there is a collision. Which means that, as soon as the collision is resolved, you go back to the original movement, which brings you right back to your collision.

Try something like

``````if( D <= r1+r2 )
{
r = !r
}
``````

Aaaah thanks, I feel such a n00b :rolleyes: they reverse directions when they collide now.

Yea i know what the distance formula is originally, its just theyâ€™d overlap each other if i dont add the radius to the formula, therefore i get an edge to edge collision, not a center to center collision - it was just trying stuff to see what happened, and that worked, dunno why, wierd huh? funnily enough i dont need to add the radius to it now to get edge/edge collision, manâ€¦this is wierdâ€¦pff whoâ€™d be a programmer thanks for help, although its kinda embrassing needing help on something that simple, should have guessed that straight away, doh! :mad: