draw enhancements

Started by garry23, May 27, 2017, 08:18:31 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

garry23

Looking into ML chdk-gui_draw.c tells me that the ML draw coding is sourced from CHDK.

Looking at the coding, which is in C, and I'm not a C programmer, tells me it should be relatively simple to add in a few enhancements, which then can be exposed in Lua.

For example, the draw_circle is coded like this:

void draw_circle(int x, int y, int r, int cl)
{
    uint8_t* bvram = bmp_vram();

    int dx = 0;
    int dy = r;
    int p=(3-(r<<1));

    do {
        bmp_putpixel_fast(bvram,(x+dx),(y+dy),cl);
        bmp_putpixel_fast(bvram,(x+dy),(y+dx),cl);
        bmp_putpixel_fast(bvram,(x+dy),(y-dx),cl);
        bmp_putpixel_fast(bvram,(x+dx),(y-dy),cl);
        bmp_putpixel_fast(bvram,(x-dx),(y-dy),cl);
        bmp_putpixel_fast(bvram,(x-dy),(y-dx),cl);
        bmp_putpixel_fast(bvram,(x-dy),(y+dx),cl);
        bmp_putpixel_fast(bvram,(x-dx),(y+dy),cl);

        ++dx;

        if (p<0)
            p += ((dx<<2)+6);
        else {
            --dy;
            p += (((dx-dy)<<2)+10);
        }
    } while (dx<=dy);
}


I've tried doing this myself, but I remain mystified at some of the C coding.

Also why do we have to duplicate certain things, eg like this:
        bmp_putpixel_fast(bvram,(x+dx),(y+dy),cl);
        bmp_putpixel_fast(bvram,(x+dy),(y+dx),cl);


My 'idea' was to use draw_circle to create a function that draws an arc, ie from angle a to angle b.

Looking at the existing coding, my thought was to simply use the existing draw_circle coding and 'simply' put in a test for the colour, ie cl.

If that part of the circle was outside the drawing angles, then don't draw or draw transparent.

Anyway, I'm afraid at this time, in my C development, I am unable to do this.

But the feature request remains: can we introduce a draw_arc into the ML chdk-gui_draw.c, and expose this in Lua?

Cheers

Garry


a1ex

The CHDK circle approximation is a mystery to me as well (and there were comments saying these circles are not even very round).

CHDK also has a draw_ellipse function based on Bresenham algorithm - this one should be more accurate, and probably easier to start from in order to implement an arc function. Still, it only computes one quadrant and draws all the others, which makes it hard to turn it into a generic draw_arc without understanding the math behind it.

Of course, you can use plain sin/cos, but I bet a naive implementation will likely give ugly results (overlapped and/or missing pixels, unless you approximate it with lines, and even in this case it's tricky to get the pixel mapping right). And it will be a lot slower.

I believe it's best to get this function from some embedded GUI library, rather than reinventing the wheel. At a quick search, I've found uGUI, which has DrawArc, but it's only limited to 90-degree arcs (any of the 4 quadrants).

garry23

@a1ex

Thanks for the pointer. I'll look into this myself, i.e. C education  ;)

Cheers

Garry

nkls

It's an optimized implementation of the Midpoint circle algorithm. The wikipedia article describes the math behind it and gives some hints on how it can be changed to draw incomplete arcs. Sounds like a good C programming task! :)
100D.100A

garry23

@nkls

Thanks for the link, things are a bit clearer now  :)

Cheers

Garry