class TaskJuggler::CollisionDetector
Public Class Methods
new(width, height)
click to toggle source
# 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
Public Instance Methods
addBlockedZone(x, y, w, h, horiz, vert)
click to toggle source
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.
# 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)
click to toggle source
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.
# 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_html()
click to toggle source
# 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