This documentation is automatically generated by online-judge-tools/verification-helper
View the Project on GitHub AlexanderNekrasov/Youthful-Passion-Fruit-teambook
/**
* Author: Igor Markelov (stole from Red Panda teambook)
* Date: 2022-11-05
* Description: Find the intersection of the half planes.
* Time: O(n \log(n))
*/
vec getPoint(line l) { return {-l.b, l.a}; }
bool bad(line a, line b, line c) {
point x;
assert(intersect(b, c, x) == 1);
return a.eval(x) < 0;
}
// Do not forget about the bounding box
vector<point> hpi(vector<line> lines) {
sort(all(lines), [](line al, line bl) -> bool {
point a = getPoint(al);
point b = getPoint(bl);
if (half(a) != half(b)) {
return half(a) < half(b);
}
return a % b > 0;
});
vector<pair<line, int>> st;
for (int it = 0; it < 2; it++) {
for (int i = 0; i < (int)lines.size(); i++) {
bool flag = false;
while (!st.empty()) {
if (len(getPoint(st.back().first) - getPoint(lines[i])) < EPS) {
if (lines[i].c >= st.back().first.c) {
flag = true;
break;
} else {
st.pop_back();
}
} else if (getPoint(st.back().first) % getPoint(lines[i]) < EPS / 2) {
return {};
} else if (st.size() >= 2 &&
bad(st[st.size() - 2].first, st[st.size() - 1].first,
lines[i])) {
st.pop_back();
} else {
break;
}
}
if (!flag)
st.push_back({lines[i], i});
}
}
vector<int> en(lines.size(), -1);
vector<point> ans;
for (int i = 0; i < (int)st.size(); i++) {
if (en[st[i].second] == -1) {
en[st[i].second] = i;
continue;
}
for (int j = en[st[i].second]; j < i; j++) {
point I;
assert(intersect(st[j].first, st[j + 1].first, I) == 1);
ans.push_back(I);
}
break;
}
return ans;
}
#line 1 "geometry/HalfPlaneIntersection.cpp"
/**
* Author: Igor Markelov (stole from Red Panda teambook)
* Date: 2022-11-05
* Description: Find the intersection of the half planes.
* Time: O(n \log(n))
*/
vec getPoint(line l) { return {-l.b, l.a}; }
bool bad(line a, line b, line c) {
point x;
assert(intersect(b, c, x) == 1);
return a.eval(x) < 0;
}
// Do not forget about the bounding box
vector<point> hpi(vector<line> lines) {
sort(all(lines), [](line al, line bl) -> bool {
point a = getPoint(al);
point b = getPoint(bl);
if (half(a) != half(b)) {
return half(a) < half(b);
}
return a % b > 0;
});
vector<pair<line, int>> st;
for (int it = 0; it < 2; it++) {
for (int i = 0; i < (int)lines.size(); i++) {
bool flag = false;
while (!st.empty()) {
if (len(getPoint(st.back().first) - getPoint(lines[i])) < EPS) {
if (lines[i].c >= st.back().first.c) {
flag = true;
break;
} else {
st.pop_back();
}
} else if (getPoint(st.back().first) % getPoint(lines[i]) < EPS / 2) {
return {};
} else if (st.size() >= 2 &&
bad(st[st.size() - 2].first, st[st.size() - 1].first,
lines[i])) {
st.pop_back();
} else {
break;
}
}
if (!flag)
st.push_back({lines[i], i});
}
}
vector<int> en(lines.size(), -1);
vector<point> ans;
for (int i = 0; i < (int)st.size(); i++) {
if (en[st[i].second] == -1) {
en[st[i].second] = i;
continue;
}
for (int j = en[st[i].second]; j < i; j++) {
point I;
assert(intersect(st[j].first, st[j + 1].first, I) == 1);
ans.push_back(I);
}
break;
}
return ans;
}