-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathBHTree.java
More file actions
127 lines (122 loc) · 4.4 KB
/
BHTree.java
File metadata and controls
127 lines (122 loc) · 4.4 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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
public class BHTree {
private Body body; // body or aggregate body stored in this node
private Quad quad; // square region that the tree represents
private BHTree NW; // tree representing northwest quadrant
private BHTree NE; // tree representing northeast quadrant
private BHTree SW; // tree representing southwest quadrant
private BHTree SE; // tree representing southeast quadrant
private double theta = 0.5; //Theta is used for calculating interactions
//Create and initialize a new bhtree. Initially, all nodes are null and will be filled by recursion
//Each BHTree represents a quadrant and a body that represents all bodies inside the quadrant
public BHTree(Quad q) {
this.quad=q;
this.body=null;
this.NW=null;
this.NE=null;
this.SW=null;
this.SE=null;
}
//If all nodes of the BHTree are null, then the quadrant represents a single body and it is "external"
public Boolean isExternal(BHTree t) {
if (t.NW==null && t.NE==null && t.SW==null && t.SE==null) return true;
else return false;
}
//We have to populate the tree with bodies. We start at the current tree and recursively travel through the branches
public void insert(Body b) {
//If there's not a body there already, put the body there.
if (this.body==null) {
this.body=b;
}
//If there's already a body there, but it's not an external node
//combine the two bodies and figure out which quadrant of the
//tree it should be located in. Then recursively update the nodes below it.
else if (this.isExternal(this)==false) {
this.body=body.add(this.body,b);
Quad northwest = this.quad.NW();
if (b.in(northwest)) {
if (this.NW==null) {this.NW= new BHTree(northwest);}
NW.insert(b);
}
else {
Quad northeast = this.quad.NE();
if (b.in(northeast)) {
if (this.NE==null) {this.NE= new BHTree(northeast);}
NE.insert(b);
}
else {
Quad southeast = this.quad.SE();
if (b.in(southeast)) {
if (this.SE==null) {this.SE= new BHTree(southeast);}
SE.insert(b);
}
else {
Quad southwest = this.quad.SW();
if(this.SW==null) {this.SW= new BHTree(southwest);}
SW.insert(b);
}
}
}
}
//If the node is external and contains another body, create BHTrees
//where the bodies should go, update the node, and end
//(do not do anything recursively)
else if (this.isExternal(this)) {
Body c = this.body;
Quad northwest = this.quad.NW();
if (c.in(northwest)) {
if (this.NW==null) {this.NW= new BHTree(northwest);}
NW.insert(c);
}
else {
Quad northeast = this.quad.NE();
if (c.in(northeast)) {
if (this.NE==null) {this.NE= new BHTree(northeast);}
NE.insert(c);
}
else {
Quad southeast = this.quad.SE();
if (c.in(southeast)) {
if (this.SE==null) {this.SE= new BHTree(southeast);}
SE.insert(c);
}
else {
Quad southwest = this.quad.SW();
if(this.SW==null) {this.SW= new BHTree(southwest);}
SW.insert(c);
}
}
}
this.insert(b);
}
}
//Start at the main node of the tree. Then, recursively go each branch
//Until either we reach an external node or we reach a node that is sufficiently
//far away that the external nodes would not matter much.
public void updateForce(Body b) {
if (this.isExternal(this)) {
if (this.body!=b) b.addForce(this.body);
}
else if (this.quad.length()/(this.body.distanceTo(b)) < theta){
b.addForce(this.body);
}
else {
if (this.NW!=null) this.NW.updateForce(b);
if (this.SW!=null) this.SW.updateForce(b);
if (this.SE!=null) this.SE.updateForce(b);
if (this.NE!=null) this.NE.updateForce(b);
}
}
// convert to string representation for output
public String toString() {
if(NE != null || NW!=null || SW!=null || SE!=null) return "*" + body + "\n" + NW + NE + SW + SE;
else return " " + body + "\n";
}
//draw the invoking Quad in Turtle graphics
public void draw() {
this.quad.draw();
if (this.NW!=null) this.NW.draw();
if (this.SW!=null) this.SW.draw();
if (this.SE!=null) this.SE.draw();
if (this.NE!=null) this.NE.draw();
}
}