Class: TaskJuggler::CollisionDetector

Inherits:
Object
  • Object
show all
Includes:
HTMLGraphics
Defined in:
lib/taskjuggler/reports/CollisionDetector.rb

Instance Method Summary collapse

Methods included from HTMLGraphics

#arrowHeadToHTML, #diamondToHTML, #jagToHTML, #lineToHTML, #rectToHTML

Constructor Details

#initialize(width, height) ⇒ CollisionDetector

Returns a new instance of CollisionDetector.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/taskjuggler/reports/CollisionDetector.rb', line 22

def initialize(width, height)
  @width = width
  @height = height

  # The zones are stored as Arrays of line segments. Horizontal blocks are
  # stored separately from vertical blocks. Blocked segments for a
  # particular x coordinate are stored in @vLines, for y coordinates in
  # @hLines. Each entry is an Array of [ start, end ] values that describe
  # the blocked segments of that particular line. Start and end point are
  # part of the segment. A listed segment will not be overwritten during
  # routing.
  @hLines = Array.new(@height) { |i| i = [] }
  @vLines = Array.new(@width) { |i| i = [] }
end

Instance Method Details

#addBlockedZone(x, y, w, h, horiz, vert) ⇒ Object

This function registers an area as don’t-cross-zone. The rectangular zone is described by x, y, w and h. If horiz is true, the zone will be blocked for horizontal lines, if vert is true the zone will be blocked for vertical lines.



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/taskjuggler/reports/CollisionDetector.rb', line 41

def addBlockedZone(x, y, w, h, horiz, vert)
  # Clip the input rectangle to fit within the handled area of this router.
  x = clip(x.to_i, @width - 1)
  y = clip(y.to_i, @height - 1)
  w = clip(w.to_i, @width - x)
  h = clip(h.to_i, @height - y)

  # We can ignore empty zones.
  return if w == 0 || h == 0

  # Break the rectangle into line segments and add them to the appropriate
  # line Arrays.
  if horiz
    y.upto(y + h - 1) do |i|
      addSegment(@hLines[i], [ x, x + w - 1 ])
    end
  end
  if vert
    x.upto(x + w - 1) do |i|
      addSegment(@vLines[i], [ y, y + h - 1 ])
    end
  end
end

#collision?(pos, segment, horizontal) ⇒ Boolean

Find out if there is a block at line pos for the start/end coordinates given by segment. If horizontal is true, we are looking for a horizontal block, otherwise a vertical.

Returns:

  • (Boolean)


68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/taskjuggler/reports/CollisionDetector.rb', line 68

def collision?(pos, segment, horizontal)
  line = (horizontal ? @hLines : @vLines)[pos]

  # For complex charts, the segment lists can be rather long. We use a
  # binary search to be fairly efficient.
  l = 0
  u = line.length - 1
  while l <= u
    # Look at the element in the middle between l and u.
    p = l + ((u - l) / 2).to_i
    return true if overlaps?(line[p], segment)

    if segment[0] > line[p][1]
      # The potential target is above p. Adjust lower bound.
      l = p + 1
    else
      # The potential target is below p. Adjust upper bound.
      u = p - 1
    end
  end
  false
end

#to_htmlObject



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/taskjuggler/reports/CollisionDetector.rb', line 91

def to_html
  html = []
  # Change this to determine what zones you want to see.
  if true
    # Show vertical blocks
    x = 0
    @vLines.each do |line|
      line.each do |segment|
        html << lineToHTML(x, segment[0], x, segment[1], 'white')
      end
      x += 1
    end
  else
    # Show horizontal blocks
    y = 0
    @hLines.each do |line|
      line.each do |segment|
        html << lineToHTML(segment[0], y, segment[1], y, 'white')
      end
      y += 1
    end
  end
  html
end