lulu 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/ext/lulu/merger.h CHANGED
@@ -10,8 +10,6 @@
10
10
 
11
11
  #include "marker.h"
12
12
 
13
- void merge_markers(MARKER_INFO *info, MARKER *markers, int markers_size);
14
13
  int merge_markers_fast(MARKER_INFO *info, MARKER *markers, int markers_size);
15
- int merge_test(int test_markers_size);
16
14
 
17
15
  #endif /* MERGER_H_ */
data/ext/lulu/pq.c CHANGED
@@ -17,228 +17,155 @@
17
17
 
18
18
  // Move index at heap location j upward until its parent's value is no bigger.
19
19
  static void pq_sift_up(PRIORITY_QUEUE *q, int j) {
20
- int i = q->heap[j];
21
- PRIORITY_QUEUE_VALUE val = q->values[i];
22
- while (j > 0) {
23
- int j_pnt = (j - 1) / 2;
24
- if (q->values[q->heap[j_pnt]] <= val)
25
- break;
26
- int k = q->heap[j] = q->heap[j_pnt];
27
- q->locs[k] = j;
28
- j = j_pnt;
29
- }
30
- int k = q->heap[j] = i;
31
- q->locs[k] = j;
20
+ int i = q->heap[j];
21
+ PRIORITY_QUEUE_VALUE val = q->values[i];
22
+ while (j > 0) {
23
+ int j_pnt = (j - 1) / 2;
24
+ if (q->values[q->heap[j_pnt]] <= val)
25
+ break;
26
+ int k = q->heap[j] = q->heap[j_pnt];
27
+ q->locs[k] = j;
28
+ j = j_pnt;
29
+ }
30
+ int k = q->heap[j] = i;
31
+ q->locs[k] = j;
32
32
  }
33
33
 
34
34
  // Move index at heap location j downward until its children's values are no smaller.
35
35
  // Pay some attention to efficiency because this is bottleneck code.
36
36
  static void pq_sift_down(PRIORITY_QUEUE *q, int j) {
37
- int i = q->heap[j];
38
- PRIORITY_QUEUE_VALUE val = q->values[i];
39
- for (;;) {
40
- int j_rgt = 2 * j + 2;
41
- if (j_rgt < q->size) {
42
- // two children
43
- int j_lft = j_rgt - 1;
44
- PRIORITY_QUEUE_VALUE val_lft = q->values[q->heap[j_lft]];
45
- PRIORITY_QUEUE_VALUE val_rgt = q->values[q->heap[j_rgt]];
46
- if (val_lft < val_rgt) {
47
- if (val <= val_lft)
48
- break;
49
- int k = q->heap[j] = q->heap[j_lft];
50
- q->locs[k] = j;
51
- j = j_lft;
52
- } else {
53
- if (val <= val_rgt)
54
- break;
55
- int k = q->heap[j] = q->heap[j_rgt];
56
- q->locs[k] = j;
57
- j = j_rgt;
58
- }
59
- } else if (j_rgt == q->size) {
60
- // left child only
61
- int j_lft = j_rgt - 1;
62
- if (val <= q->values[q->heap[j_lft]])
63
- break;
64
- int k = q->heap[j] = q->heap[j_lft];
65
- q->locs[k] = j;
66
- j = j_lft;
67
- break; // this node has no children
68
- } else {
69
- break; // no children at all
70
- }
71
- }
72
- int k = q->heap[j] = i;
73
- q->locs[k] = j;
37
+ int i = q->heap[j];
38
+ PRIORITY_QUEUE_VALUE val = q->values[i];
39
+ for (;;) {
40
+ int j_rgt = 2 * j + 2;
41
+ if (j_rgt < q->size) {
42
+ // two children
43
+ int j_lft = j_rgt - 1;
44
+ PRIORITY_QUEUE_VALUE val_lft = q->values[q->heap[j_lft]];
45
+ PRIORITY_QUEUE_VALUE val_rgt = q->values[q->heap[j_rgt]];
46
+ if (val_lft < val_rgt) {
47
+ if (val <= val_lft)
48
+ break;
49
+ int k = q->heap[j] = q->heap[j_lft];
50
+ q->locs[k] = j;
51
+ j = j_lft;
52
+ } else {
53
+ if (val <= val_rgt)
54
+ break;
55
+ int k = q->heap[j] = q->heap[j_rgt];
56
+ q->locs[k] = j;
57
+ j = j_rgt;
58
+ }
59
+ } else if (j_rgt == q->size) {
60
+ // left child only
61
+ int j_lft = j_rgt - 1;
62
+ if (val <= q->values[q->heap[j_lft]])
63
+ break;
64
+ int k = q->heap[j] = q->heap[j_lft];
65
+ q->locs[k] = j;
66
+ j = j_lft;
67
+ break; // this node has no children
68
+ } else {
69
+ break; // no children at all
70
+ }
71
+ }
72
+ int k = q->heap[j] = i;
73
+ q->locs[k] = j;
74
74
  }
