module ChunkyPNG::Canvas::Drawing
def line_xiaolin_wu(x0, y0, x1, y1, stroke_color, inclusive = true)
-
(ChunkyPNG::Canvas)
- Itself, with the line drawn.
Parameters:
-
inclusive
(true, false
) -- Whether to draw the last pixel. Set to -
stroke_color
(Integer
) -- The color to use for this line. -
y1
(Integer
) -- The y-coordinate of the second control point. -
x1
(Integer
) -- The x-coordinate of the second control point. -
y0
(Integer
) -- The y-coordinate of the first control point. -
x0
(Integer
) -- The x-coordinate of the first control point.
def line_xiaolin_wu(x0, y0, x1, y1, stroke_color, inclusive = true) stroke_color = ChunkyPNG::Color.parse(stroke_color) dx = x1 - x0 sx = dx < 0 ? -1 : 1 dx *= sx dy = y1 - y0 sy = dy < 0 ? -1 : 1 dy *= sy if dy == 0 # vertical line x0.step(inclusive ? x1 : x1 - sx, sx) do |x| compose_pixel(x, y0, stroke_color) end elsif dx == 0 # horizontal line y0.step(inclusive ? y1 : y1 - sy, sy) do |y| compose_pixel(x0, y, stroke_color) end elsif dx == dy # diagonal x0.step(inclusive ? x1 : x1 - sx, sx) do |x| compose_pixel(x, y0, stroke_color) y0 += sy end elsif dy > dx # vertical displacement compose_pixel(x0, y0, stroke_color) e_acc = 0 e = ((dx << 16) / dy.to_f).round (dy - 1).downto(0) do |i| e_acc_temp, e_acc = e_acc, (e_acc + e) & 0xffff x0 += sx if e_acc <= e_acc_temp w = 0xff - (e_acc >> 8) compose_pixel(x0, y0, ChunkyPNG::Color.fade(stroke_color, w)) if inclusive || i > 0 compose_pixel(x0 + sx, y0 + sy, ChunkyPNG::Color.fade(stroke_color, 0xff - w)) end y0 += sy end compose_pixel(x1, y1, stroke_color) if inclusive else # horizontal displacement compose_pixel(x0, y0, stroke_color) e_acc = 0 e = ((dy << 16) / dx.to_f).round (dx - 1).downto(0) do |i| e_acc_temp, e_acc = e_acc, (e_acc + e) & 0xffff y0 += sy if e_acc <= e_acc_temp w = 0xff - (e_acc >> 8) compose_pixel(x0, y0, ChunkyPNG::Color.fade(stroke_color, w)) if inclusive || i > 0 compose_pixel(x0 + sx, y0 + sy, ChunkyPNG::Color.fade(stroke_color, 0xff - w)) end x0 += sx end compose_pixel(x1, y1, stroke_color) if inclusive end self end