Class: Sevgi::Geometry::Segment

Inherits:
Data
  • Object
show all
Includes:
Comparable
Defined in:
lib/sevgi/geometry/segment.rb

Overview

Immutable polar segment in SVG/screen coordinates.

length is a distance and angle is a clockwise angle in degrees. Use Segment[length, angle] to create a segment from polar components.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(length:, angle:) ⇒ void

Creates a segment.

Parameters:

  • length (Numeric)

    segment length

  • angle (Numeric)

    clockwise angle in degrees



69
# File 'lib/sevgi/geometry/segment.rb', line 69

def initialize(length:, angle:) = super(length: length.to_f, angle: angle.to_f)

Instance Attribute Details

#angleFloat (readonly)

Returns clockwise angle in degrees.

Returns:

  • (Float)

    clockwise angle in degrees



9
10
11
# File 'lib/sevgi/geometry/segment.rb', line 9

def angle
  @angle
end

#lengthFloat (readonly)

Returns segment length.

Returns:

  • (Float)

    segment length



9
10
11
# File 'lib/sevgi/geometry/segment.rb', line 9

def length
  @length
end

Class Method Details

.call(starting, ending) ⇒ Sevgi::Geometry::Segment

Creates a segment from start and end points.

Parameters:

Returns:

Raises:



22
23
24
25
# File 'lib/sevgi/geometry/segment.rb', line 22

def self.call(starting, ending)
  starting, ending = Tuples[Point, starting, ending]
  self[Point.length(starting, ending), Point.angle(starting, ending)]
end

.downward(length) ⇒ Sevgi::Geometry::Segment Also known as: vertical

Returns a downward segment.

Parameters:

  • length (Numeric)

    segment length

Returns:



41
# File 'lib/sevgi/geometry/segment.rb', line 41

def self.downward(length) = self[length, 90.0]

.eq?(this, that, precision: nil) ⇒ Boolean

Compares two segments with optional numeric precision.

Parameters:

  • this (Sevgi::Geometry::Segment, Array<Numeric>)

    first segment

  • that (Sevgi::Geometry::Segment, Array<Numeric>)

    second segment

  • precision (Integer, nil) (defaults to: nil)

    decimal precision, or nil for the current function default

Returns:

  • (Boolean)

Raises:



33
34
35
36
# File 'lib/sevgi/geometry/segment.rb', line 33

def self.eq?(this, that, precision: nil)
  this, that = Tuples[self, this, that]
  F.eq?(this.length, that.length, precision:) && F.eq?(this.angle, that.angle, precision:)
end

.leftward(length) ⇒ Sevgi::Geometry::Segment

Returns a leftward segment.

Parameters:

  • length (Numeric)

    segment length

Returns:



46
# File 'lib/sevgi/geometry/segment.rb', line 46

def self.leftward(length) = self[length, 180.0]

.rightward(length) ⇒ Sevgi::Geometry::Segment Also known as: horizontal

Returns a rightward segment.

Parameters:

  • length (Numeric)

    segment length

Returns:



51
# File 'lib/sevgi/geometry/segment.rb', line 51

def self.rightward(length) = self[length, 0.0]

.upward(length) ⇒ Sevgi::Geometry::Segment

Returns an upward segment.

Parameters:

  • length (Numeric)

    segment length

Returns:



56
# File 'lib/sevgi/geometry/segment.rb', line 56

def self.upward(length) = self[length, -90.0]

Instance Method Details

#<=>(other) ⇒ Integer?

Compares segments by length.

Parameters:

Returns:

  • (Integer, nil)

Raises:



75
# File 'lib/sevgi/geometry/segment.rb', line 75

def <=>(other) = (other = Tuple[Segment, other]).nan? || nan? ? nil : length <=> other.length

#approx(precision = nil) ⇒ Sevgi::Geometry::Segment

Returns a segment rounded to precision.

Parameters:

  • precision (Integer, nil) (defaults to: nil)

    decimal precision, or nil for the current function default

Returns:



80
# File 'lib/sevgi/geometry/segment.rb', line 80

def approx(precision = nil) = with(length: F.approx(length, precision), angle: F.approx(angle, precision))

#ending(starting) ⇒ Sevgi::Geometry::Point

Returns the endpoint reached from a starting point.

Parameters:

Returns:

Raises:



86
# File 'lib/sevgi/geometry/segment.rb', line 86

def ending(starting) = Tuple[Point, starting].translate(x, y)

#eq?(other, precision: nil) ⇒ Boolean

Compares this segment with optional numeric precision.

Parameters:

  • other (Sevgi::Geometry::Segment, Array<Numeric>)

    segment to compare

  • precision (Integer, nil) (defaults to: nil)

    decimal precision, or nil for the current function default

Returns:

  • (Boolean)

Raises:



93
# File 'lib/sevgi/geometry/segment.rb', line 93

def eq?(other, precision: nil) = self.class.eq?(self, other, precision:)

#eql?(other) ⇒ Boolean

Reports strict segment equality.

Parameters:

  • other (Object)

    object to compare

Returns:

  • (Boolean)


98
# File 'lib/sevgi/geometry/segment.rb', line 98

def eql?(other) = self.class == other.class && deconstruct == other.deconstruct

#hashInteger

Returns a hash compatible with strict equality.

Returns:

  • (Integer)


102
# File 'lib/sevgi/geometry/segment.rb', line 102

def hash = [self.class, *deconstruct].hash

#infinite?Boolean

Reports whether any component is infinite.

Returns:

  • (Boolean)


106
# File 'lib/sevgi/geometry/segment.rb', line 106

def infinite? = deconstruct.any?(&:infinite?)

#line(point = Origin) ⇒ Sevgi::Geometry::Line

Converts the segment into a line at a point.

Parameters:

Returns:

Raises:



112
# File 'lib/sevgi/geometry/segment.rb', line 112

def line(point = Origin) = Line[length, angle, position: Tuple[Point, point]]

#nan?Boolean

Reports whether any component is NaN.

Returns:

  • (Boolean)


116
# File 'lib/sevgi/geometry/segment.rb', line 116

def nan? = deconstruct.any?(&:nan?)

#reverseSevgi::Geometry::Segment

Returns the opposite segment.



120
# File 'lib/sevgi/geometry/segment.rb', line 120

def reverse = with(angle: angle + 180.0)

#xFloat

Returns the x component of the segment.

Returns:

  • (Float)


124
# File 'lib/sevgi/geometry/segment.rb', line 124

def x = length * F.cos(angle)

#yFloat

Returns the y component of the segment.

Returns:

  • (Float)


128
# File 'lib/sevgi/geometry/segment.rb', line 128

def y = length * F.sin(angle)