75
75
 
76
76
  // Initialize a newly allocated priority queue structure.
77
77
  void pq_init(PRIORITY_QUEUE *q) {
78
- q->max_size = q->size = 0;
79
- q->heap = NULL;
80
- q->locs = NULL;
81
- q->values = NULL;
78
+ q->max_size = q->size = 0;
79
+ q->heap = NULL;
80
+ q->locs = NULL;
81
+ q->values = NULL;
82
82
  }
83
83
 
84
84
  // Clear a previously initialized and possibly set up priority queue, returning
85
85
  // it to the initialized state but with all resourced freed. Note the values
86
86
  // are owned by the user and are not freed here.
87
87
  void pq_clear(PRIORITY_QUEUE *q) {
88
- Free(q->heap);
89
- Free(q->locs);
90
- pq_init(q);
88
+ Free(q->heap);
89
+ Free(q->locs);
90
+ pq_init(q);
91
91
  }
92
92
 
93
93
  // Build the queue with given pre-allocated and filled array of values.
94
94
  void pq_set_up(PRIORITY_QUEUE *q, PRIORITY_QUEUE_VALUE *values, int size) {
95
- q->max_size = q->size = size;
96
- q->values = values;
97
- NewArray(q->heap, size);
98
- NewArray(q->locs, size);
99
- for (int i = 0; i < size; i++)
100
- q->heap[i] = q->locs[i] = i;
101
- // heapify
102
- for (int j = size / 2 - 1; j >= 0; j--)
103
- pq_sift_down(q, j);
95
+ q->max_size = q->size = size;
96
+ q->values = values;
97
+ NewArray(q->heap, size);
98
+ NewArray(q->locs, size);
99
+ for (int i = 0; i < size; i++)
100
+ q->heap[i] = q->locs[i] = i;
101
+ // heapify
102
+ for (int j = size / 2 - 1; j >= 0; j--)
103
+ pq_sift_down(q, j);
104
104
  }
105
105
 
106
106
  // Build the queue with given pre-allocated and filled array of values
107
107
  // and given heap indices. Note the indices are owned by the heap
108
108
  // after set up and will be freed with the heap.
109
109
  void pq_set_up_heap(PRIORITY_QUEUE *q, int *heap, int size,
110
- PRIORITY_QUEUE_VALUE *values, int max_size) {
111
- q->max_size = max_size;
112
- q->values = values;
113
- q->size = size;
114
- q->heap = heap;
115
- NewArray(q->locs, max_size);
116
- for (int i = 0; i < max_size; i++)
117
- q->locs[i] = -1;
118
- for (int j = 0; j < size; j++)
119
- q->locs[heap[j]] = j;
120
- for (int j = size / 2 - 1; j >= 0; j--)
121
- pq_sift_down(q, j);
110
+ PRIORITY_QUEUE_VALUE *values, int max_size) {
111
+ q->max_size = max_size;
112
+ q->values = values;
113
+ q->size = size;
114
+ q->heap = heap;
115
+ NewArray(q->locs, max_size);
116
+ for (int i = 0; i < max_size; i++)
117
+ q->locs[i] = -1;
118
+ for (int j = 0; j < size; j++)
119
+ q->locs[heap[j]] = j;
120
+ for (int j = size / 2 - 1; j >= 0; j--)
121
+ pq_sift_down(q, j);
122
122
  }
123
123
 
124
124
  // Return the index of the minimum value on the queue.
125
125
  int pq_peek_min(PRIORITY_QUEUE *q) {
126
- return q->size <= 0 ? -1 : q->heap[0];
126
+ return q->size <= 0 ? -1 : q->heap[0];
127
127
  }
128
128
 
129
129
  // Remove and return the index of the minimum value on the queue.
130
130
  int pq_get_min(PRIORITY_QUEUE *q) {
131
- if (q->size <= 0)
132
- return -1;
133
- int i = q->heap[0];
134
- q->locs[i] = -1;
135
- if (--q->size > 0) {
136
- q->heap[0] = q->heap[q->size];
137
- pq_sift_down(q, 0);
138
- }
139
- return i;
131
+ if (q->size <= 0)
132
+ return -1;
133
+ int i = q->heap[0];
134
+ q->locs[i] = -1;
135
+ if (--q->size > 0) {
136
+ q->heap[0] = q->heap[q->size];
137
+ pq_sift_down(q, 0);
138
+ }
139
+ return i;
140
140
  }
141
141
 
