Class: RGeo::Cartesian::Segment

Inherits:
Object
  • Object
show all
Defined in:
lib/rgeo/cartesian/calculations.rb

Overview

Represents a line segment in the plane.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(start, stop) ⇒ Segment

Returns a new instance of Segment.


14
15
16
17
18
19
20
21
22
23
24
# File 'lib/rgeo/cartesian/calculations.rb', line 14

def initialize(start, stop)
  @s = start
  @e = stop
  @sx = @s.x
  @sy = @s.y
  @ex = @e.x
  @ey = @e.y
  @dx = @ex - @sx
  @dy = @ey - @sy
  @lensq = @dx * @dx + @dy * @dy
end

Instance Attribute Details

#dxObject (readonly)

Returns the value of attribute dx


28
29
30
# File 'lib/rgeo/cartesian/calculations.rb', line 28

def dx
  @dx
end

#dyObject (readonly)

Returns the value of attribute dy


29
30
31
# File 'lib/rgeo/cartesian/calculations.rb', line 29

def dy
  @dy
end

#eObject (readonly)

Returns the value of attribute e


27
28
29
# File 'lib/rgeo/cartesian/calculations.rb', line 27

def e
  @e
end

#sObject (readonly)

Returns the value of attribute s


26
27
28
# File 'lib/rgeo/cartesian/calculations.rb', line 26

def s
  @s
end

Instance Method Details

#contains_point?(p) ⇒ Boolean

Returns:

  • (Boolean)

62
63
64
65
66
67
68
69
# File 'lib/rgeo/cartesian/calculations.rb', line 62

def contains_point?(p)
  if side(p) == 0
    t = tproj(p)
    t && t >= 0.0 && t <= 1.0
  else
    false
  end
end

#degenerate?Boolean

Returns:

  • (Boolean)

40
41
42
# File 'lib/rgeo/cartesian/calculations.rb', line 40

def degenerate?
  @lensq == 0
end

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

Returns:

  • (Boolean)

35
36
37
# File 'lib/rgeo/cartesian/calculations.rb', line 35

def eql?(rhs)
  rhs.is_a?(Segment) && @s == rhs.s && @e == rhs.e
end

#intersects_segment?(seg) ⇒ Boolean

Returns:

  • (Boolean)

71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/rgeo/cartesian/calculations.rb', line 71

def intersects_segment?(seg)
  s2 = seg.s
  # Handle degenerate cases
  if seg.degenerate?
    if @lensq == 0
      return @s == s2
    else
      return contains_point?(s2)
    end
  elsif @lensq == 0
    return seg.contains_point?(@s)
  end
  # Both segments have nonzero length.
  sx2 = s2.x
  sy2 = s2.y
  dx2 = seg.dx
  dy2 = seg.dy
  denom = @dx * dy2 - @dy * dx2
  if denom == 0
    # Segments are parallel. Make sure they are collinear.
    return false unless side(s2) == 0
    # 1-D check.
    ts = (@dx * (sx2 - @sx) + @dy * (sy2 - @sy)) / @lensq
    te = (@dx * (sx2 + dx2 - @sx) + @dy * (sy2 + dy2 - @sy)) / @lensq
    if ts < te
      te >= 0.0 && ts <= 1.0
    else
      ts >= 0.0 && te <= 1.0
    end
  else
    # Segments are not parallel. Check the intersection of their
    # containing lines.
    t = (dy2 * (sx2 - @sx) + dx2 * (@sy - sy2)) / denom
    return false if t < 0.0 || t > 1.0
    t2 = (@dy * (sx2 - @sx) + @dx * (@sy - sy2)) / denom
    t2 >= 0.0 && t2 <= 1.0
  end
end

#lengthObject


110
111
112
# File 'lib/rgeo/cartesian/calculations.rb', line 110

def length
  Math.sqrt(@lensq)
end

#side(p) ⇒ Object

Returns a negative value if the point is to the left, a positive value if the point is to the right, or 0 if the point is collinear to the segment.


48
49
50
51
52
# File 'lib/rgeo/cartesian/calculations.rb', line 48

def side(p)
  px = p.x
  py = p.y
  (@sx - px) * (@ey - py) - (@sy - py) * (@ex - px)
end

#to_sObject


31
32
33
# File 'lib/rgeo/cartesian/calculations.rb', line 31

def to_s
  "#{@s} - #{@e}"
end

#tproj(p) ⇒ Object


54
55
56
57
58
59
60
# File 'lib/rgeo/cartesian/calculations.rb', line 54

def tproj(p)
  if @lensq == 0
    nil
  else
    (@dx * (p.x - @sx) + @dy * (p.y - @sy)) / @lensq
  end
end