#include "stdafx.h" #include "BVH.h" #include #include #include #include #include #include #include using namespace std; struct point { double x[3]; int id; point() { x[0] = x[1] = x[2] = 0; id = 0; } // friend bool operator < (const point &a,const point &b) // {return a.x[cmpid] q; vector vec; point p[MAXPointNum]; tree t[MAXPointNum]; KDtree() { X = Y = Z = 0; n = tot = root = 0; } inline double dis(tree &x) { double P = (x.p.x[0] - X) * (x.p.x[0] - X); double Q = (x.p.x[1] - Y) * (x.p.x[1] - Y); double O = (x.p.x[2] - Z) * (x.p.x[2] - Z); return P + Q + O; } inline double mndis(tree &x) { double P = (x.mn[0] - X) * (x.mn[0] - X); double M = (x.mx[0] - X) * (x.mx[0] - X); if (X >= x.mn[0] && X <= x.mx[0]) P = M = 0; double Q = (x.mn[1] - Y) * (x.mn[1] - Y); double N = (x.mx[1] - Y) * (x.mx[1] - Y); if (Y >= x.mn[1] && Y <= x.mx[1]) Q = N = 0; double O = (x.mn[2] - Z) * (x.mn[2] - Z); double U = (x.mx[2] - Z) * (x.mx[2] - Z); if (Z >= x.mn[2] && Z <= x.mx[2]) O = U = 0; return min(P, M) + min(Q, N) + min(O, U); } inline void update(int x) { if (!x) return; int l = t[x].ls, r = t[x].rs; if (l) t[x].mn[0] = min(t[x].mn[0], t[l].mn[0]), t[x].mn[1] = min(t[x].mn[1], t[l].mn[1]), t[x].mn[2] = min(t[x].mn[2], t[l].mn[2]), t[x].mx[0] = max(t[x].mx[0], t[l].mx[0]), t[x].mx[1] = max(t[x].mx[1], t[l].mx[1]), t[x].mx[2] = max(t[x].mx[2], t[l].mx[2]); if (r) t[x].mn[0] = min(t[x].mn[0], t[r].mn[0]), t[x].mn[1] = min(t[x].mn[1], t[r].mn[1]), t[x].mn[2] = min(t[x].mn[2], t[r].mn[2]), t[x].mx[0] = max(t[x].mx[0], t[r].mx[0]), t[x].mx[1] = max(t[x].mx[1], t[r].mx[1]), t[x].mx[2] = max(t[x].mx[2], t[r].mx[2]); } void query(int x) { if (!x) return; double res = dis(t[x]); if (res < q.top().dis || (res == q.top().dis && t[x].id < q.top().id)) q.pop(), q.push(node(t[x].id, res)); int l = t[x].ls, r = t[x].rs; double ld = 0, rd = 0; if (l) ld = mndis(t[l]); if (r) rd = mndis(t[r]); // cout< r) return; x = ++tot; int mid = (l + r) >> 1; // cout<<"stage1 "< search_by_k(P &s, int k) { X = s.x; Y = s.y; Z = s.z; while (q.size()) q.pop(); for (int j = 1; j <= k; j++) q.push(node(0, 1e9)); query(root); vector veck; while (q.size()) { if (q.top().id != 0) veck.push_back(q.top().id); q.pop(); } return veck; } // 返回距离s点d以内的所有点的编号 inline vector search_by_dis(P &s, double d) { X = s.x; Y = s.y; Z = s.z; vec.clear(); queryd(root, d); return vec; } } kdtree;