Method: IntervalNotation::SweepLine.segmentation_by_boundary_points

Defined in:
lib/interval_notation/sweep_line/sweep_line.rb

.segmentation_by_boundary_points(boundary_points, initial_state) ⇒ Object

Make a segmentation using sweep line along boundary points.



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
# File 'lib/interval_notation/sweep_line/sweep_line.rb', line 61

def self.segmentation_by_boundary_points(boundary_points, initial_state)
  if boundary_points.empty?
    segment = Segmentation::Segment.new(BasicIntervals::OpenOpenInterval.new(-Float::INFINITY, Float::INFINITY), initial_state)
    return Segmentation.new([segment])
  end

  point_chunks = boundary_points.sort_by(&:value).chunk(&:value).to_a
  state = initial_state

  # Process minus-infinity points which can change initial state
  if point_chunks.first.first == -Float::INFINITY
    point_value, points_at_minus_infinity = point_chunks.shift
    state = state.state_after_point(points_at_minus_infinity)
  end

  # Remove plus-infinity points as they can change state but this won't be reflected by any interval
  if point_chunks.last.first == Float::INFINITY
    point_value, points_at_plus_infinity = point_chunks.pop
  end

  prev_point_value = -Float::INFINITY
  segments = []
  # We removed points at plus or minus infinity so now we process inner points
  point_chunks.each do |point_value, points_on_place|
    segments << Segmentation::Segment.new(BasicIntervals::OpenOpenInterval.new(prev_point_value, point_value), state)
    segments << Segmentation::Segment.new(BasicIntervals::Point.new(point_value), state.state_at_point(points_on_place))
    state = state.state_after_point(points_on_place)
    prev_point_value = point_value
  end

  # add fictive segment up to plus-infinity point (may be fictive)
  segments << Segmentation::Segment.new(BasicIntervals::OpenOpenInterval.new(prev_point_value, Float::INFINITY), state)
  Segmentation.new(segments, skip_validation: true) # here we can skip validation but not normalization
end