meshtastic / firmware

Meshtastic device firmware
https://meshtastic.org
GNU General Public License v3.0
3.3k stars 800 forks source link

A nicer compass. #4494

Open Szetya opened 4 weeks ago

Szetya commented 4 weeks ago

https://github.com/meshtastic/firmware/blob/1bbc273ba6cac076fa2c97a30178ef2bc12e682b/src/graphics/Screen.cpp#L1285 Whenever I look at the compass, I always wonder why the arrow is so simple. Maybe it could be a little more beautiful. I had time today and it's not that complicated. I tried to make a nicer compass with the drawNodeHeading and drawCompassNorth functions. I changed the north marking to a circle, because if the "N" was on top it wouldn't fit on the display on HT-VM E290. Now I kept all the original variables (N1-N4) and changed the value of the arrow "tail". Some photos of the result and the modified functions. I know it doesn't improve the function but I think it's nicer to look at. If you consider it functional could it be replaced? 😇

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);
}
//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);
display->fillTriangle(tip.x, tip.y, rightArrow.x, rightArrow.y, tail.x, tail.y);
display->drawTriangle(tip.x, tip.y, leftArrow.x, leftArrow.y, tail.x, tail.y);

}

void Screen::drawCompassNorth(OLEDDisplay *display, int16_t compassX, int16_t compassY, float myHeading) { // 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;

Point N1(-0.04f, 0.65f), N2(0.04f, 0.65f);
Point N3(-0.04f, 0.55f), N4(0.04f, 0.55f);
Point N5(0.00f, 0.50f);
Point *rosePoints[] = {&N1, &N2, &N3, &N4, &N5};

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);
}
//display->drawLine(N1.x, N1.y, N3.x, N3.y);
//display->drawLine(N2.x, N2.y, N4.x, N4.y);
//display->drawLine(N1.x, N1.y, N4.x, N4.y);
display->drawCircle(N5.x, N5.y, 4);

} IMG_20240817_202152 IMG_20240817_201902 IMG_20240817_201834

RCGV1 commented 3 weeks ago

You should make a PR

Szetya commented 3 weeks ago

You should make a PR

I am not an experienced github user. 😇

RCGV1 commented 3 weeks ago

https://youtu.be/a_FLqX3vGR4?si=gBTv4BZPeFKlox03

tropho23 commented 2 weeks ago

Yes please do submit a PR! This looks great.

Szetya commented 2 days ago

You should make a PR

I tried it once. It didn't work, I can't do it. 🙁