quadtree 1.0.2 → 1.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.
- checksums.yaml +4 -4
- data/lib/quadtree/point.rb +13 -12
- data/lib/quadtree/quadtree.rb +43 -42
- data/lib/quadtree/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d5db2d5026956693fb12005b6f413baec2df1c55336d54612c69c2d2ea5daee7
|
4
|
+
data.tar.gz: 64fad915c832732dce1b3d8f5d4e09153d6c2a5d0eacbe341ae9e36432ae910f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ba095f44c64f53fe6c708a55e59b2da9e43f4317c309fb8677ca24d0e9538c6104eec212c3ce05e092b17816a0b226e2a114ee86b16b5ce92cfc1a8dd582a681
|
7
|
+
data.tar.gz: 3d2ea5d459b276877dae1e42300f5b457c88b557cd88dc3240c4f6864cb430c0044c5ee27ceac0d0d6b1b2a1ee573f627548d12373a66eb4760f0b9c09f91712
|
data/lib/quadtree/point.rb
CHANGED
@@ -8,16 +8,17 @@ module Quadtree
|
|
8
8
|
# @return [Float] Y coordinate
|
9
9
|
attr_accessor :y
|
10
10
|
|
11
|
-
# Payload attached to this {Point}.
|
11
|
+
# @return [Object] Payload attached to this {Point}.
|
12
12
|
attr_accessor :data
|
13
13
|
|
14
14
|
# Create a new {Point}.
|
15
15
|
#
|
16
|
-
# @param [Float] x X coordinate
|
17
|
-
# @param [Float] y Y coordinate
|
16
|
+
# @param [Float, Numeric] x X coordinate.
|
17
|
+
# @param [Float, Numeric] y Y coordinate.
|
18
|
+
# @param [Object] data {Point} payload (optional).
|
18
19
|
def initialize(x, y, data=nil)
|
19
|
-
@x = x
|
20
|
-
@y = y
|
20
|
+
@x = x.to_f
|
21
|
+
@y = y.to_f
|
21
22
|
@data = data unless data.nil?
|
22
23
|
end
|
23
24
|
|
@@ -48,17 +49,17 @@ module Quadtree
|
|
48
49
|
# earth's radius
|
49
50
|
r = 6371 * 1000.0
|
50
51
|
# coverting degrees to radians
|
51
|
-
lat1 = self.y * (Math::PI / 180)
|
52
|
-
lat2 = other.y * (Math::PI / 180)
|
53
|
-
dlat = (other.y - self.y) * (Math::PI / 180)
|
54
|
-
dlon = (other.x - self.x) * (Math::PI / 180)
|
52
|
+
lat1 = self.y * (Math::PI / 180.0)
|
53
|
+
lat2 = other.y * (Math::PI / 180.0)
|
54
|
+
dlat = (other.y - self.y) * (Math::PI / 180.0)
|
55
|
+
dlon = (other.x - self.x) * (Math::PI / 180.0)
|
55
56
|
|
56
57
|
# a = sin²(Δφ/2) + cos φ_1 ⋅ cos φ_2 ⋅ sin²(Δλ/2)
|
57
|
-
a = Math.sin(dlat / 2) * Math.sin(dlat / 2) +
|
58
|
+
a = Math.sin(dlat / 2.0) * Math.sin(dlat / 2.0) +
|
58
59
|
Math.cos(lat1) * Math.cos(lat2) *
|
59
|
-
Math.sin(dlon / 2) * Math.sin(dlon / 2)
|
60
|
+
Math.sin(dlon / 2.0) * Math.sin(dlon / 2.0)
|
60
61
|
# c = 2 ⋅ atan2( √a, √(1−a) )
|
61
|
-
c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a))
|
62
|
+
c = 2.0 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a))
|
62
63
|
# d = R ⋅ c
|
63
64
|
return r * c
|
64
65
|
end
|
data/lib/quadtree/quadtree.rb
CHANGED
@@ -28,29 +28,29 @@ module Quadtree
|
|
28
28
|
attr_accessor :south_east
|
29
29
|
|
30
30
|
def initialize(boundary)
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
31
|
+
self.boundary = boundary
|
32
|
+
self.points = []
|
33
|
+
self.north_west = nil
|
34
|
+
self.north_east = nil
|
35
|
+
self.south_west = nil
|
36
|
+
self.south_east = nil
|
37
37
|
end
|
38
38
|
|
39
39
|
# @param [Point] point
|
40
40
|
# @return [Boolean]
|
41
41
|
def insert!(point)
|
42
|
-
return false unless
|
42
|
+
return false unless self.boundary.contains_point?(point)
|
43
43
|
|
44
|
-
if points.size < NODE_CAPACITY
|
45
|
-
|
44
|
+
if self.points.size < NODE_CAPACITY
|
45
|
+
self.points << point
|
46
46
|
return true
|
47
47
|
end
|
48
48
|
|
49
|
-
subdivide! if
|
50
|
-
return true if
|
51
|
-
return true if
|
52
|
-
return true if
|
53
|
-
return true if
|
49
|
+
subdivide! if self.north_west.nil?
|
50
|
+
return true if self.north_west.insert!(point)
|
51
|
+
return true if self.north_east.insert!(point)
|
52
|
+
return true if self.south_west.insert!(point)
|
53
|
+
return true if self.south_east.insert!(point)
|
54
54
|
|
55
55
|
false
|
56
56
|
end
|
@@ -64,21 +64,21 @@ module Quadtree
|
|
64
64
|
points_in_range = []
|
65
65
|
|
66
66
|
# Automatically abort if the range does not intersect this quad
|
67
|
-
return points_in_range unless
|
67
|
+
return points_in_range unless self.boundary.intersects?(range)
|
68
68
|
|
69
69
|
# Check objects at this quad level
|
70
|
-
|
70
|
+
self.points.each do |point|
|
71
71
|
points_in_range << point if range.contains_point?(point)
|
72
72
|
end
|
73
73
|
|
74
74
|
# Terminate here, if there are no children
|
75
|
-
return points_in_range if
|
75
|
+
return points_in_range if self.north_west.nil?
|
76
76
|
|
77
77
|
# Otherwise, add the points from the children
|
78
|
-
points_in_range +=
|
79
|
-
points_in_range +=
|
80
|
-
points_in_range +=
|
81
|
-
points_in_range +=
|
78
|
+
points_in_range += self.north_west.query_range(range)
|
79
|
+
points_in_range += self.north_east.query_range(range)
|
80
|
+
points_in_range += self.south_west.query_range(range)
|
81
|
+
points_in_range += self.south_east.query_range(range)
|
82
82
|
|
83
83
|
points_in_range
|
84
84
|
end
|
@@ -87,29 +87,30 @@ module Quadtree
|
|
87
87
|
|
88
88
|
# @return [Boolean]
|
89
89
|
def subdivide!
|
90
|
-
left_edge =
|
91
|
-
right_edge =
|
92
|
-
top_edge =
|
93
|
-
bottom_edge =
|
94
|
-
quad_half_dimension =
|
95
|
-
|
96
|
-
north_west_center =
|
97
|
-
north_east_center =
|
98
|
-
south_east_center =
|
99
|
-
south_west_center =
|
100
|
-
|
101
|
-
north_west_boundary =
|
102
|
-
north_east_boundary =
|
103
|
-
south_west_boundary =
|
104
|
-
south_east_boundary =
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
90
|
+
left_edge = self.boundary.left
|
91
|
+
right_edge = self.boundary.right
|
92
|
+
top_edge = self.boundary.top
|
93
|
+
bottom_edge = self.boundary.bottom
|
94
|
+
quad_half_dimension = self.boundary.half_dimension / 2
|
95
|
+
|
96
|
+
north_west_center = Point.new left_edge + quad_half_dimension, top_edge - quad_half_dimension
|
97
|
+
north_east_center = Point.new right_edge - quad_half_dimension, top_edge - quad_half_dimension
|
98
|
+
south_east_center = Point.new left_edge + quad_half_dimension, bottom_edge + quad_half_dimension
|
99
|
+
south_west_center = Point.new right_edge - quad_half_dimension, bottom_edge + quad_half_dimension
|
100
|
+
|
101
|
+
north_west_boundary = AxisAlignedBoundingBox.new north_west_center, quad_half_dimension
|
102
|
+
north_east_boundary = AxisAlignedBoundingBox.new north_east_center, quad_half_dimension
|
103
|
+
south_west_boundary = AxisAlignedBoundingBox.new south_west_center, quad_half_dimension
|
104
|
+
south_east_boundary = AxisAlignedBoundingBox.new south_east_center, quad_half_dimension
|
105
|
+
|
106
|
+
self.north_west = Quadtree.new north_west_boundary
|
107
|
+
self.north_east = Quadtree.new north_east_boundary
|
108
|
+
self.south_west = Quadtree.new south_west_boundary
|
109
|
+
self.south_east = Quadtree.new south_east_boundary
|
110
110
|
|
111
111
|
true
|
112
|
-
rescue
|
112
|
+
rescue => error
|
113
|
+
puts "Something went wrong: #{error}"
|
113
114
|
false
|
114
115
|
end
|
115
116
|
end
|
data/lib/quadtree/version.rb
CHANGED