void normalize() { set<segment> T; set<point> U; for (int i = 0; i < n; i++) make_barrier(i, i); for (int i = 0; i < m; i++) { point p = v[b[i].first], q = v[b[i].second]; set<point> S; S.insert(p); S.insert(q); for (int j = 0; j < m; j++) { point r = v[b[j].first], s = v[b[j].second]; if (r == p || r == q || s == p || s == q) continue; if (cmp((q - p) % (s - r)) == 0) { if (between(p, r, q)) S.insert(r); if (between(p, s, q)) S.insert(s); } else if (seg_intersect(p, q, r, s)) { S.insert(line_intersect(p, q, r, s)); } } foreach (st, all(S)) { if (st != S.begin()) T.insert(segment(p, *st)); U.insert(p = *st); } } clear(); foreach (it, all(U)) v[n++] = *it; foreach (it, all(T)) { int i = lower_bound(v, v+n, it->first) - v; int j = lower_bound(v, v+n, it->second) - v; make_barrier(i, j); }
polygon poly_intersect(polygon &P, polygon &Q){ int m = Q.size(), n = P.size(); int a = 0, b = 0, aa = 0, ba = 0, inflag = 0; polygon R; while( (aa < n || ba < m) && aa < 2*n && ba < 2*m){ Point p1 = P[a], p2 = P[(a+1) % n], q1 = Q[b], q2 = Q[(b+1) % m]; Point A = p2 - p1, B = q2 - q1; int cross = cmp(A ^ B), ha = turn(p2, q2, p1), hb = turn(q2, p2, q1); if(cross == 0 && turn(p1, q1, p2) == 0 && cmp(A * B) < 0){ if(between(p1, q1, p2)) R.push_back(q1); if(between(p1, q2, p2)) R.push_back(q2); if(between(q1, p1, q2)) R.push_back(p1); if(between(q1, p2, q2)) R.push_back(p2); if(R.size() < 2) return polygon(); inflag = 1; break; }else if(cross != 0 && seg_intersect(p1, p2, q1, q2)) { if(inflag == 0) aa = ba = 0; R.push_back(intersection(p1, p2, q1, q2)); inflag = (hb > 0) ? 1 : -1; } if(cross == 0 && hb < 0 && ha < 0) return R; bool t = cross == 0 && hb == 0 && ha == 0; if(t ? (inflag == 1) : (cross >= 0) ? (ha <= 0) : (hb > 0)){ if(inflag == -1) R.push_back(q2); ba++; b++; b %= m; }else{ if(inflag == 1) R.push_back(p2); aa++; a++; a %= n; } } if(inflag == 0){ if (in_polygon(P[0], Q)) return P; if (in_polygon(Q[0], P)) return Q; } R.erase(unique(R.begin(), R.end()), R.end()); if(R.size() > 1 && R.front() == R.back()) R.pop_back(); return R; }