面试中几乎不考。

射线法

射线法,由基准点水平向右生成射线Y,如果Y与多边形的交点数为偶数,则在外部,为奇数则在图内部,特殊情景另外考虑

hdu1756-射线法模板:

  1. struct Point {
  2. double x, y;
  3. Point(double x=0,double y=0):x(x),y(y){}
  4. //向量+
  5. Point operator +(const Point& b) const {
  6. return Point(x + b.x, y + b.y);
  7. }
  8. //向量-
  9. Point operator -(const Point& b)const {
  10. return Point(x - b.x, y - b.y);
  11. }
  12. //点积
  13. double operator *(const Point& b)const {
  14. return x*b.x + y*b.y;
  15. }
  16. //叉积
  17. //P^Q>0,P在Q的顺时针方向;<0,P在Q的逆时针方向;=0,P,Q共线,可能正向可能反向
  18. double operator ^(const Point& b)const {
  19. return x*b.y - b.x*y;
  20. }
  21. };
  22. float eps = 1e-6;
  23. int dcmp(double x) {
  24. if (fabs(x) < eps)
  25. return 0;
  26. else
  27. return x < 0 ? -1 : 1;
  28. }
  29. bool OnSegment(Point& P1, Point& P2,Point& Q) {//判断点Q是否在P1和P2的线段上
  30. return dcmp((P1 - Q) ^ (P2 - Q)) == 0 && dcmp((P1 - Q) * (P2 - Q)) <= 0;//前一个判断点Q在P1P2直线上 后一个判断在P1P2范围上
  31. }
  32. bool InPolygon(Point& P,vector<Point>& v) {//射线法
  33. bool flag = false;
  34. Point P1, P2;
  35. int n = v.size();
  36. for (int i = 0, j = n - 1; i < n; j = i++) {
  37. P1 = v[i];
  38. P2 = v[j];
  39. if (OnSegment(P1, P2, P))
  40. return true;
  41. //前一个判断min(P1.y,P2.y)<P.y<=max(P1.y,P2.y)
  42. //后一个判断被测点 在 射线与边交点 的左边
  43. if ((dcmp(P1.y - P.y) > 0 != dcmp(P2.y - P.y) > 0) && dcmp(P.x - (P.y - P1.y)*(P1.x - P2.x) / (P1.y - P2.y) - P1.x) < 0)
  44. flag = !flag;
  45. }
  46. return flag;
  47. }