Module: Terraformer::Geometry::ClassMethods

Included in:
Terraformer::Geometry
Defined in:
lib/terraformer/geometry/class_methods.rb

Overview

geometric “helpers”

Instance Method Summary collapse

Instance Method Details

#arrays_intersect_arrays?(a, b) ⇒ Boolean

Returns:

  • (Boolean)


44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/terraformer/geometry/class_methods.rb', line 44

def arrays_intersect_arrays? a, b
  case
  when a[0].class == Coordinate
    case
    when b[0].class == Coordinate
      a.each_cons(2) do |a1, a2|
        b.each_cons(2) do |b1, b2|
          return true if edge_intersects_edge?(a1, a2, b1, b2)
        end
      end
    when b[0].class == Array
      b.each {|e| return true if arrays_intersect_arrays?(a, e)}
    end
  when a[0].class == Array
    a.each {|e| return true if arrays_intersect_arrays?(e, b)}
  end
  false
end

#coordinates_contain_point?(coordinates, point) ⇒ Boolean

Returns:

  • (Boolean)


8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/terraformer/geometry/class_methods.rb', line 8

def coordinates_contain_point? coordinates, point
  if Terraformer::Coordinate === coordinates
    return coordinates == point
  end

  contains = false
  i = -1
  l = coordinates.length
  j = l - 1
  loop do
    break unless (i += 1) < l

    if ((coordinates[i][1] <= point[1] && point[1] < coordinates[j][1]) ||
        (coordinates[j][1] <= point[1] && point[1] < coordinates[i][1])) &&
       (point[0] < (coordinates[j][0] - coordinates[i][0]) *
        (point[1] - coordinates[i][1]) / (coordinates[j][1] - coordinates[i][1]) + coordinates[i][0])

       contains = !contains
    end
    j = i
  end
  contains
end

#edge_intersects_edge?(a1, a2, b1, b2) ⇒ Boolean

Returns:

  • (Boolean)


32
33
34
35
36
37
38
39
40
41
42
# File 'lib/terraformer/geometry/class_methods.rb', line 32

def edge_intersects_edge? a1, a2, b1, b2
  ua_t = (b2[0] - b1[0]) * (a1[1] - b1[1]) - (b2[1] - b1[1]) * (a1[0] - b1[0])
  ub_t = (a2[0] - a1[0]) * (a1[1] - b1[1]) - (a2[1] - a1[1]) * (a1[0] - b1[0])
  u_b  = (b2[1] - b1[1]) * (a2[0] - a1[0]) - (b2[0] - b1[0]) * (a2[1] - a1[1])
  if u_b != 0
    ua = ua_t / u_b
    ub = ub_t / u_b
    return true if  0 <= ua && ua <= 1 && 0 <= ub && ub <= 1
  end
  false
end

#line_contains_point?(line, point) ⇒ Boolean

Returns:

  • (Boolean)

Raises:

  • (ArgumentError)


63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/terraformer/geometry/class_methods.rb', line 63

def line_contains_point? line, point
  raise ArgumentError unless Array === line and
                             line.length == 2 and
                             Coordinate === line[0] and
                             Coordinate === line[1]
  point = point.coordinates if Point === point
  raise ArgumentError unless Coordinate === point

  return true if line[0] == point or line[1] == point

  dxp = point.x - line[0].x
  dyp = point.y - line[0].y

  dxl = line[1].x - line[0].x
  dyl = line[1].y - line[0].y

  cross = dxp * dyl - dyp * dxl
  return false unless cross == BigMath::ZERO

  if dxl.abs >= dyl.abs
    return dxl > BigMath::ZERO ?
      line[0].x <= point.x && point.x <= line[1].x :
      line[1].x <= point.x && point.x <= line[0].x
  else
    return dyl > BigMath::ZERO ?
      line[0].y <= point.y && point.y <= line[1].y :
      line[1].y <= point.y && point.y <= line[0].y
  end
end