142
142
  // Add a new value with index i into the queue.
143
143
  void pq_add(PRIORITY_QUEUE *q, int i) {
144
- if (q->size >= q->max_size)
145
- return;
146
- int j = q->size++;
147
- q->heap[j] = i;
148
- pq_sift_up(q, j);
144
+ if (q->size >= q->max_size)
145
+ return;
146
+ int j = q->size++;
147
+ q->heap[j] = i;
148
+ pq_sift_up(q, j);
149
149
  }
150
150
 
151
151
  // Restore the heap after the value at index i is changed.
152
152
  void pq_update(PRIORITY_QUEUE *q, int i) {
153
- int j = q->locs[i];
154
- if (j >= 0) {
155
- pq_sift_down(q, j);
156
- pq_sift_up(q, j);
157
- }
153
+ int j = q->locs[i];
154
+ if (j >= 0) {
155
+ pq_sift_down(q, j);
156
+ pq_sift_up(q, j);
157
+ }
158
158
  }
159
159
 
160
160
  // Delete index i from the heap, making the corresponding key an orphan.
161
161
  void pq_delete(PRIORITY_QUEUE *q, int i) {
162
- int j = q->locs[i];
163
- if (0 <= j) {
164
- q->locs[i] = -1;
165
- if (j < --q->size) {
166
- q->heap[j] = q->heap[q->size];
167
- pq_sift_down(q, j);
168
- pq_sift_up(q, j);
169
- }
170
- }
162
+ int j = q->locs[i];
163
+ if (0 <= j) {
164
+ q->locs[i] = -1;
165
+ if (j < --q->size) {
166
+ q->heap[j] = q->heap[q->size];
167
+ pq_sift_down(q, j);
168
+ pq_sift_up(q, j);
169
+ }
170
+ }
171
171
  }
172
-
173
- #ifndef EXCLUDE_UNIT_TEST
174
-
175
- /* Randomly permute the given distance array. */
176
- void permute(PRIORITY_QUEUE_VALUE *a, int size) {
177
- for (int i = size - 1; i > 0; i--) {
178
- int j = rand() % (i + 1);
179
- PRIORITY_QUEUE_VALUE tmp = a[i];
180
- a[i] = a[j];
181
- a[j] = tmp;
182
- }
183
- }
184
-
185
- // Run a unit test on a priority queue of random data with given size.
186
- int pq_test(int size) {
187
- PRIORITY_QUEUE q[1];
188
- pq_init(q);
189
-
190
- fprintf(stderr, "test: heap_ops (n = %d):\n", size);
191
-
192
- // Build linear pointer array of random keys.
193
- PRIORITY_QUEUE_VALUE *dist;
194
- NewArray(dist, size);
195
- for (int i = 0; i < size; i++)
196
- dist[i] = i;
197
- permute(dist, size);
198
- fprintf(stderr, " built random data\n");
199
-
200
- pq_set_up(q, dist, size);
201
- fprintf(stderr, " finished set up\n");
202
-
203
- // Pull min repeatedly and verify vals are what they should be.
204
- PRIORITY_QUEUE_VALUE should_be = 0;
205
- for (int n = 0; n < size; n++) {
206
- int i = pq_get_min(q);
207
- if (dist[i] != should_be++) {
208
- fprintf(stderr, "fail 1: %i -> %g\n", i, dist[i]);
209
- return 42;
210
- }
211
- }
212
- fprintf(stderr, " finished checking heapify\n");
213
-
214
- // Now rebuild the heap by inserting one key at a time.
215
- for (int n = 0; n < size; n++)
216
- pq_add(q, n);
217
- fprintf(stderr, " finished insertions\n");
218
-
219
- // And verify values again.
220
- should_be = 0;
221
- for (int n = 0; n < size; n++) {
222
- int i = pq_get_min(q);
223
- if (dist[i] != should_be++) {
224
- fprintf(stderr, " fail 2: %i -> %g\n", i, dist[i]);
225
- return 4242;
226
- }
227
- }
228
- fprintf(stderr, " finished checking insert\n");
229
-
230
- // Now rebuild the heap by inserting one key at a time in reverse.
231
- for (int n = size - 1; n >= 0; n--)
232
- pq_add(q, n);
233
- fprintf(stderr, " finished reverse insertions\n");
234
-
235
- // Now delete one by one.
236
- for (int n = 0; n < size; n++)
237
- pq_delete(q, n);
238
- fprintf(stderr, " finished reverse deletions\n");
239
-
240
- pq_clear(q);
241
- return 0;
242
- }
243
-
244
- #endif
data/ext/lulu/pq.h CHANGED
@@ -11,11 +11,11 @@
11
11
  typedef double PRIORITY_QUEUE_VALUE;
12
12
 
