【模板】三維凸包
阿新 • • 發佈:2019-04-01
() space can problem oss https clear main tor
題目地址
【三維凸包】
這個是我照著lrj的藍書打的。
代碼
#include <bits/stdc++.h> #define pb push_back #define db double #define N 2005 #define eps 1e-9 using namespace std; bool vis[N][N]; db ans = 0; db rand01() {return rand()/(db)RAND_MAX;} db randeps() {return (rand01() - 0.5) * eps;} struct Point3 { db x, y, z; Point3(db x = 0, db y = 0, db z = 0): x(x), y(y), z(z){} }P[N]; typedef Point3 Vector3; Vector3 operator +(Vector3 A, Vector3 B) { return Vector3(A.x + B.x, A.y + B.y, A.z + B.z); } Vector3 operator -(Vector3 A, Vector3 B) { return Vector3(A.x - B.x, A.y - B.y, A.z - B.z); } Vector3 operator *(Vector3 A, db p) { return Vector3(A.x * p, A.y * p, A.z * p); } Vector3 operator /(Vector3 A, db p) { return Vector3(A.x / p, A.y / p, A.z / p); } Vector3 Cross(Vector3 A, Vector3 B) { return Vector3(A.y * B.z - A.z * B.y, A.z * B.x - A.x * B.z, A.x * B.y - A.y * B.x); } db Dot(Vector3 A, Vector3 B) {return A.x * B.x + A.y * B.y + A.z * B.z;} db Length(Vector3 A) {return sqrt(Dot(A, A));} struct Face { int v[3]; Vector3 normal(Point3 *P) const{ return Cross(P[v[1]] - P[v[0]], P[v[2]] - P[v[0]]); } int cansee(Point3 *P, int i) const { return Dot(P[i] - P[v[0]], normal(P)) > 0 ? 1 : 0; } }; vector<Face> Ans; vector<Face> CH3D(Point3 *P, int n) { vector<Face> cur; cur.clear(); cur.pb((Face){0, 1, 2}); cur.pb((Face){2, 1, 0}); for (int i = 3; i < n; i ++) { vector<Face> nxt; for (int j = 0; j < (int)cur.size(); j ++) { Face& f = cur[j]; int res = f.cansee(P, i); if (!res) nxt.pb(f); for (int k = 0; k < 3; k ++) vis[f.v[k]][f.v[(k + 1) % 3]]= res; } for (int j = 0; j < (int)cur.size(); j ++) { for (int k = 0; k < 3; k ++) { int a = cur[j].v[k], b = cur[j].v[(k + 1) % 3]; if (vis[a][b] != vis[b][a] && vis[a][b]) nxt.pb((Face){a, b, i}); } } cur = nxt; } return cur; } int n; int main() { srand(19260817); scanf("%d", &n); for (int i = 0; i < n; i ++) scanf("%lf%lf%lf", &P[i].x, &P[i].y, &P[i].z); Ans = CH3D(P, n); for (int i = 0; i < (int)Ans.size(); i ++) ans += Length(Ans[i].normal(P)) / 2; printf("%.3lf\n", ans); return 0; }
【模板】三維凸包