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

Raises:



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

def initialize(length:, angle:) = super(length: Real[:length, length], angle: Real[:angle, angle])

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:



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

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:



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

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:



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

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:



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

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)


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

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

#hashInteger

Returns a hash compatible with strict equality.

Returns:

  • (Integer)


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

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

#infinite?Boolean

Reports whether any component is infinite.

Returns:

  • (Boolean)


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

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

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

Converts the segment into a line at a point.

Parameters:

Returns:

Raises:



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

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

#nan?Boolean

Reports whether any component is NaN.

Returns:

  • (Boolean)


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

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

#reverseSevgi::Geometry::Segment

Returns the opposite segment.



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

def reverse = with(angle: angle + 180.0)

#xFloat

Returns the x component of the segment.

Returns:

  • (Float)


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

def x = length * F.cos(angle)

#yFloat

Returns the y component of the segment.

Returns:

  • (Float)


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

def y = length * F.sin(angle)