mirror of
https://github.com/meshtastic/firmware.git
synced 2025-08-11 07:57:22 +00:00
CompassRenderer methods
This commit is contained in:
parent
6f922641b2
commit
6e376aeea6
@ -755,35 +755,6 @@ float Screen::estimatedHeading(double lat, double lon)
|
||||
/// nodes
|
||||
static int8_t prevFrame = -1;
|
||||
|
||||
// Draw the arrow pointing to a node's location
|
||||
void Screen::drawNodeHeading(OLEDDisplay *display, int16_t compassX, int16_t compassY, uint16_t compassDiam, float headingRadian)
|
||||
{
|
||||
Point tip(0.0f, 0.5f), tail(0.0f, -0.35f); // pointing up initially
|
||||
float arrowOffsetX = 0.14f, arrowOffsetY = 1.0f;
|
||||
Point leftArrow(tip.x - arrowOffsetX, tip.y - arrowOffsetY), rightArrow(tip.x + arrowOffsetX, tip.y - arrowOffsetY);
|
||||
|
||||
Point *arrowPoints[] = {&tip, &tail, &leftArrow, &rightArrow};
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
arrowPoints[i]->rotate(headingRadian);
|
||||
arrowPoints[i]->scale(compassDiam * 0.6);
|
||||
arrowPoints[i]->translate(compassX, compassY);
|
||||
}
|
||||
/* Old arrow
|
||||
display->drawLine(tip.x, tip.y, tail.x, tail.y);
|
||||
display->drawLine(leftArrow.x, leftArrow.y, tip.x, tip.y);
|
||||
display->drawLine(rightArrow.x, rightArrow.y, tip.x, tip.y);
|
||||
display->drawLine(leftArrow.x, leftArrow.y, tail.x, tail.y);
|
||||
display->drawLine(rightArrow.x, rightArrow.y, tail.x, tail.y);
|
||||
*/
|
||||
#ifdef USE_EINK
|
||||
display->drawTriangle(tip.x, tip.y, rightArrow.x, rightArrow.y, tail.x, tail.y);
|
||||
#else
|
||||
display->fillTriangle(tip.x, tip.y, rightArrow.x, rightArrow.y, tail.x, tail.y);
|
||||
#endif
|
||||
display->drawTriangle(tip.x, tip.y, leftArrow.x, leftArrow.y, tail.x, tail.y);
|
||||
}
|
||||
|
||||
// Get a string representation of the time passed since something happened
|
||||
void Screen::getTimeAgoStr(uint32_t agoSecs, char *timeStr, uint8_t maxLength)
|
||||
{
|
||||
@ -814,55 +785,6 @@ void Screen::getTimeAgoStr(uint32_t agoSecs, char *timeStr, uint8_t maxLength)
|
||||
snprintf(timeStr, maxLength, "unknown age");
|
||||
}
|
||||
|
||||
void Screen::drawCompassNorth(OLEDDisplay *display, int16_t compassX, int16_t compassY, float myHeading)
|
||||
{
|
||||
Serial.print("🧭 [Main Compass] Raw Heading (deg): ");
|
||||
Serial.println(myHeading * RAD_TO_DEG);
|
||||
|
||||
// If north is supposed to be at the top of the compass we want rotation to be +0
|
||||
if (config.display.compass_north_top)
|
||||
myHeading = -0;
|
||||
/* N sign points currently not deleted*/
|
||||
Point N1(-0.04f, 0.65f), N2(0.04f, 0.65f); // N sign points (N1-N4)
|
||||
Point N3(-0.04f, 0.55f), N4(0.04f, 0.55f);
|
||||
Point NC1(0.00f, 0.50f); // north circle center point
|
||||
Point *rosePoints[] = {&N1, &N2, &N3, &N4, &NC1};
|
||||
|
||||
uint16_t compassDiam = Screen::getCompassDiam(SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
// North on compass will be negative of heading
|
||||
rosePoints[i]->rotate(-myHeading);
|
||||
rosePoints[i]->scale(compassDiam);
|
||||
rosePoints[i]->translate(compassX, compassY);
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t Screen::getCompassDiam(uint32_t displayWidth, uint32_t displayHeight)
|
||||
{
|
||||
uint16_t diam = 0;
|
||||
uint16_t offset = 0;
|
||||
|
||||
if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT)
|
||||
offset = FONT_HEIGHT_SMALL;
|
||||
|
||||
// get the smaller of the 2 dimensions and subtract 20
|
||||
if (displayWidth > (displayHeight - offset)) {
|
||||
diam = displayHeight - offset;
|
||||
// if 2/3 of the other size would be smaller, use that
|
||||
if (diam > (displayWidth * 2 / 3)) {
|
||||
diam = displayWidth * 2 / 3;
|
||||
}
|
||||
} else {
|
||||
diam = displayWidth;
|
||||
if (diam > ((displayHeight - offset) * 2 / 3)) {
|
||||
diam = (displayHeight - offset) * 2 / 3;
|
||||
}
|
||||
}
|
||||
|
||||
return diam - 20;
|
||||
};
|
||||
|
||||
// Combined dynamic node list frame cycling through LastHeard, HopSignal, and Distance modes
|
||||
// Uses a single frame and changes data every few seconds (E-Ink variant is separate)
|
||||
|
||||
|
@ -238,14 +238,8 @@ class Screen : public concurrency::OSThread
|
||||
void getTimeAgoStr(uint32_t agoSecs, char *timeStr, uint8_t maxLength);
|
||||
|
||||
// Draw north
|
||||
void drawCompassNorth(OLEDDisplay *display, int16_t compassX, int16_t compassY, float myHeading);
|
||||
|
||||
static uint16_t getCompassDiam(uint32_t displayWidth, uint32_t displayHeight);
|
||||
|
||||
float estimatedHeading(double lat, double lon);
|
||||
|
||||
void drawNodeHeading(OLEDDisplay *display, int16_t compassX, int16_t compassY, uint16_t compassDiam, float headingRadian);
|
||||
|
||||
void drawColumns(OLEDDisplay *display, int16_t x, int16_t y, const char **fields);
|
||||
|
||||
/// Handle button press, trackball or swipe action)
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "UIRenderer.h"
|
||||
#include "CompassRenderer.h"
|
||||
#include "GPSStatus.h"
|
||||
#include "NodeDB.h"
|
||||
#include "NodeListRenderer.h"
|
||||
@ -451,7 +452,7 @@ void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, in
|
||||
const auto &op = ourNode->position;
|
||||
float myHeading = screen->hasHeading() ? screen->getHeading() * PI / 180
|
||||
: screen->estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i));
|
||||
screen->drawCompassNorth(display, compassX, compassY, myHeading);
|
||||
CompassRenderer::drawCompassNorth(display, compassX, compassY, myHeading);
|
||||
|
||||
const auto &p = node->position;
|
||||
float d =
|
||||
@ -459,7 +460,7 @@ void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, in
|
||||
float bearing = GeoCoord::bearing(DegD(op.latitude_i), DegD(op.longitude_i), DegD(p.latitude_i), DegD(p.longitude_i));
|
||||
if (!config.display.compass_north_top)
|
||||
bearing -= myHeading;
|
||||
screen->drawNodeHeading(display, compassX, compassY, compassDiam, bearing);
|
||||
CompassRenderer::drawNodeHeading(display, compassX, compassY, compassDiam, bearing);
|
||||
|
||||
display->drawCircle(compassX, compassY, compassRadius);
|
||||
}
|
||||
@ -498,7 +499,7 @@ void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, in
|
||||
const auto &op = ourNode->position;
|
||||
float myHeading = screen->hasHeading() ? screen->getHeading() * PI / 180
|
||||
: screen->estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i));
|
||||
screen->drawCompassNorth(display, compassX, compassY, myHeading);
|
||||
graphics::CompassRenderer::drawCompassNorth(display, compassX, compassY, myHeading);
|
||||
|
||||
const auto &p = node->position;
|
||||
float d =
|
||||
@ -506,7 +507,7 @@ void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, in
|
||||
float bearing = GeoCoord::bearing(DegD(op.latitude_i), DegD(op.longitude_i), DegD(p.latitude_i), DegD(p.longitude_i));
|
||||
if (!config.display.compass_north_top)
|
||||
bearing -= myHeading;
|
||||
screen->drawNodeHeading(display, compassX, compassY, compassRadius * 2, bearing);
|
||||
graphics::CompassRenderer::drawNodeHeading(display, compassX, compassY, compassRadius * 2, bearing);
|
||||
|
||||
display->drawCircle(compassX, compassY, compassRadius);
|
||||
}
|
||||
@ -1014,7 +1015,7 @@ void drawCompassAndLocationScreen(OLEDDisplay *display, OLEDDisplayUiState *stat
|
||||
// Center vertically and nudge down slightly to keep "N" clear of header
|
||||
const int16_t compassY = topY + (usableHeight / 2) + ((FONT_HEIGHT_SMALL - 1) / 2) + 2;
|
||||
|
||||
screen->drawNodeHeading(display, compassX, compassY, compassDiam, -heading);
|
||||
CompassRenderer::drawNodeHeading(display, compassX, compassY, compassDiam, -heading);
|
||||
display->drawCircle(compassX, compassY, compassRadius);
|
||||
|
||||
// "N" label
|
||||
@ -1055,7 +1056,7 @@ void drawCompassAndLocationScreen(OLEDDisplay *display, OLEDDisplayUiState *stat
|
||||
int compassX = x + SCREEN_WIDTH / 2;
|
||||
int compassY = yBelowContent + availableHeight / 2;
|
||||
|
||||
screen->drawNodeHeading(display, compassX, compassY, compassRadius * 2, -heading);
|
||||
CompassRenderer::drawNodeHeading(display, compassX, compassY, compassRadius * 2, -heading);
|
||||
display->drawCircle(compassX, compassY, compassRadius);
|
||||
|
||||
// "N" label
|
||||
|
@ -2,6 +2,8 @@
|
||||
#include "NodeDB.h"
|
||||
#include "PowerFSM.h"
|
||||
#include "configuration.h"
|
||||
#include "graphics/draw/CompassRenderer.h"
|
||||
|
||||
#if HAS_SCREEN
|
||||
#include "gps/RTC.h"
|
||||
#include "graphics/Screen.h"
|
||||
@ -119,7 +121,7 @@ void WaypointModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state,
|
||||
|
||||
// Dimensions / co-ordinates for the compass/circle
|
||||
int16_t compassX = 0, compassY = 0;
|
||||
uint16_t compassDiam = graphics::Screen::getCompassDiam(display->getWidth(), display->getHeight());
|
||||
uint16_t compassDiam = graphics::CompassRenderer::getCompassDiam(display->getWidth(), display->getHeight());
|
||||
|
||||
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) {
|
||||
compassX = x + display->getWidth() - compassDiam / 2 - 5;
|
||||
@ -137,7 +139,7 @@ void WaypointModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state,
|
||||
myHeading = (screen->getHeading()) * PI / 180; // gotta convert compass degrees to Radians
|
||||
else
|
||||
myHeading = screen->estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i));
|
||||
screen->drawCompassNorth(display, compassX, compassY, myHeading);
|
||||
graphics::CompassRenderer::drawCompassNorth(display, compassX, compassY, myHeading);
|
||||
|
||||
// Compass bearing to waypoint
|
||||
float bearingToOther =
|
||||
@ -146,7 +148,7 @@ void WaypointModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state,
|
||||
// If the top of the compass is not a static north we need adjust bearingToOther based on heading
|
||||
if (!config.display.compass_north_top)
|
||||
bearingToOther -= myHeading;
|
||||
screen->drawNodeHeading(display, compassX, compassY, compassDiam, bearingToOther);
|
||||
graphics::CompassRenderer::drawNodeHeading(display, compassX, compassY, compassDiam, bearingToOther);
|
||||
|
||||
float bearingToOtherDegrees = (bearingToOther < 0) ? bearingToOther + 2 * PI : bearingToOther;
|
||||
bearingToOtherDegrees = bearingToOtherDegrees * 180 / PI;
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "MotionSensor.h"
|
||||
#include "graphics/draw/CompassRenderer.h"
|
||||
|
||||
#if !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C
|
||||
|
||||
@ -48,7 +49,7 @@ void MotionSensor::drawFrameCalibration(OLEDDisplay *display, OLEDDisplayUiState
|
||||
display->drawString(x, y + 40, timeRemainingBuffer);
|
||||
|
||||
int16_t compassX = 0, compassY = 0;
|
||||
uint16_t compassDiam = graphics::Screen::getCompassDiam(display->getWidth(), display->getHeight());
|
||||
uint16_t compassDiam = graphics::CompassRenderer::getCompassDiam(display->getWidth(), display->getHeight());
|
||||
|
||||
// coordinates for the center of the compass/circle
|
||||
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) {
|
||||
@ -59,7 +60,7 @@ void MotionSensor::drawFrameCalibration(OLEDDisplay *display, OLEDDisplayUiState
|
||||
compassY = y + FONT_HEIGHT_SMALL + (display->getHeight() - FONT_HEIGHT_SMALL) / 2;
|
||||
}
|
||||
display->drawCircle(compassX, compassY, compassDiam / 2);
|
||||
screen->drawCompassNorth(display, compassX, compassY, screen->getHeading() * PI / 180);
|
||||
graphics::CompassRenderer::drawCompassNorth(display, compassX, compassY, screen->getHeading() * PI / 180);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user