임의의 개수의 2차원 점을 input으로 받아, 볼록 껍질 객체를 만들어 주는 클래스이다.
using namespace std;
class Point {
public:
long long x, y;
Point(long long _x, long long _y) : x(_x), y(_y) {}
Point operator-(const Point& rhs) const {
return Point(x - rhs.x, y - rhs.y);
}
bool operator<(const Point& rhs) const {
// return y / x < rhs.y / rhs.x
if (y * rhs.x < x * rhs.y) {
return true;
} else if (y * rhs.x > x * rhs.y) {
return false;
} else {
return x * x + y * y < rhs.x * rhs.x + rhs.y * rhs.y;
}
}
bool operator==(const Point& rhs) const {
return x == rhs.x && y == rhs.y;
}
};
ostream& operator<<(ostream& os, const Point& p) {
os << '(' << p.x << ' ' << p.y << ')';
return os;
}
class ConvexHull {
vector<Point> v;
long long signed_area(const Point& v1, const Point& v2) const {
// return det
return v1.x * v2.y - v2.x * v1.y;
}
long long signed_area(const Point& a, const Point& b, const Point& c) const {
// return det
Point v1 = b - a, v2 = c - b;
return v1.x * v2.y - v2.x * v1.y;
}
long long inner_product(const Point& v1, const Point& v2) const {
return v1.x * v2.x + v1.y * v2.y;
}
public:
ConvexHull(vector<Point> ipv) {
// Find the smallest Point (smallest x among the smallest y)
Point minp = ipv[0];
int min_idx = 0;
for (int i = 1; i < ipv.size(); ++i) {
if (minp.y > ipv[i].y || (minp.y == ipv[i].y && minp.x > ipv[i].x)) {
minp = ipv[i];
min_idx = i;
}
}
swap(ipv[0], ipv[min_idx]);
sort(ipv.begin() + 1, ipv.end(), [minp](const Point& lhs, const Point& rhs) -> bool {
return lhs - minp < rhs - minp;
});
// Convex hull making
v.push_back(ipv[0]);
for (int i = 1; i < ipv.size(); ++i) {
while (v.size() >= 2 && signed_area(v[v.size() - 2], v.back(), ipv[i]) <= 0) {
v.pop_back();
}
v.push_back(ipv[i]);
}
}
void print() const {
for (int i = 0; i < v.size(); ++i) {
cout << v[i] << endl;
}
}
int size() const {
return (int) v.size();
}
};
'Computer Science' 카테고리의 다른 글
[C++] Segment Tree 라이브러리 만들기 (0) | 2022.08.16 |
---|---|
유용한 비트 연산들 (0) | 2022.08.11 |
[C++] 다항식 클래스와 라그랑주 보간법(Lagrange Interpolation) 구현 (0) | 2022.08.07 |
[C++] SCC Maker class (0) | 2022.08.06 |
[C++] 선분 교차 판정 (0) | 2022.08.04 |
댓글