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 |