Skip to content

Commit 5e3a7be

Browse files
committed
Gift wrapping 3D, line-line distance 3D
1 parent 3466da5 commit 5e3a7be

2 files changed

Lines changed: 74 additions & 0 deletions

File tree

‎code/geometry/convex_hull3d.cpp‎

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#include "primitives3d.cpp"
2+
double mixed(P(a), P(b), P(c)) { return a % (b * c); }
3+
bool cmpy(point3d& a, point3d& b) {
4+
if(abs(a.y-b.y) < EPS) {
5+
if(abs(a.x-b.x) < EPS) return a.z < b.z;
6+
else return a.x < b.x; }
7+
return a.y < b.y; }
8+
point3d slp;
9+
bool cmpsl(point3d& a, point3d& b) {
10+
point3d ad = a-slp, bd = b-slp;
11+
double al = sqrt(ad.x*ad.x + ad.z*ad.z),
12+
bl = sqrt(bd.x*bd.x + bd.z*bd.z);
13+
double aa = atan2(ad.y, al), ba = atan2(bd.y, bl);
14+
return aa < ba; }
15+
set<vi> gift_wrap(vector<point3d> points) {
16+
int n = size(points);
17+
set<vi> res;
18+
if(n < 3) return res;
19+
int lowi = 0;
20+
rep(i,1,n) if(cmpy(points[i], points[lowi])) lowi = i;
21+
slp = points[lowi];
22+
int lowj = 0;
23+
if(lowj == lowi) lowj++;
24+
rep(j,lowj+1,n) {
25+
if(j == lowi) continue;
26+
if(cmpsl(points[j], points[lowj])) lowj = j; }
27+
if(lowi > lowj) swap(lowi, lowj);
28+
set<ii> vis;
29+
queue<ii> q;
30+
q.push(ii(lowi, lowj));
31+
while(!q.empty()) {
32+
ii cur = q.front();
33+
q.pop();
34+
if(vis.find(cur) != vis.end()) continue;
35+
vis.insert(cur);
36+
int mxi = 0, mni = 0;
37+
while(mni == cur.first || mni == cur.second) mni++;
38+
while(mxi == cur.first || mxi == cur.second) mxi++;
39+
rep(i,0,n) {
40+
if(i == cur.first || i == cur.second) continue;
41+
if(mixed(points[cur.second] - points[cur.first],
42+
points[mni] - points[cur.first],
43+
points[i] - points[cur.first]) < 0) mni = i;
44+
if(mixed(points[cur.second] - points[cur.first],
45+
points[mxi] - points[cur.first],
46+
points[i] - points[cur.first]) > 0) mxi = i; }
47+
vi a(2), b(2);
48+
a[0] = cur.first, a[1] = cur.second;
49+
b[0] = mni, b[1] = mxi;
50+
rep(i,0,2) {
51+
if(b[i] == -1) continue;
52+
bool either = false;
53+
rep(j,0,2) {
54+
ii st = ii(b[i], a[j]);
55+
if(st.first > st.second) swap(st.first, st.second);
56+
either = true;
57+
q.push(st); }
58+
vi v;
59+
v.push_back(a[0]);
60+
v.push_back(a[1]);
61+
v.push_back(b[i]);
62+
sort(v.begin(), v.end());
63+
res.insert(v); } } return res; }
64+
// vim: cc=60 ts=2 sts=2 sw=2:

‎code/geometry/primitives3d.cpp‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,14 @@ bool plane_plane_intersect(P(A), P(nA), P(B), P(nB),
8484
P = A + (n * nA) * ((B - A) % nB / (v % nB));
8585
Q = P + n;
8686
return true; }
87+
double line_line_distance(L(A, B), L(C, D),point3d &E,
88+
point3d &F) {
89+
point3d w = (C-A), v = (B-A), u = (D-C),
90+
N = v*u, N1 = v*(u*v), N2 = u*(v*u);
91+
if(w.isZero() || (v*w).isZero()) E = F = A;
92+
else if(N.isZero()) E = A,
93+
F = A + w - v * ((w%v)/(v%v));
94+
else E = A + v*((w % N2)/(v%N2)),
95+
F = C + u*(((-w) % N1)/(u%N1));
96+
return (F-E).length(); }
8797
// vim: cc=60 ts=2 sts=2 sw=2:

0 commit comments

Comments
 (0)