Module: ChunkyPNG::Canvas::Drawing
- Included in:
- ChunkyPNG::Canvas
- Defined in:
- lib/chunky_png/canvas/drawing.rb
Instance Method Summary collapse
-
#line_xiaolin_wu(x0, y0, x1, y1, color) ⇒ Object
(also: #line)
Draws an anti-aliased line using Xiaolin Wu’s algorithm.
-
#point(x, y, color) ⇒ Object
Sets a point on the canvas by composing a pixel with its background color.
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 |