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

Returns a new instance of 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

Returns:



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