-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathQuadrantTree.java
More file actions
110 lines (100 loc) · 4.12 KB
/
QuadrantTree.java
File metadata and controls
110 lines (100 loc) · 4.12 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
public class QuadrantTree {
private QTreeNode root;
public QuadrantTree(int[][] thePixels) {
// The root node will represent the entire image.
// (0,0) is the upper-left corner, and the size is the length of the pixel array.
// The color is the average color of the entire pixel array.
this.root = buildTree(thePixels, 0, 0, thePixels.length);
}
private QTreeNode buildTree(int[][] pixels, int x, int y, int size) {
if (size == 1) {
// Base case: each leaf node represents a single pixel.
return new QTreeNode(null, x, y, size, pixels[y][x]);
} else {
int newSize = size / 2;
int avgColor = Gui.averageColor(pixels, x, y, size);
QTreeNode node = new QTreeNode(new QTreeNode[4], x, y, size, avgColor);
// Recursively build the tree for each quadrant.
node.setChild(buildTree(pixels, x, y, newSize), 0); // Upper-left quadrant
node.setChild(buildTree(pixels, x + newSize, y, newSize), 1); // Upper-right quadrant
node.setChild(buildTree(pixels, x, y + newSize, newSize), 2); // Lower-left quadrant
node.setChild(buildTree(pixels, x + newSize, y + newSize, newSize), 3); // Lower-right quadrant
// Set the parent for each child
for (int i = 0; i < 4; i++) {
if (node.getChild(i) != null) {
node.getChild(i).setParent(node);
}
}
return node;
}
}
public QTreeNode getRoot() {
return root;
}
public ListNode<QTreeNode> getPixels(QTreeNode r, int theLevel) {
if (r == null) {
return null;
}
if (theLevel == 0) {
return new ListNode<>(r);
} else if (r.isLeaf()) {
return new ListNode<>(r); // If it's a leaf, return it regardless of the level
} else {
ListNode<QTreeNode> list = null;
for (int i = 0; i < 4; i++) {
ListNode<QTreeNode> childList = getPixels(r.getChild(i), theLevel - 1);
list = concatenateLists(list, childList);
}
return list;
}
}
// Helper method to concatenate two lists
private ListNode<QTreeNode> concatenateLists(ListNode<QTreeNode> list1, ListNode<QTreeNode> list2) {
if (list1 == null) {
return list2;
}
ListNode<QTreeNode> temp = list1;
while (temp.getNext() != null) {
temp = temp.getNext();
}
temp.setNext(list2);
return list1;
}
// Method to find all nodes matching a certain color at a certain level
public Duple findMatching(QTreeNode r, int theColor, int theLevel) {
if (r == null) {
return new Duple(null, 0);
}
if (theLevel == 0 || r.isLeaf()) {
if (Gui.similarColor(r.getColor(), theColor)) {
return new Duple(new ListNode<>(r), 1);
} else {
return new Duple(null, 0);
}
} else {
Duple result = new Duple(null, 0);
for (int i = 0; i < 4; i++) {
Duple childDuple = findMatching(r.getChild(i), theColor, theLevel - 1);
result.setFront(concatenateLists(result.getFront(), childDuple.getFront()));
result.setCount(result.getCount() + childDuple.getCount());
}
return result;
}
}
// Method to find a node that contains a certain point at a certain level
public QTreeNode findNode(QTreeNode r, int theLevel, int x, int y) {
if (r == null || !r.contains(x, y)) {
return null;
}
if (theLevel == 0 || r.isLeaf()) {
return r;
}
int midX = r.getx() + r.getSize() / 2;
int midY = r.gety() + r.getSize() / 2;
if (x < midX) {
return x < midY ? findNode(r.getChild(0), theLevel - 1, x, y) : findNode(r.getChild(2), theLevel - 1, x, y);
} else {
return x < midY ? findNode(r.getChild(1), theLevel - 1, x, y) : findNode(r.getChild(3), theLevel - 1, x, y);
}
}
}