Module: Overlap

Defined in:
lib/nswtopo/geometry/overlap.rb

Instance Method Summary collapse

Instance Method Details

#overlap?(buffer) ⇒ Boolean

Returns:

  • (Boolean)


42
43
44
# File 'lib/nswtopo/geometry/overlap.rb', line 42

def overlap?(buffer)
  !separated_by?(buffer)
end

#separated_by?(buffer) ⇒ Boolean

Returns:

  • (Boolean)


2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/nswtopo/geometry/overlap.rb', line 2

def separated_by?(buffer)
  simplex = [map(&:first).inject(&:minus)]
  perp = simplex[0].perp
  loop do
    return false unless case
    when simplex.one? then simplex[0].norm
    when simplex.inject(&:minus).dot(simplex[1]) > 0 then simplex[1].norm
    when simplex.inject(&:minus).dot(simplex[0]) < 0 then simplex[0].norm
    else simplex.inject(&:cross).abs / simplex.inject(&:minus).norm
    end > buffer
    max = self[0].max_by { |point| perp.cross point }
    min = self[1].min_by { |point| perp.cross point }
    support = max.minus min
    return true unless simplex[0].minus(support).cross(perp) > 0
    rays = simplex.map { |point| point.minus support }
    case simplex.length
    when 1
      case
      when rays[0].dot(support) > 0
        simplex, perp = [support], support.perp
      when rays[0].cross(support) < 0
        simplex, perp = [support, *simplex], rays[0]
      else
        simplex, perp = [*simplex, support], rays[0].negate
      end
    when 2
      case
      when rays[0].cross(support) > 0 && rays[0].dot(support) < 0
        simplex, perp = [simplex[0], support], rays[0].negate
      when rays[1].cross(support) < 0 && rays[1].dot(support) < 0
        simplex, perp = [support, simplex[1]], rays[1]
      when rays[0].cross(support) <= 0 && rays[1].cross(support) >= 0
        return false
      else
        simplex, perp = [support], support.perp
      end
    end
  end
end