1
- package at .jotschi .quadtree .impl ;
1
+ package at .jotschi .quadtree .spacial ;
2
2
3
3
import java .awt .Dimension ;
4
4
import java .awt .Point ;
5
5
import java .util .HashMap ;
6
6
import java .util .Map ;
7
7
8
- import at . jotschi . quadtree . AbstractNodeElement ;
8
+ import org . apache . log4j . Logger ;
9
9
10
- public class SpacialNode < T > extends PointNode < T > {
10
+ import at . jotschi . quadtree . AbstractNode ;
11
11
12
- protected Map < Cell , SpacialNode <T >> nodes = new HashMap < Cell , SpacialNode < T >>();
12
+ public class SpatialNode <T > extends AbstractNode {
13
13
14
- protected AbstractNodeElement < T > element ;
14
+ protected Map < Cell , SpatialNode < T >> nodes = new HashMap < Cell , SpatialNode < T >>() ;
15
15
16
- public SpacialNode (Point startCoordinates , Dimension bounds , int depth ) {
16
+ protected SpatialNodeElement <T > element ;
17
+
18
+ protected static Logger log = Logger .getLogger (SpatialNode .class );
19
+
20
+ public SpatialNode (Point startCoordinates , Dimension bounds , int depth ) {
17
21
super (startCoordinates , bounds , depth );
18
22
}
19
23
20
- public SpacialNode (Point startCoordinates , Dimension bounds , int depth ,
24
+ public SpatialNode (Point startCoordinates , Dimension bounds , int depth ,
21
25
int maxDepth , int maxChildren ) {
22
26
super (startCoordinates , bounds , depth , maxDepth , maxChildren );
23
27
@@ -29,32 +33,120 @@ public SpacialNode(Point startCoordinates, Dimension bounds, int depth,
29
33
*
30
34
* @param element
31
35
*/
32
- public void insert (SpacialNodeElement <T > element ) {
33
- log .debug ("Inserting element into Node at depth " + depth );
36
+ public boolean insert (SpatialNodeElement <T > element ) {
34
37
35
38
boolean wMatch = element .getWidth () == this .getBounds ().width ;
36
39
boolean hMatch = element .getHeight () == this .getBounds ().height ;
40
+ boolean fits = wMatch && hMatch ;
41
+
42
+ boolean wSmaller = element .getWidth () < this .getBounds ().width ;
43
+ boolean hSmaller = element .getHeight () < this .getBounds ().height ;
44
+ boolean smaller = wSmaller && hSmaller ;
45
+
46
+ log .debug ("Inserting element " + element .getHeight () + " - "
47
+ + element .getWidth ());
48
+
49
+ // Check if this node already contains a element
50
+ if (this .element != null ) {
51
+ return false ;
52
+ }
37
53
38
54
// Check if the element fits into this node
39
- if (wMatch && hMatch && this .element == null ) {
55
+ if (fits && this .nodes . size () == 0 ) {
40
56
element .x = this .startCoordinates .x ;
41
57
element .y = this .startCoordinates .y ;
42
58
this .element = element ;
43
- return ;
44
- }
45
-
46
- // We need to subdivide the node if the element is smaller than then the
47
- // dimensions of this node.
48
- if (!( this . depth >= MAX_DEPTH )) {
59
+ log . debug ( "Inserting element at coordinates [" + element . x + "-"
60
+ + element . y + "]" );
61
+ return true ;
62
+ } else if (!( this . depth >= MAX_DEPTH ) && nodes . size () == 0 && smaller ) {
63
+ // We need to subdivide the node if the element is smaller than then
64
+ // the dimensions of this node.
49
65
this .subdivide ();
66
+ // After subdivision we try to insert the element into one of the subnodes
67
+ for (SpatialNode <T > current : nodes .values ()) {
68
+ if (current .insert (element )) {
69
+ return true ;
70
+ }
71
+ }
72
+
73
+ } else {
74
+ // Recall insert for the element. This will try to add the element
75
+ // into
76
+ // one of the subnodes.
77
+ for (SpatialNode <T > current : nodes .values ()) {
78
+ if (current .insert (element )) {
79
+ return true ;
80
+ }
81
+ }
82
+
50
83
}
51
84
52
- // Recall insert for the element. This will try to add the element into
53
- // one of the subnodes.
54
- for (SpacialNode <T > current : nodes .values ()) {
55
- current .insert (element );
85
+ return false ;
86
+ }
87
+
88
+ @ Override
89
+ /**
90
+ * Subdivide the current node and add subnodes
91
+ */
92
+ public void subdivide () {
93
+ log .debug ("Subdividing node at depth " + depth );
94
+ int depth = this .depth + 1 ;
95
+
96
+ int bx = this .startCoordinates .x ;
97
+ int by = this .startCoordinates .y ;
98
+
99
+ // Create the bounds for the new cell
100
+ Dimension newBounds = new Dimension (this .bounds .width / 2 ,
101
+ this .bounds .height / 2 );
102
+
103
+ // Add new bounds to current start coordinates to calculate the new
104
+ // start coordinates
105
+ int newXStartCoordinate = bx + newBounds .width ;
106
+ int newYStartCoordinate = by + newBounds .height ;
107
+
108
+ SpatialNode <T > cellNode = null ;
109
+
110
+ // top left
111
+ cellNode = new SpatialNode <T >(new Point (bx , by ), newBounds , depth );
112
+ this .nodes .put (Cell .TOP_LEFT , cellNode );
113
+
114
+ // top right
115
+ cellNode = new SpatialNode <T >(new Point (newXStartCoordinate , by ),
116
+ newBounds , depth );
117
+ this .nodes .put (Cell .TOP_RIGHT , cellNode );
118
+
119
+ // bottom left
120
+ cellNode = new SpatialNode <T >(new Point (bx , newYStartCoordinate ),
121
+ newBounds , depth );
122
+ this .nodes .put (Cell .BOTTOM_LEFT , cellNode );
123
+
124
+ // bottom right
125
+ cellNode = new SpatialNode <T >(new Point (newXStartCoordinate ,
126
+ newYStartCoordinate ), newBounds , depth );
127
+ this .nodes .put (Cell .BOTTOM_RIGHT , cellNode );
128
+ }
129
+
130
+ /**
131
+ * Clears this node and all subnodes
132
+ */
133
+ public void clear () {
134
+ for (SpatialNode <T > node : nodes .values ()) {
135
+ node .clear ();
56
136
}
137
+ }
138
+
139
+ public SpatialNodeElement <T > getElement () {
140
+ return this .element ;
141
+ }
57
142
143
+ /**
144
+ * Returns the subnodes of this node
145
+ *
146
+ * @return
147
+ */
148
+ public Map <Cell , SpatialNode <T >> getSubNodes () {
149
+ return this .nodes ;
58
150
}
59
151
60
152
}
0 commit comments