Module: ChunkyPNG::Canvas::Drawing

Included in:
ChunkyPNG::Canvas
Defined in:
lib/chunky_png/canvas/drawing.rb

Instance Method Summary collapse

Instance Method Details

#line_xiaolin_wu(x0, y0, x1, y1, color) ⇒ Object Also known as: line

Draws an anti-aliased line using Xiaolin Wu’s algorithm.



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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/chunky_png/canvas/drawing.rb', line 13

def line_xiaolin_wu(x0, y0, x1, y1, color)
  y0, y1, x0, x1 = y1, y0, x1, x0 if y0 > y1
  dx = x1 - x0
  sx = dx < 0 ? -1 : 1
  dx *= sx
  dy = y1 - y0
  
  if dy == 0 # vertical line
    Range.new(*[x0,x1].sort).each do |x|
      point(x, y0, color)
    end
  elsif dx == 0 # horizontal line
    (y0..y1).each do |y|
      point(x0, y, color)
    end
  elsif dx == dy # diagonal
    x0.step(x1, sx) do |x|
      point(x, y0, color)
      y0 += 1
    end
    
  elsif dy > dx  # vertical displacement
    point(x0, y0, color)
    e_acc = 0          
    e = ((dx << 16) / dy.to_f).round
    (y0...y1-1).each do |i|
      e_acc_temp, e_acc = e_acc, (e_acc + e) & 0xffff
      x0 = x0 + sx if (e_acc <= e_acc_temp)
      w = 0xff - (e_acc >> 8)
      point(x0, y0, ChunkyPNG::Color.fade(color, w)) if include?(x0, y0)
      y0 = y0 + 1
      point(x0 + sx, y0, ChunkyPNG::Color.fade(color, 0xff - w)) if include?(x0 + sx, y0)
    end
    point(x1, y1, color)
    
  else # horizontal displacement
    point(x0, y0, color)
    e_acc = 0
    e = (dy << 16) / dx
    (dx - 1).downto(0) do |i|
      e_acc_temp, e_acc = e_acc, (e_acc + e) & 0xffff
      y0 += 1 if (e_acc <= e_acc_temp)
      w = 0xff - (e_acc >> 8)
      point(x0, y0, ChunkyPNG::Color.fade(color, w)) if include?(x0, y0)
      x0 += sx
      point(x0, y0 + 1, ChunkyPNG::Color.fade(color, 0xff - w)) if include?(x0, y0 + 1)
    end
    point(x1, y1, color)
  end
end

#point(x, y, color) ⇒ Object

Sets a point on the canvas by composing a pixel with its background color.



7
8
9
# File 'lib/chunky_png/canvas/drawing.rb', line 7

def point(x, y, color)
  self[x, y] = ChunkyPNG::Color.compose(color, self[x, y])
end