class Dieses::Geometry::Rect

codebeat:disable

Constants

Corner
Orientation
Side

Attributes

height[R]
position[R]
width[R]

Public Class Methods

new(width, height, position: Point.origin) click to toggle source
Calls superclass method Dieses::Geometry::Element::new
# File lib/dieses/geometry/rect.rb, line 22
def initialize(width, height, position: Point.origin)
  @width    = width.to_f
  @height   = height.to_f
  @position = Point.cast(position)
  @corner   = calculate_corner
  @side     = calculate_side

  super()
end

Public Instance Methods

align(other, alignment = :center) click to toggle source
# File lib/dieses/geometry/rect.rb, line 67
def align(other, alignment = :center)
  raise ArgumentError, "No such alignment type: #{alignment}" unless Align.respond_to? alignment

  self.class.new other.width, other.height, position: Align.public_send(alignment, self, other).approx
end
angle() click to toggle source

codebeat:enable

# File lib/dieses/geometry/rect.rb, line 130
def angle
  Math.atan(height / width)
end
bbox() click to toggle source
# File lib/dieses/geometry/rect.rb, line 134
def bbox
  BoundingBox.new(@corner.values.min, @corner.values.max)
end
intersect(equation, precision: nil) click to toggle source

codebeat:disable

# File lib/dieses/geometry/rect.rb, line 115
def intersect(equation, precision: nil)
  points = Side.members
    .map { |line| public_send(line).intersect(equation).approx(precision) }
    .uniq
    .select { |intersect| onto?(intersect) }
    .sort

  return if points.empty?

  raise "Unexpected number of intersection points: #{points.size}" unless points.size <= 2

  Line.new((starting = points.shift), (points.shift || starting))
end
orient(new_orientation) click to toggle source
# File lib/dieses/geometry/rect.rb, line 84
def orient(new_orientation)
  new_orientation = Orientation.(new_orientation)
  return self if orientation == new_orientation

  self.class.new height, width, position: position
end
orientation() click to toggle source
# File lib/dieses/geometry/rect.rb, line 75
def orientation
  value = if Support.almost_greater_than(width, height)
            :landscape
          else
            :portrait
          end
  Orientation.(value)
end
shrink(width: 0, height: 0) click to toggle source
# File lib/dieses/geometry/rect.rb, line 36
def shrink(width: 0, height: 0)
  self.class.new self.width - width, self.height - height, position: position
end
to_h() click to toggle source
# File lib/dieses/geometry/rect.rb, line 145
def to_h
  { width: width, height: height, **position.to_h }
end
to_s() click to toggle source
# File lib/dieses/geometry/rect.rb, line 138
def to_s
  repr = "R(#{width}, #{height})"
  return repr if position == Point.origin

  "#{repr}@#{position}"
end
to_svgf() click to toggle source

codebeat:disable

# File lib/dieses/geometry/rect.rb, line 150
      def to_svgf
        <<~SVG
          <rect width="#{Support.approx(width)}" height="#{Support.approx(height)}" x="#{Support.approx(position.x)}" y="#{Support.approx(position.y)}" %{attributes}/>
        SVG
      end
translate(x: 0, y: 0) click to toggle source
# File lib/dieses/geometry/rect.rb, line 32
def translate(x: 0, y: 0)
  self.class.new width, height, position: position.translate(x: x, y: y)
end

Private Instance Methods

calculate_corner() click to toggle source
# File lib/dieses/geometry/rect.rb, line 158
def calculate_corner
  Corner.new(top_left:     position,
             top_right:    Point.new(position.x + width, position.y),
             bottom_right: Point.new(position.x + width, position.y + height),
             bottom_left:  Point.new(position.x,         position.y + height))
end
calculate_side() click to toggle source
# File lib/dieses/geometry/rect.rb, line 165
def calculate_side
  Side.new(top:    Line.new(@corner.top_left,     @corner.top_right),
           right:  Line.new(@corner.top_right,    @corner.bottom_right),
           bottom: Line.new(@corner.bottom_left,  @corner.bottom_right),
           left:   Line.new(@corner.top_left,     @corner.bottom_left))
end