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:, start_x:, end_x:) ⇒ 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:, start_x:, end_x:)
  @finder = finder
  @tiles = []
  @hub = Hub.new(height:)
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/contrek/finder/concurrent/cluster.rb', line 24

def merge_tiles!
  treemap = @finder.options[:treemap]
  tot_inner = 0
  tot_outer = 0

  new_shapes = []
  all_new_inner_polylines = []

  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!
        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.any_ancients
        cursor = Cursor.new(cluster: self, shape: shape)

        new_outer = nil
        tot_outer += Benchmark.measure do
          new_outer = cursor.join_outers!
        end.real

        new_inners = shape.inner_polylines
        new_inner_polylines = []
        tot_inner += Benchmark.measure do
          new_inner_polylines = cursor.join_inners!(new_outer, treemap)
          new_inners += new_inner_polylines
          if treemap
            new_inner_polylines.each do |inner_polyline|
              inner_polyline.sequence.compute_vertical_bounds!
              all_new_inner_polylines += new_inner_polylines
            end
          end
          new_inners += cursor.orphan_inners
        end.real

        polyline = Polyline.new(tile: tile, polygon: new_outer.to_a)
        inserting_new_shape = Shape.init_by(polyline, new_inners)
        new_shapes << inserting_new_shape
        polyline.shape = inserting_new_shape

        new_inner_polylines.each { |inner_polyline| inner_polyline.sequence.shape = inserting_new_shape }

        if treemap
          cursor.shapes_sequence.each do |merged_shape|
            merged_shape.merged_to_shape = inserting_new_shape
          end
          if shape.outer_polyline.inside_inner_polyline
            assign_ancestry(inserting_new_shape, shape.outer_polyline.inside_inner_polyline)
          end
        end
      else
        if treemap
          if shape.fixed
            shape.set_parent_shape(shape.parent_shape.merged_to_shape) if shape.parent_shape.merged_to_shape
          else
            is_children(shape, all_new_inner_polylines)
          end
        end

        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