-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathOctreeNode.java
More file actions
110 lines (89 loc) · 3.13 KB
/
OctreeNode.java
File metadata and controls
110 lines (89 loc) · 3.13 KB
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import java.util.ArrayList;
import Jcg.geometry.Point_3;
/**
* A class for representing a node of an Octree
*
* @author Luca Castelli Aleardi, Ecole Polytechnique
* @version december 2018
*/
public class OctreeNode {
final static int COMPLET_NODE=1,COMPLET_LEAF=2,NON_COMPLET =0;
public int level;
public OctreeNode[] children=null;
public OctreeNode father;
public Point_3 p; //point stored in a leaf or the middle of the box if the node isn't a leaf
public double a; // length of the side of the cube
int label=-1;// to identify the node
int complet = NON_COMPLET; // NON_COMPLET if we are not in the precomputation
double aMin; // best radius
/**
* Create the octree for storing an input point cloud
*/
public OctreeNode(ArrayList<Point_3> points, Point_3 p, OctreeNode father, double a, int level,int label) {
int i;
Point_3 new_center;
this.father = father;
this.p = p;
this.a = a;
this.level = level;
this.label = label;
// compute the best radius
double rMax = 0;
for(Point_3 p1 :points){
if((double)p1.distanceFrom(p)>rMax){
rMax = (double)p1.distanceFrom(p);
}
}
this.aMin = (rMax*2.000000001)/Math.sqrt(3.0);
/**
* If the node is a leaf, set the point stored
*/
if (points.size() <= 1){
if (points.size() == 0)
this.p = null;
else
this.p = points.get(0);
}
else{
/**
* Compute the points going in each new cube
*/
children = new OctreeNode[8];
ArrayList<Point_3>[] children_points = new ArrayList[8];
i = 0;
for (int add_0=-1; add_0 <= 1; add_0 = add_0 + 2) {
for (int add_1 = -1; add_1 <= 1; add_1 = add_1 + 2) {
for (int add_2 = -1; add_2 <= 1; add_2 = add_2 + 2) {
children_points[i] = new ArrayList<>();
for (Point_3 point : points) {
if ((point.x - p.x) * add_0 >= 0 && (point.y - p.y) * add_1 >=0 &&(point.z - p.z) * add_2 >=0)
children_points[i].add(point);
}
i++;
}
}
}
/**
* Initialize each children
*/
i = 0;
for (int add_0=-1; add_0 <= 1; add_0 = add_0 + 2){
for (int add_1=-1; add_1 <= 1; add_1 = add_1 + 2){
for (int add_2=-1; add_2 <= 1; add_2 = add_2 + 2){
new_center = new Point_3(p.x + add_0 * (a / 4), p.y + add_1 * (a / 4), p.z + add_2 * (a / 4)); //compute the center of the new node
children[i] = new OctreeNode(children_points[i], new_center , this, a / 2, level + 1,8*label+i+1);
i++;
}
}
}
}
}
public boolean hasExactlyOnePoint(){
return (this.children == null && p!=null) || complet==this.COMPLET_LEAF;
}
@Override
public String toString(){
if(p==null) return null;
return "l: "+level+" px: "+Integer.toString((int)(10*p.x))+" a: "+(int)(a*10)/10.+" label: "+Integer.toString(label);
}
}