13
13
  typedef struct priority_queue_s {
14
- int max_size; // max number of items in heap
15
- int size; // current number of items in heap
16
- int *heap; // heap of indices to values
17
- int *locs; // map of value indices to heap locations
18
- PRIORITY_QUEUE_VALUE *values; // values referred to by heap
14
+ int max_size; // max number of items in heap
15
+ int size; // current number of items in heap
16
+ int *heap; // heap of indices to values
17
+ int *locs; // map of value indices to heap locations
18
+ PRIORITY_QUEUE_VALUE *values; // values referred to by heap
19
19
  } PRIORITY_QUEUE;
20
20
 
21
21
  // Initialize a newly allocated priority queue structure.
@@ -34,8 +34,8 @@ void pq_set_up(PRIORITY_QUEUE *q, PRIORITY_QUEUE_VALUE *values, int size);
34
34
  // and given heap indices. Note the indices are owned by the heap
35
35
  // after set up and will be freed with the heap.
36
36
  void pq_set_up_heap(PRIORITY_QUEUE *q,
37
- int *heap, int size,
38
- PRIORITY_QUEUE_VALUE *values, int max_size);
37
+ int *heap, int size,
38
+ PRIORITY_QUEUE_VALUE *values, int max_size);
39
39
 
40
40
  // Return the index of the minimum value on the queue.
41
41
  int pq_peek_min(PRIORITY_QUEUE *q);
@@ -53,18 +53,15 @@ void pq_add(PRIORITY_QUEUE *q, int i);
53
53
  void pq_delete(PRIORITY_QUEUE *q, int i);
54
54
 
55
55
  // Return an array containing indices currently in the heap.
56
- #define pq_index_set(Q) ((Q)->heap)
56
+ #define pq_index_set(Q) ((Q)->heap)
57
57
 
58
58
  // Return an array containing indices currently in the heap.
59
- #define pq_index(Q, I) ((Q)->heap[I])
59
+ #define pq_index(Q, I) ((Q)->heap[I])
60
60
 
61
61
  // Return the size of the index array contained above.
62
- #define pq_index_set_size(Q) ((Q)->size)
62
+ #define pq_index_set_size(Q) ((Q)->size)
63
63
 
64
64
  // Return non-zero iff the queue is empty.
65
65
  #define pq_empty_p(Q) ((Q)->size <= 0)
66
66
 
67
- // Run the heap module through some unit tests.
68
- int pq_test(int size);
69
-
70
67
  #endif /* PRIORITY_QUEUE_H_ */
data/ext/lulu/qt.c CHANGED
@@ -14,31 +14,31 @@
14
14
 
15
15
  // Declare the given quadrant of a given bounding box.
16
16
  #define QUADRANT_DECL(Q, QX, QY, QW, QH, X, Y, W, H) \
17
- double QW = W * 0.5; \
18
- double QH = H * 0.5; \
19
- double QX = (Q & 1) ? X + QW : X; \
20
- double QY = (Q & 2) ? Y + QH : Y
17
+ MARKER_DISTANCE QW = W * 0.5; \
18
+ MARKER_DISTANCE QH = H * 0.5; \
19
+ MARKER_COORD QX = (Q & 1) ? X + QW : X; \
20
+ MARKER_COORD QY = (Q & 2) ? Y + QH : Y
21
21
 
22
22
  // Initialize a node to an empty leaf.
23
23
  static void init_leaf(NODE *node) {
24
- node->children = NULL;
25
- node->markers = NULL;
26
- node->marker_count = node->markers_size = 0;
24
+ node->children = NULL;
25
+ node->markers = NULL;
26
+ node->marker_count = node->markers_size = 0;
27
27
  }
28
28
 
29
29
  // Clear contents of a leaf, returning it to the init_leaf state.
30
30
  static void clear_leaf(NODE *node) {
31
- Free(node->markers);
32
- init_leaf(node);
31
+ Free(node->markers);
32
+ init_leaf(node);
33
33
  }
34
34
 
35
35
  // Make a leaf into an internal node with four empty leaves.
36
36
  static void subdivide(NODE *node) {
37
- if (leaf_p(node)) {
38
- NewArray(node->children, 4);
39
- for (int i = 0; i < 4; i++)
40
- init_leaf(node->children + i);
41
- }
37
+ if (leaf_p(node)) {
38
+ NewArray(node->children, 4);
39
+ for (int i = 0; i < 4; i++)
40
+ init_leaf(node->children + i);
41
+ }
42
42
  }
43
43
 
44
44
  static void clear_node(NODE *node);
@@ -46,254 +46,198 @@ static void clear_node(NODE *node);
46
46
  // Recursively clear an internal node by removing all
47
47
  // subtrees, returning this node to the init_leaf state.
