Module: Sevgi::Geometry::Operation

Extended by:
Operation
Included in:
Operation
Defined in:
lib/sevgi/geometry/operation.rb,
lib/sevgi/geometry/operation/align.rb,
lib/sevgi/geometry/operation/sweep.rb

Overview

Stateless operations that relate or derive geometry values.

alignment returns a translation offset, while align applies that offset to a copy. Center alignment works on both axes; edge alignments change only the named axis and preserve the other coordinate. sweep derives boundary-to-boundary spans from a closed lined element, and sweep! additionally requires at least one span.

Constant Summary collapse

OperationError =

Raised when an operation starts but cannot complete.

Class.new(Error)
OperationInapplicableError =

Raised when an operation does not apply to the target element.

Class.new(Error)

Class Method Summary collapse

Class Method Details

.align(element, other, alignment = :center) ⇒ Sevgi::Geometry::Element

Returns an element translated to align with another element. Center alignment changes both axes. Edge alignments change only the named axis.

Examples:

Center one rectangle inside another

inner = Sevgi::Geometry::Rect[4, 2]
outer = Sevgi::Geometry::Rect[20, 10, position: [5, 5]]
Sevgi::Geometry::Operation.align(inner, outer).position.deconstruct # => [13.0, 9.0]

Parameters:

Returns:

Raises:



94
# File 'lib/sevgi/geometry/operation.rb', line 94

def register(handler, *operations) = operations.each { |operation| def_operation(operation, handler) }

.alignment(element, other, alignment = :center) ⇒ Sevgi::Geometry::Point

Returns the offset needed to align one element with another. Center alignment includes both axes. Edge alignments return zero on the other axis.

Examples:

Calculate an offset without moving the element

inner = Sevgi::Geometry::Rect[4, 2]
outer = Sevgi::Geometry::Rect[20, 10, position: [5, 5]]
Sevgi::Geometry::Operation.alignment(inner, outer, :bottom).approx.deconstruct # => [0.0, 13.0]

Parameters:

Returns:

Raises:



94
# File 'lib/sevgi/geometry/operation.rb', line 94

def register(handler, *operations) = operations.each { |operation| def_operation(operation, handler) }

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

Sweeps parallel lines across a lined element in both directions. angle is the direction of the returned lines; step is their signed perpendicular spacing. Open paths yield no interior spans.

Examples:

Generate horizontal spans through a rectangle

rect = Sevgi::Geometry::Rect[10, 6]
lines = Sevgi::Geometry::Operation.sweep(rect, initial: [0, 0], angle: 0, step: 2)
lines.size                # => 4
lines.map(&:length).uniq # => [10.0]

Parameters:

  • element (Sevgi::Geometry::Element::Lined)

    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: Sweep::LIMIT)

    maximum iterations per direction

Yields:

  • (lines)

    optional hook receiving the generated lines

Yield Parameters:

Yield Returns:

  • (void)

Returns:

Raises:



94
# File 'lib/sevgi/geometry/operation.rb', line 94

def register(handler, *operations) = operations.each { |operation| def_operation(operation, handler) }

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

Sweeps parallel lines across a lined element and requires at least one result. It has the same geometry as sweep, but raises when the result would be empty.

Parameters:

  • element (Sevgi::Geometry::Element::Lined)

    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: Sweep::LIMIT)

    maximum iterations per direction

Yields:

  • (lines)

    optional hook receiving the generated lines

Yield Parameters:

Yield Returns:

  • (void)

Returns:

Raises:



94
# File 'lib/sevgi/geometry/operation.rb', line 94

def register(handler, *operations) = operations.each { |operation| def_operation(operation, handler) }