一些点按顺序能否构成凸包
只要判断每三个点顺序构成的两向量都向一个方向拐。判断两向量向哪个方向拐,只要看叉积:>0逆时针、<0顺时针、=0共线。
向量a和b的叉积\[a \times b = \begin{vmatrix} x_1 & x_2 \ y_1 & y_2 \end{vmatrix} = x_1y_2 - x_2y_1\]
bool isConvex(vector<vector<int>>& points) {
const int N = points.size();
if (N < 3) return false;
int prev = 0;
for (int i = 0; i < N; i++) {
int curr = getDirection(points[i], points[(i+1) % N], points[(i+2) % N]);
if (curr == 0) continue;
if (prev == 0) prev = curr;
else if (curr != prev) return false;
}
return true;
}
int getDirection(const vector<int> &x, const vector<int> &y, const vector<int> &z) {
// x、y、z三点构成a、b两向量,计算a、b的叉积,返回1、-1、0表示拐向
vector<int> a = { y[0] - x[0], y[1] - x[1] };
vector<int> b = { z[0] - y[0], z[1] - y[1] };
int crossProd = a[0] * b[1] - a[1] * b[0];
return crossProd > 0 ? 1 : (crossProd < 0 ? -1 : 0);
}
最大三角形面积
double largestTriangleArea(vector<vector<int>>& points) {
const int N = points.size();
double ans = 0;
for (int i = 0; i < N; i++) {
for (int j = i + 1; j < N; j++) {
for (int k = j + 1; k < N; k++) {
ans = max(ans, area(points[i], points[j], points[k]));
}
}
}
return ans;
}
double area(const vector<int> &x, const vector<int> &y, const vector<int> &z) {
// x、y、z三点可以构造x->y向量a、y->z向量b,计算a、b的叉积
// 根据平行四边形面积=abs(叉积),三角形面积=abs(叉积)*0.5
vector<int> a = { y[0]-x[0], y[1]-x[1] };
vector<int> b = { z[0]-y[0], z[1]-y[1] };
int crossProd = a[0] * b[1] - a[1] * b[0];
return abs(crossProd) * 0.5;
}