Class: TaskJuggler::CollisionDetector
- Includes:
- HTMLGraphics
- Defined in:
- lib/taskjuggler/reports/CollisionDetector.rb
Instance Method Summary collapse
-
#addBlockedZone(x, y, w, h, horiz, vert) ⇒ Object
This function registers an area as don’t-cross-zone.
-
#collision?(pos, segment, horizontal) ⇒ Boolean
Find out if there is a block at line pos for the start/end coordinates given by segment.
-
#initialize(width, height) ⇒ CollisionDetector
constructor
A new instance of CollisionDetector.
- #to_html ⇒ Object
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.
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_html ⇒ Object
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 |