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

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

Overview

Sweep operation implementation.

Constant Summary collapse

LIMIT =

Default maximum number of sweep iterations.

1_000

Instance Method Summary collapse

Instance Method Details

#applicable?(element) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Reports whether the sweep handler can operate on an element.

Parameters:

  • element (Object)

    candidate element

Returns:

  • (Boolean)


86
87
88
# File 'lib/sevgi/geometry/operation/sweep.rb', line 86

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

#sweep(element, initial:, angle:, step:, limit: LIMIT) {|lines| ... } ⇒ Array<Sevgi::Geometry::Line>

Sweeps parallel lines across an element in both directions.

Parameters:

  • element (Sevgi::Geometry::Element)

    element to intersect

  • initial (Sevgi::Geometry::Point, Array<Numeric>)

    point on the initial sweep line

  • angle (Numeric)

    clockwise sweep line angle in degrees

  • step (Numeric)

    signed distance between sweep lines

  • limit (Integer) (defaults to: LIMIT)

    maximum iterations per direction

Yields:

  • (lines)

    optional hook receiving the generated lines

Yield Parameters:

Yield Returns:

  • (void)

Returns:

Raises:



25
26
27
28
29
30
31
32
33
34
# File 'lib/sevgi/geometry/operation/sweep.rb', line 25

def sweep(element, initial:, angle:, step:, limit: LIMIT, &block)
  equation = Tuple[Point, initial].equation(angle)

  [
    *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:, angle:, step:, limit: LIMIT) {|lines| ... } ⇒ Array<Sevgi::Geometry::Line>

Sweeps parallel lines and requires at least one result.

Parameters:

  • element (Sevgi::Geometry::Element)

    element to intersect

  • initial (Sevgi::Geometry::Point, Array<Numeric>)

    point on the initial sweep line

  • angle (Numeric)

    clockwise sweep line angle in degrees

  • step (Numeric)

    signed distance between sweep lines

  • limit (Integer) (defaults to: LIMIT)

    maximum iterations per direction

Yields:

  • (lines)

    optional hook receiving the generated lines

Yield Parameters:

Yield Returns:

  • (void)

Returns:

Raises:



48
49
50
51
52
53
54
55
56
# File 'lib/sevgi/geometry/operation/sweep.rb', line 48

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

    yield(lines) if block
  end
end

#unisweep(element, equation, step, limit: LIMIT) ⇒ Array<Sevgi::Geometry::Line>

Sweeps parallel lines in one signed direction from an equation.

Parameters:

Returns:

Raises:



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/sevgi/geometry/operation/sweep.rb', line 65

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