Class: Contrek::Concurrent::Cluster

Inherits:
Object
  • Object
show all
Defined in:
lib/contrek/finder/concurrent/cluster.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(finder:, height:, width:) ⇒ Cluster

Returns a new instance of Cluster.



6
7
8
9
10
# File 'lib/contrek/finder/concurrent/cluster.rb', line 6

def initialize(finder:, height:, width:)
  @finder = finder
  @tiles = []
  @hub = Hub.new(height:, width:)
end

Instance Attribute Details

#hubObject (readonly)

Returns the value of attribute hub.



4
5
6
# File 'lib/contrek/finder/concurrent/cluster.rb', line 4

def hub
  @hub
end

#tilesObject (readonly)

Returns the value of attribute tiles.



4
5
6
# File 'lib/contrek/finder/concurrent/cluster.rb', line 4

def tiles
  @tiles
end

Instance Method Details

#add(tile) ⇒ Object



12
13
14
15
16
17
18
19
# File 'lib/contrek/finder/concurrent/cluster.rb', line 12

def add(tile)
  last_tile = @tiles.last
  last_tile.next = last_tile.circular_next = tile if last_tile
  @tiles << tile
  tile.prev = last_tile
  tile.circular_next = last_tile
  tile.cluster = self
end

#merge_tiles!Object

Here, two tiles are merged into a single one. The tile is assigned new shapes composed of the detected outer sequences and both the old and new inner ones. Shapes that are not in the contact area are directly reassigned unchanged to the new shape.



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
# File 'lib/contrek/finder/concurrent/cluster.rb', line 24

def merge_tiles!
  tot_inner = 0
  tot_outer = 0

  new_shapes = []
  tot_outer += Benchmark.measure do
    @tiles.each do |tile|
      tile.shapes.each do |shape|
        next if shape.outer_polyline.on?(Polyline::TRACKED_OUTER) || shape.outer_polyline.width == 0
        if shape.outer_polyline.boundary?
          shape.outer_polyline.partition!
          shape.outer_polyline.precalc!
        end
      end
    end
  end.real

  @tiles.each do |tile|
    tile.shapes.each do |shape|
      next if shape.outer_polyline.on?(Polyline::TRACKED_OUTER) || shape.outer_polyline.width == 0

      if shape.outer_polyline.boundary? && shape.outer_polyline.next_tile_eligible_shapes.any?
        new_outer = nil
        new_inners = shape.inner_polylines
        cursor = Cursor.new(cluster: self, shape: shape)

        tot_outer += Benchmark.measure do
          new_outer = cursor.join_outers!
        end.real
        tot_inner += Benchmark.measure do
          new_inner_seq = cursor.join_inners!(new_outer)
          new_inners += new_inner_seq if new_inner_seq.any?
          new_inners += cursor.orphan_inners
        end.real

        new_shapes << Shape.new.tap do |shape|
          polyline = Polyline.new(tile: tile, polygon: new_outer.to_a)
          shape.outer_polyline = polyline
          polyline.shape = shape
          shape.inner_polylines = new_inners
        end
      else
        new_shapes << shape
      end
    end
  end
  past_tot_outer = @tiles.first.benchmarks[:outer] + @tiles.last.benchmarks[:outer]
  past_tot_inner = @tiles.first.benchmarks[:inner] + @tiles.last.benchmarks[:inner]

  tile = Tile.new(
    finder: @finder,
    start_x: @tiles.first.start_x,
    end_x: @tiles.last.end_x,
    benchmarks: {outer: tot_outer + past_tot_outer, inner: tot_inner + past_tot_inner},
    name: @tiles.first.name + @tiles.last.name
  )

  tile.assign_shapes!(new_shapes)
  tile
end