From 5cda2f758eca65b244a87c427f767468d0d31433 Mon Sep 17 00:00:00 2001 From: Gabriel Roldan Date: Wed, 4 Mar 2020 17:27:01 -0300 Subject: [PATCH] Fix aritmetic error on vertical lines using line/5 --- lib/oled/display/impl/ssd_1306/draw.ex | 25 ++++++++++---- test/oled/display/impl/ssd_1306/line_test.exs | 33 ++++++++++++++++++- 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/lib/oled/display/impl/ssd_1306/draw.ex b/lib/oled/display/impl/ssd_1306/draw.ex index 286d331..a99adc1 100644 --- a/lib/oled/display/impl/ssd_1306/draw.ex +++ b/lib/oled/display/impl/ssd_1306/draw.ex @@ -62,13 +62,16 @@ defmodule OLED.Display.Impl.SSD1306.Draw do {x1, y1, x2, y2} end - dx = x2 - x1 - dy = y2 - y1 + cond do + x1 == x2 -> + line_v(state, x1, y1, y2 - y1 + 1, opts) - Enum.reduce(x1..x2, state, fn x, acc -> - y = trunc(y1 + dy * (x - x1) / dx) - put_pixel(acc, x, y, opts) - end) + y1 == y2 -> + line_h(state, x1, y1, x2 - x1 + 1, opts) + + true -> + do_line(state, x1, y1, x2, y2, opts) + end end def line_h(state, _x, _y, width, _opts) when width < 1, @@ -132,4 +135,14 @@ defmodule OLED.Display.Impl.SSD1306.Draw do defp draw_circle(_x0, _y0, _x, _y, _f, _ddF_x, _ddF_y, _opts, state), do: state + + defp do_line(state, x1, y1, x2, y2, opts) do + dx = x2 - x1 + dy = y2 - y1 + + Enum.reduce(x1..x2, state, fn x, acc -> + y = trunc(y1 + dy * (x - x1) / dx) + put_pixel(acc, x, y, opts) + end) + end end diff --git a/test/oled/display/impl/ssd_1306/line_test.exs b/test/oled/display/impl/ssd_1306/line_test.exs index e2da634..34decae 100644 --- a/test/oled/display/impl/ssd_1306/line_test.exs +++ b/test/oled/display/impl/ssd_1306/line_test.exs @@ -39,7 +39,6 @@ defmodule OLED.Display.Impl.SSD1306.LineTest do ] end - #|> Enum.each(&IO.inspect/1) test "draw xor" do assert build_state(@w, @h) |> Draw.line(0, 0, 32, 8, []) @@ -71,6 +70,38 @@ defmodule OLED.Display.Impl.SSD1306.LineTest do ] end + test "draw horizontal rect" do + assert build_state(@w, @h) + |> Draw.line(4, 5, 16, 5, []) + |> ascii_render() == + [ + " ", + " ", + " ", + " ", + " ", + " ############# ", + " ", + " " + ] + end + + test "draw vertical rect" do + assert build_state(@w, @h) + |> Draw.line(10, 1, 10, 6, []) + |> ascii_render() == + [ + " ", + " # ", + " # ", + " # ", + " # ", + " # ", + " # ", + " " + ] + end + test "draw rect out 2" do assert build_state(@w, @h) |> Draw.line(-32, -8, 32, 8, [])