Class: Sevgi::Geometry::Segment

Inherits:
Element
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/sevgi/geometry/elements/segment.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Element

#at, #bh, #bw, #ignorable?, #position, #position!

Constructor Details

#initialize(position: Point.origin, ending:, &block) ⇒ Segment

Returns a new instance of Segment.



14
15
16
17
18
19
20
21
# File 'lib/sevgi/geometry/elements/segment.rb', line 14

def initialize(position: Point.origin, ending:, &block)
  super()

  @position = position
  @ending   = ending

  instance_exec(&block) if block # memoization backdoor for constructors
end

Instance Attribute Details

#endingObject (readonly)

Returns the value of attribute ending.



12
13
14
# File 'lib/sevgi/geometry/elements/segment.rb', line 12

def ending
  @ending
end

Class Method Details

.[](position, ending) ⇒ Object



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

def [](position, ending)
  new(position:, ending:)
end

.directed(position: nil, length:, direction:) ⇒ Object



110
111
112
113
114
115
116
117
118
119
120
# File 'lib/sevgi/geometry/elements/segment.rb', line 110

def directed(position: nil, length:, direction:)
  dx = F.dxa(length, direction)
  dy = F.dya(length, direction)

  new(position: (position ||= Point.origin), ending: position.translate(dx:, dy:)) do # avoid recalculations
    @direction = direction.to_f
    @length    = length.to_f
    @dx        = dx
    @dy        = dy
  end
end

.forward(p, q = nil) ⇒ Object



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

def forward(p, q = nil)
  new(position: (points = [ p, q || p ]).sort!.shift, ending: points.shift)
end

.horizontal(length, position = nil) ⇒ Object



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

def horizontal(length, position = nil)
  directed(position:, length:, direction: 0.0)
end

.vertical(length, position = nil) ⇒ Object



130
131
132
# File 'lib/sevgi/geometry/elements/segment.rb', line 130

def vertical(length, position = nil)
  directed(position:, length:, direction: 90.0)
end

Instance Method Details

#boxObject



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

def box
  Rect.with_points(position, ending)
end

#directionObject



27
28
29
# File 'lib/sevgi/geometry/elements/segment.rb', line 27

def direction
  @direction ||= F.angler(dx, dy)
end

#dxObject



31
32
33
# File 'lib/sevgi/geometry/elements/segment.rb', line 31

def dx
  @dx ||= F.dxp(position, ending)
end

#dyObject



35
36
37
# File 'lib/sevgi/geometry/elements/segment.rb', line 35

def dy
  @dy ||= F.dyp(position, ending)
end

#ending!Object



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

def ending!(...)
  ending.approx(...)
end

#eql?(other) ⇒ Boolean Also known as: ==

Returns:

  • (Boolean)


43
44
45
# File 'lib/sevgi/geometry/elements/segment.rb', line 43

def eql?(other)
  self.class == other.class && points == other.points
end

#hashObject



47
48
49
# File 'lib/sevgi/geometry/elements/segment.rb', line 47

def hash
  [ self.class, *points ].hash
end

#horizontal?(precision = nil) ⇒ Boolean

Returns:

  • (Boolean)


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

def horizontal?(precision = nil)
  F.horizontal?(direction, precision:)
end

#infinite?Boolean

Returns:

  • (Boolean)


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

def infinite?
  points.any(&:infinite?)
end

#lengthObject



59
60
61
# File 'lib/sevgi/geometry/elements/segment.rb', line 59

def length
  @length ||= F.distance(position, ending)
end

#lineObject



63
64
65
# File 'lib/sevgi/geometry/elements/segment.rb', line 63

def line
  @line ||= Equation::Line.from_segment(self)
end

#onto?(point) ⇒ Boolean

Returns:

  • (Boolean)


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

def onto?(point)
  point.unordered_between?(ending, position) && line.onto?(point)
end

#pairsObject



71
72
73
# File 'lib/sevgi/geometry/elements/segment.rb', line 71

def pairs
  points.map(&:to_a)
end

#pairs!Object



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

def pairs!(...)
  points!(...).map(&:to_a)
end

#pointsObject



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

def points
  [ position, ending ]
end

#points!(precision = nil) ⇒ Object



83
84
85
# File 'lib/sevgi/geometry/elements/segment.rb', line 83

def points!(precision = nil)
  points.map { _1.approx(precision) }
end

#shift(distance) ⇒ Object



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

def shift(distance)
  translate(dx: distance * F.sin(direction), dy: distance * F.cos(direction))
end

#to_sObject



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

def to_s
  "S[#{position} -> #{ending}]"
end

#translate(dx: nil, dy: nil) ⇒ Object



95
96
97
# File 'lib/sevgi/geometry/elements/segment.rb', line 95

def translate(dx: nil, dy: nil)
  self.class.new(position: position.translate(dx:, dy:), ending: ending.translate(dx:, dy:))
end

#vertical?(precision = nil) ⇒ Boolean

Returns:

  • (Boolean)


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

def vertical?(precision = nil)
  F.vertical?(direction, precision:)
end