From 8fd10d6859ca3013c72820a64f3853a2fed89622 Mon Sep 17 00:00:00 2001 From: Daniel Eisterhold Date: Sun, 17 Mar 2024 18:51:46 -0500 Subject: [PATCH] Add line_at_angle method to Display component (#6381) --- esphome/components/display/display.cpp | 15 ++++++++++ esphome/components/display/display.h | 7 +++++ tests/components/display/test.esp32.yaml | 35 ++++++++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 tests/components/display/test.esp32.yaml diff --git a/esphome/components/display/display.cpp b/esphome/components/display/display.cpp index 8ae1ee46aa..010e6eca0b 100644 --- a/esphome/components/display/display.cpp +++ b/esphome/components/display/display.cpp @@ -36,6 +36,21 @@ void HOT Display::line(int x1, int y1, int x2, int y2, Color color) { } } +void Display::line_at_angle(int x, int y, int angle, int length, Color color) { + this->line_at_angle(x, y, angle, 0, length, color); +} + +void Display::line_at_angle(int x, int y, int angle, int start_radius, int stop_radius, Color color) { + // Calculate start and end points + int x1 = (start_radius * cos(angle * M_PI / 180)) + x; + int y1 = (start_radius * sin(angle * M_PI / 180)) + y; + int x2 = (stop_radius * cos(angle * M_PI / 180)) + x; + int y2 = (stop_radius * sin(angle * M_PI / 180)) + y; + + // Draw line + this->line(x1, y1, x2, y2, color); +} + void Display::draw_pixels_at(int x_start, int y_start, int w, int h, const uint8_t *ptr, ColorOrder order, ColorBitness bitness, bool big_endian, int x_offset, int y_offset, int x_pad) { size_t line_stride = x_offset + w + x_pad; // length of each source line in pixels diff --git a/esphome/components/display/display.h b/esphome/components/display/display.h index 21954ebb71..a30ba976b4 100644 --- a/esphome/components/display/display.h +++ b/esphome/components/display/display.h @@ -258,6 +258,13 @@ class Display : public PollingComponent { /// Draw a straight line from the point [x1,y1] to [x2,y2] with the given color. void line(int x1, int y1, int x2, int y2, Color color = COLOR_ON); + /// Draw a straight line at the given angle based on the origin [x, y] for a specified length with the given color. + void line_at_angle(int x, int y, int angle, int length, Color color = COLOR_ON); + + /// Draw a straight line at the given angle based on the origin [x, y] from a specified start and stop radius with the + /// given color. + void line_at_angle(int x, int y, int angle, int start_radius, int stop_radius, Color color = COLOR_ON); + /// Draw a horizontal line from the point [x,y] to [x+width,y] with the given color. void horizontal_line(int x, int y, int width, Color color = COLOR_ON); diff --git a/tests/components/display/test.esp32.yaml b/tests/components/display/test.esp32.yaml new file mode 100644 index 0000000000..a22aa76780 --- /dev/null +++ b/tests/components/display/test.esp32.yaml @@ -0,0 +1,35 @@ +spi: + - id: spi_main_lcd + clk_pin: 16 + mosi_pin: 17 + miso_pin: 15 + +display: + - platform: ili9xxx + id: main_lcd + model: ili9342 + cs_pin: 12 + dc_pin: 13 + reset_pin: 21 + lambda: |- + // Draw an analog clock in the center of the screen + int centerX = it.get_width() / 2; + int centerY = it.get_height() / 2; + int radius = min(it.get_width(), it.get_height()) / 4; + + // Draw border + it.circle(centerX, centerY, radius); + + // Draw hour ticks + for(int h = 0; h < 12; h++) { + int hourAngle = (h * 30) - 90; + + it.line_at_angle(centerX, centerY, hourAngle, radius - 10, radius); + } + + // Draw minute ticks + for(int m = 0; m < 60; m++) { + int minuteAngle = (m * 6) - 90; + + it.line_at_angle(centerX, centerY, minuteAngle, radius - 5, radius); + }