nasarouf

line-circle intersection test

Apr 20th, 2017
723
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.54 KB | None | 0 0
  1. //circle-line intersection
  2.  
  3. // from tju1607.cpp http://acm.tju.edu.cn/toj/showp1607.html
  4. // actually does a ray intersection test. but should work for lines too.
  5. // finds the int pt closest to pos
  6. // for ray intersection, if t<0, there is no intersection
  7.  
  8. #define X first
  9. #define Y second
  10. double hypot(double x, double y){   return sqrt(x*x + y*y); }
  11. #define area2(x1,y1,x2,y2,x3,y3) ((x1)*(y2)+(x2)*(y3)+(x3)*(y1))-((y1)*(x2)+(y2)*(x3)+(y3)*(x1))
  12. typedef pair<double,double> pdd;
  13. pdd unit(pdd d){   double h=hypot(d.X,d.Y);   return make_pair(d.X/h,d.Y/h); }
  14. pdd operator+(pdd a, pdd b){   return make_pair(a.X+b.X,a.Y+b.Y); }
  15. pdd operator*(pdd a, double t){   return make_pair(a.X*t,a.Y*t); }
  16. double dot(pdd a, pdd b){   return a.X*b.X + a.Y*b.Y; }
  17.  
  18. //dir has to be a unit vector
  19. //returns: pair<yes=1/no=0, t(param, how far is the intersection pt)>
  20. pair<int,double> line_intersects_circle(double x, double y, double r, pdd pos, pdd dir){
  21.   pos.X-=x;   pos.Y-=y;
  22.   x=y=0;
  23.   if (dir.X<0){     dir.X=-dir.X;     pos.X=-pos.X;   }
  24.   if (dir.Y<0){     dir.Y=-dir.Y;     pos.Y=-pos.Y;   }
  25.   pdd pos1=pos+dir;
  26.   double h=area2(pos.X,pos.Y,pos1.X,pos1.Y,x,y); //since base=|dir|=1
  27.   if (r<=abs(h)) return make_pair<int,double>(0,0.0);
  28.   pdd dir1=make_pair(dir.Y,-dir.X);
  29.   pos1=dir1*h;//+dir*(-sqrt(r*r-h*h));
  30.   pos1=pos1+pos*(-1);
  31.   double d,d1=sqrt(r*r-h*h);
  32.   if (abs(dir.X)>abs(dir.Y)) d=pos1.X/dir.X;
  33.   else d=pos1.Y/dir.Y;
  34.   if (d>0) return make_pair<int,double>(1,d-d1);
  35.   else return make_pair<int,double>(1,d+d1);
  36. }
Advertisement
Add Comment
Please, Sign In to add comment