Module: Sevgi::Geometry::Operation::Sweep

Extended by:
Sweep
Included in:
Sweep
Defined in:
lib/sevgi/geometry/operation/sweep.rb

Constant Summary collapse

LIMIT =
1_000

Instance Method Summary collapse

Instance Method Details

#applicable?(element) ⇒ Boolean

Returns:

  • (Boolean)


44
45
46
# File 'lib/sevgi/geometry/operation/sweep.rb', line 44

def applicable?(element)
  element.respond_to?(:intersection)
end

#sweep(element, initial:, direction:, step:, limit: LIMIT, &block) ⇒ Object



11
12
13
14
15
16
17
18
19
20
# File 'lib/sevgi/geometry/operation/sweep.rb', line 11

def sweep(element, initial:, direction:, step:, limit: LIMIT, &block)
  line = Equation::Line.from_direction(point: initial, direction:)

  [
    *unisweep(element, line.shift(-step), -step, limit:).reverse,
    *unisweep(element, line, step, limit:)
  ].tap do |segments|
    yield(segments) if block
  end
end

#sweep!(element, initial:, direction:, step:, limit: LIMIT, &block) ⇒ Object



22
23
24
25
26
27
28
# File 'lib/sevgi/geometry/operation/sweep.rb', line 22

def sweep!(element, initial:, direction:, step:, limit: LIMIT, &block)
  sweep(element, initial: initial, direction:, step:, limit:) do |segments|
    OperationError.("No segments found [initial: #{initial}, direction: #{direction} step: #{step}]") if segments.empty?

    yield(segments) if block
  end
end

#unisweep(element, line, step, limit: LIMIT) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/sevgi/geometry/operation/sweep.rb', line 30

def unisweep(element, line, step, limit: LIMIT)
  segments = []

  limit.times do
    return segments unless (segment = element.intersection(line))

    segments << segment unless segment.ignorable?

    line = line.shift(step)
  end

  OperationError.("Loop limit reached: #{limit}")
end