QuadTree.insert()   F
last analyzed

Complexity

Conditions 11

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 11
dl 0
loc 27
rs 3.1764

How to fix   Complexity   

Complexity

Complex classes like QuadTree.insert() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
from ed2d.physics.rectangle import Rectangle
2
3
class QuadTree(object):
4
	def __init__(self, lvl, bounds):
5
		self.level = lvl
6
		self.bounds = bounds
7
		self.max_objects = 1
8
		self.max_levels = 5
9
		self.objects = []
10
		self.nodes = []
11
12
	def clear(self):
13
		self.objects = []
14
		for i in range(len(self.nodes)):
15
			self.nodes[i].clear()
16
		self.nodes = []
17
18
	# Splits the node into 4 subnodes
19
	def split(self):
20
		subWidth = int(self.bounds.getWidth() / 2)
21
		subHeight = int(self.bounds.getHeight() / 2)
22
23
		x = int(self.bounds.getX())
24
		y = int(self.bounds.getY())
25
26
		# Top Right Node
27
		self.nodes.append(QuadTree(self.level + 1, Rectangle(x + subWidth, y, subWidth, subHeight)))
28
29
		# Top Left Node
30
		self.nodes.append(QuadTree(self.level + 1, Rectangle(x, y, subWidth, subHeight)))
31
32
		# Bottom Left Node
33
		self.nodes.append(QuadTree(self.level + 1, Rectangle(x, y + subHeight, subWidth, subHeight)))
34
35
		# Bottom Right Node
36
		self.nodes.append(QuadTree(self.level + 1, Rectangle(x + subWidth, y + subHeight, subWidth, subHeight)))
37
38
	# Determine which node the objects belongs to.
39
	# -1 means object cannot completely fit within
40
	# A child node and is part of the parent node
41
	def getIndex(self, obj):
42
		index = -1
43
		verticalMidPoint = self.bounds.getX() + (self.bounds.getWidth() / 2)
44
		horizontalMidPoint = self.bounds.getY() + (self.bounds.getHeight() / 2)
45
46
		# Object can completely fit whitin the top quadrants
47
		topQuadrant = (obj.getY() < horizontalMidPoint) and ((obj.getY() + obj.getHeight()) < horizontalMidPoint)
48
		# Object can completely fit whitin the bottom quadrants
49
		bottomQuadrant = (obj.getY() > horizontalMidPoint)
50
51
		# Object can completely fit within left quadrants
52
		if ((obj.getX() < verticalMidPoint) and ((obj.getX() + obj.getWidth()) < verticalMidPoint)):
53
			if topQuadrant:
54
				index = 1
55
			elif bottomQuadrant:
56
				index = 2
57
		# Object can completely fit within right quadrants
58
		elif (obj.getX() > verticalMidPoint):
59
			if topQuadrant:
60
				index = 0
61
			elif bottomQuadrant:
62
				index = 3
63
		return index
64
65
	# Insert the object into the quadtree.
66
	# If the node exdees the capacity, it will split and add all
67
	# objects to their corresponding nodes.
68
	def insert(self, obj):
69
		if obj is None:
70
			return
71
72
		if isinstance(obj, list):
73
			for i in range(len(obj)):
74
				self.insert(obj[i])
75
			return
76
77
		if len(self.nodes):
78
			index = self.getIndex(obj)
79
			if index is not -1:
80
				self.nodes[index].insert(obj)
81
				return
82
83
		self.objects.append(obj)
84
85
		if (len(self.objects) > self.max_objects) and (self.level < self.max_levels):
86
			if len(self.nodes) is 0:
87
				self.split()
88
			i = 0
89
			while (i < len(self.objects)):
90
				index = self.getIndex(self.objects[i])
91
				if index is not -1:
92
					self.nodes[index].insert(self.objects.pop(i))
93
				else:
94
					i += 1
95
96
	def retriveAll(self, returnObjects):
97
		for i in range(len(self.nodes)):
98
			self.nodes[i].retriveAll(returnObjects)
99
100
		for i in range(len(self.objects)):
101
			returnObjects.append(self.objects[i])
102
		return returnObjects
103
104
	def findObjects(self, returnedObjects, obj):
105
		index = self.getIndex(obj)
106
		if index is not -1 and len(self.nodes):
107
			self.nodes[index].findObjects(returnedObjects, obj)
108
		for i in range(len(self.objects)):
109
			returnedObjects.append(self.objects[i])
110
		return returnedObjects
111