ホームに戻る
凸包

//扱える値は int 値のみ
//0,1,2 という3点を与えたとき結果は 0 -> 1 -> 2 -> 0 になる。
//結果の点の数は最初に戻るので1つ増えることに注意。

struct Point{
  int x, y;
  Point(){};
  Point(int x, int y):x(x), y(y){};
  bool operator <(const Point &p) const {
    return x < p.x || (x == p.x && y < p.y);
  }
  bool operator ==(const Point &p) const {
    return (x == p.x && y == p.y);
  }
};

long long cross(const Point &O, const Point &A, const Point &B){
  return (long long)(A.x - O.x) * (B.y - O.y) - (long long)(A.y - O.y) * (B.x - O.x);
}

vector<Point> convex_hull(vector<Point> P){
  int chn = P.size();
  int chk = 0;
  vector<Point> H(2*chn);

  sort(P.begin(), P.end());

  for(int i = 0; i < chn; i++){
    while(chk >= 2 && cross(H[chk-2], H[chk-1], P[i]) <= 0)chk--;
    H[chk++] = P[i];
  }

  for(int i = chn-2, t = chk+1; i >= 0; i--){
    while(chk >= t && cross(H[chk-2], H[chk-1], P[i]) <= 0)chk--;
    H[chk++] = P[i];
  }

  H.resize(chk);
  return H;
}


//凸包を用いた点0と三角123の内外判定
//線上は内部とみなす 角上は外部とみなす
//x2 == x3 として 点0が線分12上かも判定できる
int isIn(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3){
  vector<Point> vp;

  vp.pb(Point(x0, y0));
  vp.pb(Point(x1, y1));
  vp.pb(Point(x2, y2));
  vp.pb(Point(x3, y3));

  vector<Point> vp1 = convex_hull(vp);

  if(count(all(vp1), Point(x0, y0)) == 0){
    return 1;
  }
  return 0;
}

inserted by FC2 system