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)


49
50
51
# File 'lib/sevgi/geometry/operation/sweep.rb', line 49

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)
  equation = Tuple[Point, initial].equation(direction)

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

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



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

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

    yield(lines) if block
  end
end

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



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/sevgi/geometry/operation/sweep.rb', line 32

def unisweep(element, equation, step, limit: LIMIT)
  lines = []

  limit.times do
    points = element.intersection(equation)
    return lines if points.empty?

    if points.size == 2 && !(line = Line.(*points)).ignorable?
      lines << line
    end

    equation = equation.shift(step)
  end

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