Class: Contrek::Concurrent::Polyline

Inherits:
Object
  • Object
show all
Includes:
Partitionable
Defined in:
lib/contrek/finder/concurrent/polyline.rb

Constant Summary collapse

TRACKED_OUTER =
1 << 0

Instance Attribute Summary collapse

Attributes included from Partitionable

#parts

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Partitionable

#add_part, #inspect_parts, #partition!

Constructor Details

#initialize(tile:, polygon:, shape: nil, bounds: nil) ⇒ Polyline

Returns a new instance of Polyline.



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/contrek/finder/concurrent/polyline.rb', line 11

def initialize(tile:, polygon:, shape: nil, bounds: nil)
  @tile = tile
  @name = tile.shapes.count
  @raw = polygon
  @shape = shape
  @flags = 0
  @any_ancients = 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

#any_ancientsObject

Returns the value of attribute any_ancients.



9
10
11
# File 'lib/contrek/finder/concurrent/polyline.rb', line 9

def any_ancients
  @any_ancients
end

#max_yObject (readonly)

Returns the value of attribute max_y.



8
9
10
# File 'lib/contrek/finder/concurrent/polyline.rb', line 8

def max_y
  @max_y
end

#min_yObject (readonly)

Returns the value of attribute min_y.



8
9
10
# File 'lib/contrek/finder/concurrent/polyline.rb', line 8

def min_y
  @min_y
end

#nameObject (readonly)

Returns the value of attribute name.



8
9
10
# File 'lib/contrek/finder/concurrent/polyline.rb', line 8

def name
  @name
end

#rawObject (readonly)

Returns the value of attribute raw.



8
9
10
# File 'lib/contrek/finder/concurrent/polyline.rb', line 8

def raw
  @raw
end

#shapeObject

Returns the value of attribute shape.



9
10
11
# File 'lib/contrek/finder/concurrent/polyline.rb', line 9

def shape
  @shape
end

#tileObject

Returns the value of attribute tile.



9
10
11
# File 'lib/contrek/finder/concurrent/polyline.rb', line 9

def tile
  @tile
end

Class Method Details

.is_within?(test_seq, container_seq) ⇒ Boolean

Returns:

  • (Boolean)


112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/contrek/finder/concurrent/polyline.rb', line 112

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

Returns:

  • (Boolean)


61
62
63
# File 'lib/contrek/finder/concurrent/polyline.rb', line 61

def boundary?
  @tile.tg_border?({x: @min_x}) || @tile.tg_border?({x: @max_x})
end

#clear!Object



65
66
67
# File 'lib/contrek/finder/concurrent/polyline.rb', line 65

def clear!
  @raw = []
end

#empty?Boolean

Returns:

  • (Boolean)


57
58
59
# File 'lib/contrek/finder/concurrent/polyline.rb', line 57

def empty?
  @raw.empty?
end

#get_boundsObject



105
106
107
108
109
110
# File 'lib/contrek/finder/concurrent/polyline.rb', line 105

def get_bounds
  {min_x: @min_x,
   max_x: @max_x,
   min_y: @min_y,
   max_y: @max_y}
end

#infoObject



41
42
43
# File 'lib/contrek/finder/concurrent/polyline.rb', line 41

def info
  "w#{@tile.name} S#{@name}"
end

#inspectObject



29
30
31
# File 'lib/contrek/finder/concurrent/polyline.rb', line 29

def inspect
  "#{self.class}#{named} (#{raw.count} => #{raw.inspect})"
end

#namedObject



33
34
35
# File 'lib/contrek/finder/concurrent/polyline.rb', line 33

def named
  "[b#{@tile.name} S#{@name} #{"B" if boundary?}]"
end

#numpy_rawObject



37
38
39
# File 'lib/contrek/finder/concurrent/polyline.rb', line 37

def numpy_raw
  raw.flat_map { |p| [p[:x], p[:y]] }
end

#on?(flag) ⇒ Boolean

Returns:

  • (Boolean)


53
54
55
# File 'lib/contrek/finder/concurrent/polyline.rb', line 53

def on?(flag)
  (@flags & flag) != 0
end

#turn_off(flag) ⇒ Object



49
50
51
# File 'lib/contrek/finder/concurrent/polyline.rb', line 49

def turn_off(flag)
  @flags &= ~flag
end

#turn_on(flag) ⇒ Object



45
46
47
# File 'lib/contrek/finder/concurrent/polyline.rb', line 45

def turn_on(flag)
  @flags |= flag
end

#vert_bounds_intersect?(vertical_bounds) ⇒ Boolean

Returns:

  • (Boolean)


78
79
80
# File 'lib/contrek/finder/concurrent/polyline.rb', line 78

def vert_bounds_intersect?(vertical_bounds)
  !(@max_y < vertical_bounds[:min] || vertical_bounds[:max] < @min_y)
end

#vert_intersect?(other) ⇒ Boolean

Returns:

  • (Boolean)


74
75
76
# File 'lib/contrek/finder/concurrent/polyline.rb', line 74

def vert_intersect?(other)
  !(@max_y < other.min_y || other.max_y < @min_y)
end

#widthObject



69
70
71
72
# File 'lib/contrek/finder/concurrent/polyline.rb', line 69

def width
  return 0 if empty?
  @max_x - @min_x
end

#within?(raw_coords) ⇒ Boolean

verifies if enclosed in the given sequence (raycasting technique)

Returns:

  • (Boolean)


83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/contrek/finder/concurrent/polyline.rb', line 83

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