mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-07-26 14:58:12 +00:00
refactor(ui): share Bresenham line + midpoint circle in GfxUtils.h
drawLine was duplicated verbatim in TrailScreen and CompassScreen, and drawCircle lived only in CompassScreen. Lift both into a gfx:: namespace header so the map and compass share one copy of each 1-px primitive. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
// being recorded.
|
||||
|
||||
#include "../GeoUtils.h"
|
||||
#include "GfxUtils.h"
|
||||
#include <math.h>
|
||||
|
||||
class CompassScreen : public UIScreen {
|
||||
@@ -15,33 +16,6 @@ class CompassScreen : public UIScreen {
|
||||
|
||||
bool gpsValid() const { int32_t lat, lon; return _task->currentLocation(lat, lon); }
|
||||
|
||||
// Midpoint circle (DisplayDriver has no circle primitive).
|
||||
static void drawCircle(DisplayDriver& d, int cx, int cy, int r) {
|
||||
int x = r, y = 0, err = 1 - r;
|
||||
while (x >= y) {
|
||||
d.fillRect(cx + x, cy + y, 1, 1); d.fillRect(cx + y, cy + x, 1, 1);
|
||||
d.fillRect(cx - y, cy + x, 1, 1); d.fillRect(cx - x, cy + y, 1, 1);
|
||||
d.fillRect(cx - x, cy - y, 1, 1); d.fillRect(cx - y, cy - x, 1, 1);
|
||||
d.fillRect(cx + y, cy - x, 1, 1); d.fillRect(cx + x, cy - y, 1, 1);
|
||||
y++;
|
||||
if (err < 0) err += 2 * y + 1;
|
||||
else { x--; err += 2 * (y - x) + 1; }
|
||||
}
|
||||
}
|
||||
|
||||
static void drawLine(DisplayDriver& d, int x0, int y0, int x1, int y1) {
|
||||
int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1;
|
||||
int dy = -abs(y1 - y0), sy = y0 < y1 ? 1 : -1;
|
||||
int err = dx + dy;
|
||||
while (true) {
|
||||
d.fillRect(x0, y0, 1, 1);
|
||||
if (x0 == x1 && y0 == y1) break;
|
||||
int e2 = err * 2;
|
||||
if (e2 >= dy) { err += dy; x0 += sx; }
|
||||
if (e2 <= dx) { err += dx; y0 += sy; }
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
CompassScreen(UITask* task) : _task(task) {}
|
||||
void enter() {}
|
||||
@@ -74,7 +48,7 @@ public:
|
||||
int cog;
|
||||
bool have = _task->currentCourse(cog);
|
||||
|
||||
drawCircle(display, cx, cy, r); // compass ring
|
||||
gfx::drawCircle(display, cx, cy, r); // compass ring
|
||||
|
||||
// Fixed forward index at the top: the direction you are travelling is
|
||||
// always "up". The compass card (North) rotates underneath it.
|
||||
@@ -98,11 +72,11 @@ public:
|
||||
|
||||
// North needle from centre.
|
||||
int nx, ny; cardPos(0, r - 2, nx, ny);
|
||||
drawLine(display, cx, cy, nx, ny);
|
||||
gfx::drawLine(display, cx, cy, nx, ny);
|
||||
float nrad = (0 - cog) * (float)M_PI / 180.0f;
|
||||
for (int da = -25; da <= 25; da += 50) {
|
||||
float a = nrad + (float)M_PI + da * (float)M_PI / 180.0f;
|
||||
drawLine(display, nx, ny, nx + (int)(sinf(a) * 4), ny - (int)(cosf(a) * 4));
|
||||
gfx::drawLine(display, nx, ny, nx + (int)(sinf(a) * 4), ny - (int)(cosf(a) * 4));
|
||||
}
|
||||
|
||||
// Cardinal letters around the rim (N at the needle tip).
|
||||
|
||||
40
examples/companion_radio/ui-new/GfxUtils.h
Normal file
40
examples/companion_radio/ui-new/GfxUtils.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
// Small 1-px drawing primitives the DisplayDriver abstraction doesn't provide
|
||||
// (no line / circle in the GFX wrapper used here). Shared by the map and the
|
||||
// compass so the Bresenham / midpoint routines aren't copy-pasted per screen.
|
||||
// Everything is plotted as 1x1 fillRect to stay within DisplayDriver's API.
|
||||
|
||||
#include <helpers/ui/DisplayDriver.h>
|
||||
#include <stdlib.h> // abs
|
||||
|
||||
namespace gfx {
|
||||
|
||||
// Bresenham line between two points.
|
||||
static inline void drawLine(DisplayDriver& d, int x0, int y0, int x1, int y1) {
|
||||
int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1;
|
||||
int dy = -abs(y1 - y0), sy = y0 < y1 ? 1 : -1;
|
||||
int err = dx + dy;
|
||||
while (true) {
|
||||
d.fillRect(x0, y0, 1, 1);
|
||||
if (x0 == x1 && y0 == y1) break;
|
||||
int e2 = err * 2;
|
||||
if (e2 >= dy) { err += dy; x0 += sx; }
|
||||
if (e2 <= dx) { err += dx; y0 += sy; }
|
||||
}
|
||||
}
|
||||
|
||||
// Midpoint-circle outline.
|
||||
static inline void drawCircle(DisplayDriver& d, int cx, int cy, int r) {
|
||||
int x = r, y = 0, err = 1 - r;
|
||||
while (x >= y) {
|
||||
d.fillRect(cx + x, cy + y, 1, 1); d.fillRect(cx + y, cy + x, 1, 1);
|
||||
d.fillRect(cx - y, cy + x, 1, 1); d.fillRect(cx - x, cy + y, 1, 1);
|
||||
d.fillRect(cx - x, cy - y, 1, 1); d.fillRect(cx - y, cy - x, 1, 1);
|
||||
d.fillRect(cx + y, cy - x, 1, 1); d.fillRect(cx + x, cy - y, 1, 1);
|
||||
y++;
|
||||
if (err < 0) err += 2 * y + 1;
|
||||
else { x--; err += 2 * (y - x) + 1; }
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "../Trail.h"
|
||||
#include "../GeoUtils.h"
|
||||
#include "GfxUtils.h"
|
||||
#include "NavView.h"
|
||||
#include <math.h>
|
||||
|
||||
@@ -733,7 +734,7 @@ private:
|
||||
drawFilledDot(display, x0, y0);
|
||||
drawOpenDot(display, x1, y1);
|
||||
} else {
|
||||
drawLine(display, x0, y0, x1, y1);
|
||||
gfx::drawLine(display, x0, y0, x1, y1);
|
||||
}
|
||||
x0 = x1;
|
||||
y0 = y1;
|
||||
@@ -882,19 +883,6 @@ private:
|
||||
display.print(lbl);
|
||||
}
|
||||
|
||||
static void drawLine(DisplayDriver& d, int x0, int y0, int x1, int y1) {
|
||||
int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1;
|
||||
int dy = -abs(y1 - y0), sy = y0 < y1 ? 1 : -1;
|
||||
int err = dx + dy;
|
||||
while (true) {
|
||||
d.fillRect(x0, y0, 1, 1);
|
||||
if (x0 == x1 && y0 == y1) break;
|
||||
int e2 = err * 2;
|
||||
if (e2 >= dy) { err += dy; x0 += sx; }
|
||||
if (e2 <= dx) { err += dx; y0 += sy; }
|
||||
}
|
||||
}
|
||||
|
||||
static void drawFilledDot(DisplayDriver& d, int cx, int cy) {
|
||||
d.fillRect(cx - 1, cy - 1, 3, 3);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user