Class: RayTracer

Inherits:
Object
  • Object
show all
Defined in:
lib/natural_20/utils/ray_tracer.rb

Overview

typed: false class used for ray trace and path trace computations

Instance Method Summary collapse

Constructor Details

#initialize(map) ⇒ RayTracer



4
5
6
# File 'lib/natural_20/utils/ray_tracer.rb', line 4

def initialize(map)
  @map = map
end

Instance Method Details

#line_of_sight?(pos1_x, pos1_y, pos2_x, pos2_y, distance = nil) ⇒ Boolean



49
50
51
52
53
54
55
56
57
58
59
60
61
62
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
# File 'lib/natural_20/utils/ray_tracer.rb', line 49

def line_of_sight?(pos1_x, pos1_y, pos2_x, pos2_y, distance = nil)
  return true if [pos1_x, pos1_y] == [pos2_x, pos2_y]

  if pos2_x == pos1_x
    scanner = pos2_y > pos1_y ? (pos1_y...pos2_y) : (pos2_y...pos1_y)

    scanner.each_with_index do |y, index|
      return false if !distance.nil? && index > distance
      next if (y == pos1_y) || (y == pos2_y)
      return false if @map.opaque?(pos1_x, y)
    end
    true
  else
    m = (pos2_y - pos1_y).to_f / (pos2_x - pos1_x)
    if m == 0
      scanner = pos2_x > pos1_x ? (pos1_x...pos2_x) : (pos2_x...pos1_x)

      scanner.each_with_index do |x, index|
        return false if !distance.nil? && index > distance
        next if (x == pos1_x) || (x == pos2_x)
        return false if @map.opaque?(x, pos2_y)
      end

      true
    else
      scanner = pos2_x > pos1_x ? (pos1_x...pos2_x) : (pos2_x...pos1_x)

      b = pos1_y - m * pos1_x
      step = m.abs > 1 ? 1 / m.abs : m.abs

      scanner.step(step).each_with_index do |x, index|
        y = (m * x + b).round

        return false if !distance.nil? && index > distance
        next if (x.round == pos1_x && y == pos1_y) || (x.round == pos2_x && y == pos2_y)
        return false if @map.opaque?(x.round, y)
      end
      true
    end
  end
end

#ray_trace(pos1_x, pos1_y, pos2_x, pos2_y, _max_distance) ⇒ Object



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
41
42
43
44
45
46
47
# File 'lib/natural_20/utils/ray_tracer.rb', line 8

def ray_trace(pos1_x, pos1_y, pos2_x, pos2_y, _max_distance)
  return true if [pos1_x, pos1_y] == [pos2_x, pos2_y]

  if pos2_x == pos1_x
    scanner = pos2_y > pos1_y ? (pos1_y...pos2_y) : (pos2_y...pos1_y)

    scanner.each_with_index do |y, index|
      return false if !distance.nil? && index > distance
      next if (y == pos1_y) || (y == pos2_y)
      return false if @map.opaque?(pos1_x, y)
    end
    true
  else
    m = (pos2_y - pos1_y).to_f / (pos2_x - pos1_x)
    scanner = pos2_x > pos1_x ? (pos1_x...pos2_x) : (pos2_x...pos1_x)
    if m.zero?

      scanner.each_with_index do |x, index|
        return false if !distance.nil? && index > distance
        next if (x == pos1_x) || (x == pos2_x)
        return false if @map.opaque?(x, pos2_y)
      end

      true
    else

      b = pos1_y - m * pos1_x
      step = m.abs > 1 ? 1 / m.abs : m.abs

      scanner.step(step).each_with_index do |x, index|
        y = (m * x + b).round

        return false if !distance.nil? && index > distance
        next if (x.round == pos1_x && y == pos1_y) || (x.round == pos2_x && y == pos2_y)
        return false if @map.opaque?(x.round, y)
      end
      true
    end
  end
end