-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathKDTree.hpp
82 lines (77 loc) · 2.07 KB
/
KDTree.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#pragma once
#include "Vec3.hpp"
#include "utils.hpp"
#include "KDTreenode.hpp"
#include "Viewpoint.hpp"
#define DIM 3
class KDTree
{
public:
Node* root;
KDTree() : root(nullptr) {}
~KDTree() { clean(root); }
void build(Node*& present, std::vector<HitPoint>& points, int depth, int begin, int end)
{
if (end - begin <= 0)
return;
int mid = (begin + end) >> 1;
auto st = points.begin();
HitPoint::depth = depth;
std::nth_element(st + begin, st + mid, st + end);
present = new Node(points[mid]);
depth = (depth + 1) % DIM;
build(present->left, points, depth, begin, mid);
build(present->right, points, depth, mid + 1, end);
present->updatebound();
}
void query(Node* present, std::vector<std::vector<ViewPoint>>& view, const RayPoint& rp)
{
if (present == nullptr) return;
if (rp.pos.outrange(present->boundmin, present->boundmax))
return;
if ((rp.pos - present->hp.pos).sqrlen() < sqr(present->hp.rad))
{
present->hp.ptclast += 1;
int h, w; std::tie(h, w) = present->hp.viewpoint;
view[h][w].add(rp.its.mult(present->hp.col) * rp.prob * present->hp.prob, rp.prob);
}
query(present->left, view, rp);
query(present->right, view, rp);
}
/*int query(Node* present, const RayPoint& rp)
{
if (present == nullptr) return 0;
if (rp.pos.outrange(present->boundmin, present->boundmax))
return 0;
if ((rp.pos - present->hp.pos).sqrlen() < sqr(present->hp.rad))
return 1 + query(present->left, rp) + query(present->right, rp);
return query(present->left, rp) + query(present->right, rp);
}*/
void traverse(Node* present)
{
if (present != nullptr) {
printf("GO LEFT\n");
traverse(present->left);
present->hp.print();
printf("GO RIGHT\n");
traverse(present->right);
}
printf("RETURN\n");
}
void reducerad(Node* present)
{
if (present == nullptr) return;
present->hp.update();
present->initbound();
reducerad(present->left);
reducerad(present->right);
present->updatebound();
}
void clean(Node* present)
{
if (present == nullptr) return;
clean(present->left);
clean(present->right);
delete present;
}
};