aboutsummaryrefslogtreecommitdiff
path: root/Week8 Quadtrees/src/qtrees/QTree.java
blob: 24fa5e089e8d7bb3ae398962e21c1cd64cea43c2 (plain) (blame)
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
package qtrees;

import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Representation of a Quad-tree
 * @author Camil Staps, s4498062
 */
public class QTree {
    /** the root of the tree */
    QTNode root;
    
    /**
     * Construct the tree based on an ASCII representation of a bitstream on a reader
     * @param input the reader
     */
    public QTree( Reader input ) {
        root = readQTree( input );
    }
    
    /**
     * Construct the tree based on a bitmap
     * @param bitmap the bitmap
     */
    public QTree( Bitmap bitmap ) {
        root = bitmap2QTree( 0, 0,  bitmap.getWidth(), bitmap );
    }

    /**
     * Fill a bitmap based on this tree
     * @param bitmap the bitmap
     */
    public void fillBitmap ( Bitmap bitmap ) {
        root.fillBitmap(0, 0, bitmap.getWidth(), bitmap);
    }

    /**
     * Write the quad-tree as compressed bitstream
     * @param sb the Writer to write to
     * @throws IOException is passed on from Writer
     */
    public void writeQTree( Writer sb ) throws IOException {
        root.writeNode( sb );
    }
    
    /**
     * Read a Quad-tree node based on an ASCII representation of a bitstream on a Reader
     * @param input the Reader
     * @return the node
     */
    private static QTNode readQTree( Reader input ) {
        try {
            int read = input.read();
            if (read == '1') {
                GreyNode node = new GreyNode();
                for (int i = 0; i < 4; i++)
                    node.setChild(i, readQTree(input));
                return node;
            } else {
                read = input.read();
                if (read == '1') {
                    return new WhiteLeaf();
                } else {
                    return new BlackLeaf();
                }
            }
        } catch (IOException ex) {
            Logger.getLogger(QTree.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }
    
    /**
     * Get a (compressed) node from a (part of a) bitmap
     * @param x the x coordinate of the top left corner
     * @param y the y coordinate of the top left corner
     * @param width the width of the part to read
     * @param bitmap the bitmap
     * @return the (compressed) node
     */
    public static QTNode bitmap2QTree( int x, int y, int width, Bitmap bitmap ) {
        if (width == 1) {
            if (bitmap.getBit(x,y)) {
                return new WhiteLeaf();
            } else {
                return new BlackLeaf();
            }
        } else {
            GreyNode node = new GreyNode();
            node.setChild(0, bitmap2QTree(x, y, width / 2, bitmap));
            node.setChild(1, bitmap2QTree(x + width / 2, y, width / 2, bitmap));
            node.setChild(2, bitmap2QTree(x + width / 2, y + width / 2, width / 2, bitmap));
            node.setChild(3, bitmap2QTree(x, y + width / 2, width / 2, bitmap));
            return node.compress();
        }
    }

}