Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PicoGraphics Implementation of Arc, Pie and Fast Trigonometry #586

Closed
wants to merge 11 commits into from

Conversation

thinkier
Copy link
Contributor

@thinkier thinkier commented Nov 25, 2022

Hi, I implemented the maths for drawing arcs and pies for one of my projects. I thought it would be helpful to contribute this upstream too.

This works like normal trigonometry except it's degrees based (due to performance hits with float related operations). With this particular implementation, the discrete steps are 1 degree.

Example

#include <cmath>
#include <cstdlib>

#include "drivers/st7789/st7789.hpp"
#include "libraries/pico_graphics/pico_graphics.hpp"

using namespace pimoroni;

const int WIDTH = 240;
const int HEIGHT = 240;

ST7789 st7789(WIDTH, HEIGHT, ROTATE_0, true, get_spi_pins(BG_SPI_FRONT));
PicoGraphics_PenRGB332 graphics(st7789.width, st7789.height, nullptr);

Pen blk = graphics.create_pen(0x00, 0x00, 0x00);
Pen wht = graphics.create_pen(0xFF, 0xFF, 0xFF);
Pen red = graphics.create_pen(0xFF, 0x00, 0x00);
Pen orn = graphics.create_pen(0xFF, 0xA5, 0x00);
Pen ylw = graphics.create_pen(0xFF, 0xFF, 0x00);
Pen grn = graphics.create_pen(0x00, 0x80, 0x00);
Pen blu = graphics.create_pen(0x00, 0x00, 0xFF);
Pen pur = graphics.create_pen(0x4B, 0x00, 0x82);

void rainbow(int8_t r, int8_t w) {
    graphics.arc(
        Point(WIDTH / 2, HEIGHT / 2),
        Point(WIDTH / 2 + r, HEIGHT / 2),
        180,
        w
    );
}

int main() {
    st7789.set_backlight(255);
    Point c(120, 120);

    graphics.set_pen(blk);
    graphics.clear();

    // Demo of poly impl (rainbow)
    graphics.set_pen(red);
    rainbow(120, 10);
    graphics.set_pen(orn);
    rainbow(110, 10);
    graphics.set_pen(ylw);
    rainbow(100, 10);
    graphics.set_pen(grn);
    rainbow(90, 10);
    graphics.set_pen(blu);
    rainbow(80, 10);
    graphics.set_pen(pur);
    rainbow(70, 10);

    graphics.set_pen(wht);
    // Demo of pie
    graphics.arc(c, Point(180, 180), -90, 85);
    // Demo of line arc
    for (int i = 0; i < 6; i++) {
        graphics.arc(c, Point(239 - (i * 10), 120), -180);
    }

    st7789.update(&graphics);
}

Demo

picture of the working code on my pico lipo + RLCD

@thinkier
Copy link
Contributor Author

8ed7fae should address the CI failures.

@Gadgetoid
Copy link
Member

Thank you, your demo shot looks incredible! This could be really useful. I probably wont have the time to give this the attention it deserves until the new year, but it's on my radar.

@Gadgetoid
Copy link
Member

This might have been entirely supplanted by PicoVector - #783 - which, with a basic walk around the perimeter of two circles of "r" and "r - arc_thickness", can produce similar results. I posted an example to this end here - #783 (comment)

Does make me wonder if PicoVector should have an explicit arc function. It's fertile ground for all-the-shapes.

@Gadgetoid
Copy link
Member

The new, updated PicoVector does have an explicit arc function, but it's still slowly trundling through the pipeline.

Experimental builds are available here, but there is no documentation... yet - #1019

Since PicoVector can use anti-aliasing, arcs, circles and everything else looks so much nicer!

@Gadgetoid Gadgetoid closed this Oct 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants