   Problems with line-circle collision detection (part 3)
  I *try* to perform collision detection with the walls of the world usingmy collision detection function------------------------------------------------------------------------boolDetectCollision(float xPosition, float zPosition, WALL *wall){//I am using a Circle-Line Intersection algorithm to perform collision detection//between a circle (camera) and each individual line (walls) that are part of a collection//(sector1.SectorWalls[x].wallPoints//algorithm is publicly available at //http://mathworld.wolfram.com/Circle-LineIntersection.html//as of Wednesday, December 7, 2005//what is radius of circle?//circle's radius can be defined by the point (xpos, zpos) which is used to//translate the camera each frameCOLLISIONCIRCLE camera;camera.circleOrigin.x = xPosition;camera.circleOrigin.z = zPosition;//************//Sidenote   |//************//This collision detection function should not only determine whether the line and circle//intersect, it should also determine if the motion of translation would carry the camera//THROUGH the object.  As an example, imagine that the camera is 0.5 units of movement away//from a wall and the "camera" has a radius of 0.1 units.  There is no collision at this point//so the positioning is valid.  Imagine that the minimum unit of movement for the camera is 1 unit//With the current radius, and the requested positioning, there is still NO collision as the camera//would be completely on the opposite side of the wall, thus breaking the collision detection rules//there are several methods of solving this problem, of which I am choosing the simpler://----------------------------//1.  (Complex)//Not only do a circle-line intersection, but also perform a vector-line intersection//between the translation vector and each wall.  This would check for the origin of//the circle passing through the wall, which would inherently cause a collision to happen//this method is more robust, but would also require more processing power, time, and coding effort//2.  (Simple)//Make the radius of the camera barely slightly larger than the minimum unit of movement//therefore, movement can never "carry" through the wall, because part of the circle will always//intersectcamera.radius = 0.251f;//Collision detection formula//**define the line segment that would represent the wall//dx = x2 - x1;//dy = z2 - z1;//dr = sqrt(dx^2 + dz^2)//D = //|  x1    x2  |// |  z1    z2  |    = x1z2 - x2z1double dx, dz, dr;//the deltasdouble xintersectPlus, xintersectMinus;//the x intersects (+/-)double zintersectPlus, zintersectMinus;//the z intersects (+/-)double x1, x2, z1, z2;//the ordsdouble D;//the Matrix crossproductdouble discrim;//the discriminantint  sgn;//sign x1 = (double) wall->wallPoints[0].x;x2 = (double) wall->wallPoints[1].x;z1 = (double) wall->wallPoints[0].z;z2 = (double) wall->wallPoints[1].z;dx = (double)(x2 - x1);dz = (double)(z2 - z1);dr = sqrt((dx * dx) + (dz * dz));//dr = sqrt(dx^2 + dz^2);D = (double)((x1 * z2) - (x2 * z1));discrim = (camera.radius * camera.radius) * (dr * dr) - (D * D);if(dz < 0){sgn = -1;}else{sgn = 1;}if( discrim < 0 ){return false;}else{//collisionxintersectPlus= ((D* dz) + sgn * dx*(sqrt(discrim)) ) / (dr * dr);xintersectMinus= ((D* dz) - sgn * dx*(sqrt(discrim)) ) / (dr * dr);zintersectPlus  = ( ((-1) * (D * dx)) + (abs(dz) * (sqrt(discrim)) )) / (dr * dr);zintersectMinus= ( ((-1) * (D * dx)) - (abs(dz) * (sqrt(discrim)) )) / (dr * dr);//I don't know what I'm supposed to do with the intersects, so for right now, I'm just//going to return true;return true;}}which is triggered inMy keyboard function (The relevant part of it)It seemed kind of intuitive to perform the collision detection wheneverone of the arrow keys was pressed.---------------------float deltax = (float)sin(heading*piover180) * 0.25f;float deltaz = (float)cos(heading*piover180) * 0.25f;bool xcollision = false;bool zcollision = false;  case UG_KEY_UP:{//do collision detection to see if you can perform movement//perform collision detection with (xpos + deltax, z) as well as with//(x, zpos + deltaz).  If either of them return true, do not perform//the 'positional incrementation'xcollision = false;zcollision = false;for(int i = 0; i < sector1.numWalls; i++){WALL wall = sector1.SectorWalls; if(DetectCollision((xpos - deltax), zpos, &wall)){WALL wall2 = sector1.SectorWalls;if(DetectCollision((xpos - deltax), zpos, &wall2)) //this is checked again for  //debugging purposes.  I can //set a break point here and //only have to follow  //DetectCollision() for  //collisionsxcollision = true;}if(DetectCollision(xpos, (zpos - deltaz), &wall)){WALL wall2 = sector1.SectorWalls;if(DetectCollision(xpos, (zpos - deltaz), &wall2))zcollision = true;}}if(!xcollision){xpos -= deltax;}else{MessageBox(NULL, L"You Hit a wall in the x axis", L"HIT", MB_OK);xpos -= 0;  //**simplified.  Still need to perform "snap" functionality}if(!zcollision){zpos -= deltaz;}else{MessageBox(NULL, L"You Hit a wall in the z axis", L"HIT", MB_OK);zpos -= 0; //**simplified.  Still need to perform "snap" functionality}if(walkbiasangle >= 359.0f){walkbiasangle = 0.0f;}else{walkbiasangle+=10;}walkbias = (float)sin(walkbiasangle * piover180)/20.0f;break;}**********Pressing the down key performs opposite functionality***case UG_KEY_LEFT:   { heading += 2.0f;   }case UG_KEY_RIGHT:   { heading -= 2.0f;   }[Edited by - Alaric on December 7, 2005 8:09:27 PM]