Class: Contrek::Concurrent::Polyline
- Inherits:
-
Object
- Object
- Contrek::Concurrent::Polyline
show all
- Includes:
- Partitionable
- Defined in:
- lib/contrek/finder/concurrent/polyline.rb
Constant Summary
collapse
- TRACKED_OUTER =
1 << 0
- TRACKED_INNER =
1 << 1
Instance Attribute Summary collapse
#parts
Class Method Summary
collapse
Instance Method Summary
collapse
#add_part, #find_first_part_by_position, #insert_after, #inspect_parts, #partition!, #sew!
Constructor Details
#initialize(tile:, polygon:, shape: nil, bounds: nil) ⇒ Polyline
Returns a new instance of Polyline.
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
# File 'lib/contrek/finder/concurrent/polyline.rb', line 12
def initialize(tile:, polygon:, shape: nil, bounds: nil)
@tile = tile
@name = tile.shapes.count
@raw = polygon
@shape = shape
@flags = 0
@mixed_tile_origin = false
if bounds.nil?
find_boundary
else
@min_x = bounds[:min_x]
@max_x = bounds[:max_x]
@min_y = bounds[:min_y]
@max_y = bounds[:max_y]
end
end
|
Instance Attribute Details
#max_y ⇒ Object
Returns the value of attribute max_y.
9
10
11
|
# File 'lib/contrek/finder/concurrent/polyline.rb', line 9
def max_y
@max_y
end
|
#min_y ⇒ Object
Returns the value of attribute min_y.
9
10
11
|
# File 'lib/contrek/finder/concurrent/polyline.rb', line 9
def min_y
@min_y
end
|
#mixed_tile_origin ⇒ Object
Returns the value of attribute mixed_tile_origin.
10
11
12
|
# File 'lib/contrek/finder/concurrent/polyline.rb', line 10
def mixed_tile_origin
@mixed_tile_origin
end
|
#name ⇒ Object
Returns the value of attribute name.
9
10
11
|
# File 'lib/contrek/finder/concurrent/polyline.rb', line 9
def name
@name
end
|
#next_tile_eligible_shapes ⇒ Object
Returns the value of attribute next_tile_eligible_shapes.
9
10
11
|
# File 'lib/contrek/finder/concurrent/polyline.rb', line 9
def next_tile_eligible_shapes
@next_tile_eligible_shapes
end
|
#raw ⇒ Object
Returns the value of attribute raw.
9
10
11
|
# File 'lib/contrek/finder/concurrent/polyline.rb', line 9
def raw
@raw
end
|
#shape ⇒ Object
Returns the value of attribute shape.
10
11
12
|
# File 'lib/contrek/finder/concurrent/polyline.rb', line 10
def shape
@shape
end
|
#tile ⇒ Object
Returns the value of attribute tile.
10
11
12
|
# File 'lib/contrek/finder/concurrent/polyline.rb', line 10
def tile
@tile
end
|
Class Method Details
.is_within?(test_seq, container_seq) ⇒ Boolean
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
|
# File 'lib/contrek/finder/concurrent/polyline.rb', line 156
def self.is_within?(test_seq, container_seq)
target = test_seq.first
return false unless target
tx, ty = target[:x], target[:y]
inside = false
j = container_seq.length - 1
container_seq.each_with_index do |p_i, i|
p_j = container_seq[j]
if (p_i[:y] > ty) != (p_j[:y] > ty)
intersect_x = (p_j[:x] - p_i[:x]) * (ty - p_i[:y]).to_f / (p_j[:y] - p_i[:y]) + p_i[:x]
if tx < intersect_x
inside = !inside
end
end
j = i
end
inside
end
|
Instance Method Details
#boundary? ⇒ Boolean
94
95
96
|
# File 'lib/contrek/finder/concurrent/polyline.rb', line 94
def boundary?
@tile.tg_border?({x: @min_x}) || @tile.tg_border?({x: @max_x})
end
|
#clear! ⇒ Object
98
99
100
|
# File 'lib/contrek/finder/concurrent/polyline.rb', line 98
def clear!
@raw = []
end
|
#empty? ⇒ Boolean
90
91
92
|
# File 'lib/contrek/finder/concurrent/polyline.rb', line 90
def empty?
@raw.empty?
end
|
#get_bounds ⇒ Object
149
150
151
152
153
154
|
# File 'lib/contrek/finder/concurrent/polyline.rb', line 149
def get_bounds
{min_x: @min_x,
max_x: @max_x,
min_y: @min_y,
max_y: @max_y}
end
|
#info ⇒ Object
42
43
44
|
# File 'lib/contrek/finder/concurrent/polyline.rb', line 42
def info
"w#{@tile.name} S#{@name}"
end
|
#inspect ⇒ Object
30
31
32
|
# File 'lib/contrek/finder/concurrent/polyline.rb', line 30
def inspect
"#{self.class}#{named} (#{raw.count} => #{raw.inspect})"
end
|
#intersection(other) ⇒ Object
returns for every position of intersection an array composed by the indexes of parts (self,other) involved es [[1,3],,…]. The first time the sequence for self is computed is stored.
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
|
# File 'lib/contrek/finder/concurrent/polyline.rb', line 64
def intersection(other)
if @tracked_endpoints.nil?
@tracked_endpoints = {} parts.each_with_index do |part, part_index|
next if !part.is?(Part::SEAM) && part.trasmuted
part.each do |pos|
next if pos.end_point.nil?
@tracked_endpoints[pos.end_point.object_id] = part_index
end
end
end
matching_parts = []
other.parts.each_with_index do |part, part_index|
next if !part.is?(Part::SEAM) && part.trasmuted
part.each do |pos|
if (self_index = @tracked_endpoints[pos.end_point.object_id])
matching_parts << [self_index, part_index]
false
else
true
end
end
end
matching_parts
end
|
#named ⇒ Object
34
35
36
|
# File 'lib/contrek/finder/concurrent/polyline.rb', line 34
def named
"[b#{@tile.name} S#{@name} #{"B" if boundary?}]"
end
|
#numpy_raw ⇒ Object
38
39
40
|
# File 'lib/contrek/finder/concurrent/polyline.rb', line 38
def numpy_raw
raw.flat_map { |p| [p[:x], p[:y]] }
end
|
#on?(flag) ⇒ Boolean
54
55
56
|
# File 'lib/contrek/finder/concurrent/polyline.rb', line 54
def on?(flag)
(@flags & flag) != 0
end
|
#precalc! ⇒ Object
Pre-detects, for the current polyline, adjacent ones in the neighboring tile that vertically intersect.
109
110
111
112
113
114
115
116
|
# File 'lib/contrek/finder/concurrent/polyline.rb', line 109
def precalc!
@next_tile_eligible_shapes = @tile
.circular_next.boundary_shapes
.select { |s|
!s.outer_polyline.on?(Polyline::TRACKED_OUTER) &&
vert_intersect?(s.outer_polyline)
}
end
|
#reset_tracked_endpoints! ⇒ Object
58
59
60
|
# File 'lib/contrek/finder/concurrent/polyline.rb', line 58
def reset_tracked_endpoints!
@tracked_endpoints = nil
end
|
#turn_off(flag) ⇒ Object
50
51
52
|
# File 'lib/contrek/finder/concurrent/polyline.rb', line 50
def turn_off(flag)
@flags &= ~flag
end
|
#turn_on(flag) ⇒ Object
46
47
48
|
# File 'lib/contrek/finder/concurrent/polyline.rb', line 46
def turn_on(flag)
@flags |= flag
end
|
#vert_bounds_intersect?(vertical_bounds) ⇒ Boolean
122
123
124
|
# File 'lib/contrek/finder/concurrent/polyline.rb', line 122
def vert_bounds_intersect?(vertical_bounds)
!(@max_y < vertical_bounds[:min] || vertical_bounds[:max] < @min_y)
end
|
#vert_intersect?(other) ⇒ Boolean
118
119
120
|
# File 'lib/contrek/finder/concurrent/polyline.rb', line 118
def vert_intersect?(other)
!(@max_y < other.min_y || other.max_y < @min_y)
end
|
#width ⇒ Object
102
103
104
105
|
# File 'lib/contrek/finder/concurrent/polyline.rb', line 102
def width
return 0 if empty?
@max_x - @min_x
end
|
#within?(raw_coords) ⇒ Boolean
verifies if enclosed in the given sequence (raycasting technique)
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
# File 'lib/contrek/finder/concurrent/polyline.rb', line 127
def within?(raw_coords)
is_within = false
self_y = raw.first[:y]
self_x = raw.first[:x]
last_node = raw_coords.last
return false if last_node.nil?
lx = last_node[:x]
ly = last_node[:y]
raw_coords.each do |pos|
cx = pos[:x]
cy = pos[:y]
if (cy > self_y) != (ly > self_y)
intersect_x = lx + (self_y - ly).to_f * (cx - lx) / (cy - ly)
if self_x < intersect_x
is_within = !is_within
end
end
lx, ly = cx, cy
end
is_within
end
|