48
48
  static void clear_internal(NODE *node) {
49
- for (int i = 0; i < 4; i++)
50
- clear_node(node->children + i);
51
- Free(node->children);
52
- clear_leaf(node);
49
+ for (int i = 0; i < 4; i++)
50
+ clear_node(node->children + i);
51
+ Free(node->children);
52
+ clear_leaf(node);
53
53
  }
54
54
 
55
55
  // Clear any node, returning it to the init_leaf state.
56
56
  // Recursively removes all subtrees.
57
57
  static void clear_node(NODE *node) {
58
- if (internal_p(node))
59
- clear_internal(node);
60
- else
61
- clear_leaf(node);
58
+ if (internal_p(node))
59
+ clear_internal(node);
60
+ else
61
+ clear_leaf(node);
62
62
  }
63
63
 
64
64
  // Add a marker to the given node's marker list.
65
65
  static void add_marker(NODE *node, MARKER *marker) {
66
- if (node->marker_count == node->markers_size) {
67
- node->markers_size = 2 + 2 * node->markers_size;
68
- RenewArray(node->markers, node->markers_size);
69
- }
70
- node->markers[node->marker_count++] = marker;
66
+ if (node->marker_count == node->markers_size) {
67
+ node->markers_size = 2 + 2 * node->markers_size;
68
+ RenewArray(node->markers, node->markers_size);
69
+ }
70
+ node->markers[node->marker_count++] = marker;
71
71
  }
72
72
 
73
73
  // Find a marker in the given node's marker list.
74
74
  static int find_marker(NODE *node, MARKER *marker) {
75
- for (int i = 0; i < node->marker_count; i++)
76
- if (node->markers[i] == marker)
77
- return i;
78
- return -1;
75
+ for (int i = 0; i < node->marker_count; i++)
76
+ if (node->markers[i] == marker)
77
+ return i;
78
+ return -1;
79
79
  }
80
80
 
81
81
  // Delete a marker from the given node's marker list.
82
82
  static int delete_marker(NODE *node, MARKER *marker) {
83
- int i = find_marker(node, marker);
84
- if (i != -1 && --node->marker_count != 0)
85
- node->markers[i] = node->markers[node->marker_count];
86
- return i;
83
+ int i = find_marker(node, marker);
84
+ if (i != -1 && --node->marker_count != 0)
85
+ node->markers[i] = node->markers[node->marker_count];
86
+ return i;
87
87
  }
88
88
 
89
89
  // Return non-zero iff the given bounding box lies inside the marker including its boundary.
90
- static int bounds_inside_marker(double x, double y, double w, double h, MARKER *marker) {
91
- double mx = mr_x(marker);
92
- double my = mr_y(marker);
93
- double mr = mr_r(marker);
94
- return mx - mr <= x && x + w <= mx + mr && my - mr <= y && y + h <= my + mr ;
90
+ static int bounds_inside_marker(MARKER_COORD x, MARKER_COORD y, MARKER_DISTANCE w, MARKER_DISTANCE h, MARKER *marker) {
91
+ MARKER_COORD mx = mr_x(marker);
92
+ MARKER_COORD my = mr_y(marker);
93
+ MARKER_DISTANCE mr = mr_r(marker);
94
+ return mx - mr <= x && x + w <= mx + mr && my - mr <= y && y + h <= my + mr;
95
95
  }
96
96
 
97
97
  // Return an integer code with bits showing which quadrants of the given
98
98
  // bounding box are overlapped by the given marker.
99
- static int touch_code(double x, double y, double w, double h, MARKER *marker) {
100
- double xm = x + 0.5 * w;
101
- double ym = y + 0.5 * h;
102
- int code = bit(SW) | bit(SE) | bit(NW) | bit(NE);
103
- if (mr_e(marker) < xm) code &= ~(bit(NE) | bit(SE));
104
- if (mr_w(marker) > xm) code &= ~(bit(NW) | bit(SW));
105
- if (mr_n(marker) < ym) code &= ~(bit(NW) | bit(NE));
106
- if (mr_s(marker) > ym) code &= ~(bit(SW) | bit(SE));
107
- return code;
99
+ static int touch_code(MARKER_COORD x, MARKER_COORD y, MARKER_DISTANCE w, MARKER_DISTANCE h, MARKER *marker) {
100
+ MARKER_COORD xm = x + 0.5 * w;
101
+ MARKER_COORD ym = y + 0.5 * h;
102
+ int code = bit(SW) | bit(SE) | bit(NW) | bit(NE);
103
+ if (mr_e(marker) < xm) code &= ~(bit(NE) | bit(SE));
104
+ if (mr_w(marker) > xm) code &= ~(bit(NW) | bit(SW));
105
+ if (mr_n(marker) < ym) code &= ~(bit(NW) | bit(NE));
106
+ if (mr_s(marker) > ym) code &= ~(bit(SW) | bit(SE));
107
+ return code;
108
108
  }
109
109
 
110
110
  // Insert the given marker into the quadtree with given root and corresponding bounding box,
111
111
  // subdividing no more than the given number of levels.
112
- static void insert(NODE *node, int levels, double x, double y, double w, double h, MARKER *marker) {
113
- if (bounds_inside_marker(x, y, w, h, marker) || levels == 0)
114
- add_marker(node, marker);
115
- else {
116
- if (leaf_p(node))
117
- subdivide(node);
118
- int code = touch_code(x, y, w, h, marker);
119
- for (int q = 0; q < 4; q++)
120
- if (code & bit(q)) {
121
- QUADRANT_DECL(q, qx, qy, qw, qh, x, y, w, h);
122
- insert(node->children + q, levels - 1, qx, qy, qw, qh, marker);
123
- }
124
- }
112
+ static void insert(NODE *node, int levels, MARKER_COORD x, MARKER_COORD y, MARKER_DISTANCE w, MARKER_DISTANCE h, MARKER *marker) {
113
+ if (bounds_inside_marker(x, y, w, h, marker) || levels == 0)
114
+ add_marker(node, marker);
115
+ else {
116
+ if (leaf_p(node))
117
+ subdivide(node);
118
+ int code = touch_code(x, y, w, h, marker);
119
+ for (int q = 0; q < 4; q++)
120
+ if (code & bit(q)) {
121
+ QUADRANT_DECL(q, qx, qy, qw, qh, x, y, w, h);
122
+ insert(node->children + q, levels - 1, qx, qy, qw, qh, marker);
123
+ }
124
+ }
125
125
  }
126
126
 
127
127
  // A helper function that returns true iff the given array of 4 child quadtrees are all empty leaves.
128
128
  static int empty_leaves_p(NODE *children) {
129
- for (int i = 0; i < 4; i++)
130
- if (internal_p(children + i) || children[i].marker_count > 0)
131
- return 0;
132
- return 1;
129
+ for (int i = 0; i < 4; i++)
130
+ if (internal_p(children + i) || children[i].marker_count > 0)
131
+ return 0;
132
+ return 1;
133
133
  }
134
134
 
135
135
  // Delete the given marker from the quadtree with given root and corresponding bounding box,
136
136
  // trimming any remaining empty leaves.
137
- static void delete(NODE *node, int levels, double x, double y, double w, double h, MARKER *marker) {
138
- if (bounds_inside_marker(x, y, w, h, marker) || levels == 0)
139
- delete_marker(node, marker);
140
- else if (internal_p(node)){
141
- int code = touch_code(x, y, w, h, marker);
142
- for (int q = 0; q < 4; q++)
143
- if (code & bit(q)) {
144
- QUADRANT_DECL(q, qx, qy, qw, qh, x, y, w, h);
145
- delete(node->children + q, levels - 1, qx, qy, qw, qh, marker);
146
- }
147
- if (empty_leaves_p(node->children))
148
- Free(node->children);
149
- }
137
+ static void delete(NODE *node, int levels,
138
+ MARKER_COORD x, MARKER_COORD y, MARKER_DISTANCE w, MARKER_DISTANCE h,
139
+ MARKER *marker) {
140
+ if (bounds_inside_marker(x, y, w, h, marker) || levels == 0)
141
+ delete_marker(node, marker);
142
+ else if (internal_p(node)){
143
+ int code = touch_code(x, y, w, h, marker);
144
+ for (int q = 0; q < 4; q++)
145
+ if (code & bit(q)) {
146
+ QUADRANT_DECL(q, qx, qy, qw, qh, x, y, w, h);
147
+ delete(node->children + q, levels - 1, qx, qy, qw, qh, marker);
148
+ }
149
+ if (empty_leaves_p(node->children))
150
+ Free(node->children);
151
+ }
150
152
  }
151
153
 
152
154
  // Local struct to hold information about the nearest marker seen so far in a search.
153
155
  struct nearest_info {
154
156
  MARKER_INFO *info;
155
157
  MARKER *target, *nearest;
156
- double distance;
158
+ MARKER_DISTANCE distance;
157
159
  };
158
160
 
159
161
  // Use the marker list of the given node to update nearest information with
160
162
  // respect to the given marker.
161
163
  static void update_nearest(NODE *node, struct nearest_info *nearest_info) {
162
- for (int i = 0; i < node->marker_count; i++) {
163
- // This < assumes the markers are in an array. It sustains the invariant.
164
- if (node->markers[i] < nearest_info->target) {
165
- double d = mr_distance(nearest_info->info, nearest_info->target, node->markers[i]);
166
- if (d < nearest_info->distance) {
167
- nearest_info->distance = d;
168
- nearest_info->nearest = node->markers[i];
169
- }
170
- }
171
- }
164
+ for (int i = 0; i < node->marker_count; i++) {
165
+ // This < assumes the markers are in an array. It sustains the invariant.
166
+ if (node->markers[i] < nearest_info->target) {
167
+ MARKER_DISTANCE d = mr_distance(nearest_info->info, nearest_info->target, node->markers[i]);
168
+ if (d < nearest_info->distance) {
169
+ nearest_info->distance = d;
170
+ nearest_info->nearest = node->markers[i];
171
+ }
172
+ }
173
+ }
172
174
  }
173
175
 
174
176
  // Search out the nearest marker that overlaps the given one. This just visits every
175
177
  // quad that overlaps the given marker and remembers the closest marker it sees. The
176
178
  // circle distance function renders quite impossible the ruling out of quads as in
177
179
  // nearest point neighbor search.
178
- static void search_for_nearest(NODE *node, double x, double y, double w, double h, struct nearest_info *nearest_info) {
179
- update_nearest(node, nearest_info);
180
- if (internal_p(node)) {
181
- // Search the children that include some part of the marker.
182
- int code = touch_code(x, y, w, h, nearest_info->target);
183
- for (int q = 0; q < 4; q++)
184
- if (code & bit(q)) {
185
- QUADRANT_DECL(q, qx, qy, qw, qh, x, y, w, h);
186
- search_for_nearest(node->children + q, qx, qy, qw, qh, nearest_info);
187
- }
188
- }
189
- }
190
-
191
- static MARKER *nearest(MARKER_INFO *info, NODE *node, double x, double y, double w, double h, MARKER *marker) {
192
- struct nearest_info nearest_info[1] = {{ info, marker, NULL, 0 }};
193
- search_for_nearest(node, x, y, w, h, nearest_info);
194
- return nearest_info->nearest;
180
+ static void search_for_nearest(NODE *node,
181
+ MARKER_COORD x, MARKER_COORD y, MARKER_DISTANCE w, MARKER_DISTANCE h,
182
+ struct nearest_info *nearest_info) {
183
+ update_nearest(node, nearest_info);
184
+ if (internal_p(node)) {
185
+ // Search the children that include some part of the marker.
186
+ int code = touch_code(x, y, w, h, nearest_info->target);
187
+ for (int q = 0; q < 4; q++)
188
+ if (code & bit(q)) {
189
+ QUADRANT_DECL(q, qx, qy, qw, qh, x, y, w, h);
190
+ search_for_nearest(node->children + q, qx, qy, qw, qh, nearest_info);
191
+ }
192
+ }
193
+ }
194
+
195
+ static MARKER *nearest(MARKER_INFO *info, NODE *node,
196
+ MARKER_COORD x, MARKER_COORD y, MARKER_DISTANCE w, MARKER_DISTANCE h,
197
+ MARKER *marker) {
198
+ struct nearest_info nearest_info[1] = {{ info, marker, NULL, 0 }};
199
+ search_for_nearest(node, x, y, w, h, nearest_info);
200
+ return nearest_info->nearest;
195
201
  }
196
202
 
197
203
  void qt_init(QUADTREE *qt) {
198
- init_leaf(qt->root);
199
- qt->x = qt->y = qt->w = qt->h = 0;
204
+ init_leaf(qt->root);
205
+ qt->x = qt->y = qt->w = qt->h = 0;
200
206
  }
201
207
 
202
- void qt_setup(QUADTREE *qt, int max_depth, double x, double y, double w, double h, MARKER_INFO *info) {
203
- qt->x = x;
204
- qt->y = y;
205
- qt->w = w;
206
- qt->h = h;
207
- qt->max_depth = max_depth;
208
- qt->info = info;
208
+ void qt_setup(QUADTREE *qt, int max_depth,
209
+ MARKER_COORD x, MARKER_COORD y, MARKER_DISTANCE w, MARKER_DISTANCE h,
210
+ MARKER_INFO *info) {
211
+ qt->x = x;
212
+ qt->y = y;
213
+ qt->w = w;
214
+ qt->h = h;
215
+ qt->max_depth = max_depth;
216
+ qt->info = info;
209
217
  }
210
218
 
211
219
  void qt_clear(QUADTREE *qt) {
212
- clear_node(qt->root);
213
- qt_init(qt);
220
+ clear_node(qt->root);
221
+ qt_init(qt);
214
222
  }
215
223
 
216
224
  void qt_insert(QUADTREE *qt, MARKER *marker) {
217
- double x = mr_x(marker);
218
- double y = mr_y(marker);
219
- double r = mr_r(marker);
220
- if (x + r >= qt->x && x - r <= qt->x + qt->w && y + r >= qt->y && y - r <= qt->y + qt->h)
221
- insert(qt->root, qt->max_depth, qt->x, qt->y, qt->w, qt->h, marker);
225
+ MARKER_COORD x = mr_x(marker);
226
+ MARKER_COORD y = mr_y(marker);
227
+ MARKER_DISTANCE r = mr_r(marker);
228
+ if (x + r >= qt->x && x - r <= qt->x + qt->w && y + r >= qt->y && y - r <= qt->y + qt->h)
229
+ insert(qt->root, qt->max_depth, qt->x, qt->y, qt->w, qt->h, marker);
222
230
  }
223
231
 
224
232
  void qt_delete(QUADTREE *qt, MARKER *marker) {
225
- delete(qt->root, qt->max_depth, qt->x, qt->y, qt->w, qt->h, marker);
233
+ delete(qt->root, qt->max_depth, qt->x, qt->y, qt->w, qt->h, marker);
226
234
  }
227
235
 
228
236
  MARKER *qt_nearest(QUADTREE *qt, MARKER *marker) {
229
- return nearest(qt->info, qt->root, qt->x, qt->y, qt->w, qt->h, marker);
237
+ return nearest(qt->info, qt->root, qt->x, qt->y, qt->w, qt->h, marker);
230
238
  }
231
239
 
232
240
  int qt_nearest_wrt(MARKER *markers, QUADTREE *qt, int a) {
233
- MARKER *nearest = qt_nearest(qt, markers + a);
234
- return nearest ? (int)(nearest - markers) : -1;
235
- }
236
-
237
- #ifndef EXCLUDE_UNIT_TEST
238
-
239
- static void draw(FILE *f, NODE *node, double x, double y, double w, double h) {
240
- emit_rectangle(f, x, y, w, h);
241
- emit_marker_ptr_array(f, node->markers, node->marker_count);
242
- if (internal_p(node)) {
243
- for (int q = 0; q < 4; q++) {
244
- QUADRANT_DECL(q, qx, qy, qw, qh, x, y, w, h);
245
- draw(f, node->children + q, qx, qy, qw, qh);
246
- }
247
- }
248
- }
249
-
250
- static void draw_nearest(FILE *f, MARKER *markers, MARKER **nearest_markers, int n_markers) {
251
- for (int i = 0; i < n_markers; i++) {
252
- if (nearest_markers[i])
253
- emit_segment(f, markers + i, nearest_markers[i]);
254
- }
241
+ MARKER *nearest = qt_nearest(qt, markers + a);
242
+ return nearest ? (int)(nearest - markers) : -1;
255
243
  }
256
-
257
- int qt_draw(QUADTREE *qt, MARKER *markers, MARKER **nearest_markers, int n_markers, const char *name) {
258
- char buf[1024];
259
- sprintf(buf, "test/%s.js", name);
260
- FILE *f = fopen(buf, "w");
261
- if (!f)
262
- return -1;
263
- fprintf(f, "var %s = [\n", name);
264
- draw(f, qt->root, qt->x, qt->y, qt->w, qt->h);
265
- draw_nearest(f, markers, nearest_markers, n_markers);
266
- fprintf(f, "];\n");
267
- fclose(f);
268
- return EXIT_SUCCESS;
269
- }
270
-
271
- int qt_test(int size) {
272
- QUADTREE_DECL(qt);
273
- MARKER_INFO_DECL(info);
274
- MARKER *markers, **nearest_markers;
275
- NewArray(markers, size);
276
- NewArray(nearest_markers, size);
277
- set_random_markers(info, markers, size);
278
- qt_setup(qt, 5, 0, 0, 1024, 724, info);
279
- fprintf(stderr, "inserting %d:\n", size);
280
- for (int i = 0; i < size; i++) {
281
- qt_insert(qt, markers + i);
282
- }
283
- fprintf(stderr, "inserted %d\n", size);
284
- for (int i = 0; i < size; i++) {
285
- nearest_markers[i] = qt_nearest(qt, markers + i);
286
- }
287
- fprintf(stderr, "looked up %d\n", size);
288
- qt_draw(qt, markers, nearest_markers, size, "qt");
289
- fprintf(stderr, "drew %d\n", size);
290
- for (int i = 0; i < size; i++) {
291
- qt_delete(qt, markers + i);
292
- }
293
- fprintf(stderr, "after delete all, root is %s\n",
294
- leaf_p(qt->root) ? "leaf (ok)" : "internal (not ok)");
295
-
296
- return EXIT_SUCCESS;
297
- }
298
-
299
- #endif