Building a open source graphics library from scratch

Started by Felipe de Andrade Neves Lavratti January 3, 2014
For those interested in embedded open source projects,

I've written a small graphics library to run in small MCUs, the project is
called Marsh and is hosted on github.

https://github.com/felipe-lavratti/marsh

Marsh has the following features already:
- Framebuffer based
- Draw images, icons, rectangles and texts.
- Has a widget base class that implements polymorphism in strict C.

The project has a linux GDK framebuffer simulation where you can run the
GUI on a linux window for testing propose.

Anyone needing further information, please ask.

At.
--
Skype: felipeanl

An Engineer's Guide to the LPC2100 Series

>
> I've written a small graphics library to run in small MCUs, the
> project is called Marsh and is hosted on github.
>
> https://github.com/felipe-lavratti/marsh
>
> Marsh has the following features already:
> - Framebuffer based
> - Draw images, icons, rectangles and texts.
> - Has a widget base class that implements polymorphism in strict C.
Hi Felipe

I have done something similar some time ago. What I did not find
anywhere was a simple and goofd algorithm to draw a circle with a given
line width. Did you find something like that?

Wouter
>
With antialiasing? No. The algorithms are too expansive. The approach I
predicted is to the user provide his illustrations in bmp or not compressed
png format when antialiasing is fundamental. I implemented an icon drawing
algorithm where antialiasing is faked by an alpha blending.

Circles without antialiasing on the March works nice with you use square
pen widths (1, 2, 4, 9). The algorithm is that one found on Wikipedia.

Em sexta-feira, 3 de janeiro de 2014, Wouter van Ooijen escreveu:

>
> I've written a small graphics library to run in small MCUs, the project is
> called Marsh and is hosted on github.
>
> https://github.com/felipe-lavratti/marsh
>
> Marsh has the following features already:
> - Framebuffer based
> - Draw images, icons, rectangles and texts.
> - Has a widget base class that implements polymorphism in strict C.
> Hi Felipe
>
> I have done something similar some time ago. What I did not find anywhere
> was a simple and goofd algorithm to draw a circle with a given line width.
> Did you find something like that?
>
> Wouter
>
>
>
--
Skype: felipeanl
---In l..., wrote:

Hi Felipe

I have done something similar some time ago. What I did not find anywhere was a simple and goofd algorithm to draw a circle with a given line width. Did you find something like that?

Wouter

Look up Bresenham's Circle Algorithm e.g.

http://www.ecse.rpi.edu/~wrf/Research/Short_Notes/bresenham.html http://www.ecse.rpi.edu/~wrf/Research/Short_Notes/bresenham.html

Regards,

Chris

Chris Burrows
CFB Software

http://www.astrobe.com http://www.astrobe.com/
c...@internode.on.net schreef op 03-Jan-14 10:42 PM:
> ---In l..., wrote:
>
>>
> Hi Felipe
>
> I have done something similar some time ago. What I did not find
> anywhere was a simple and goofd algorithm to draw a circle with a
> given line width. Did you find something like that?
>
> Wouter
> Look up Bresenham's Circle Algorithm e.g.

Ik know how to draw a circle. I'd like to know how to draw a decent
circle *with a given line width*.

Wouter
On 3 Jan 2014, at 22:04, Wouter van Ooijen wrote:

> c...@internode.on.net schreef op 03-Jan-14 10:42 PM:
>> ---In l..., wrote:
>>>
>> Hi Felipe
>>
>> I have done something similar some time ago. What I did not find anywhere was a simple and goofd algorithm to draw a circle with a given line width. Did you find something like that?
>>
>> Wouter
>>
>> Look up Bresenham's Circle Algorithm e.g.
>>
>>
>> Ik know how to draw a circle. I'd like to know how to draw a decent circle *with a given line width*.
>

Possibly the easiest method is to run two DDAs in parallel, one that inscribes the inner part radius of the circle and one that inscribes the outer radius of the circle.

Consider drawing anticlockwise in Quadrant I. You initially set the x co-ordinates of the DDAs to the desired radius +/- 1/2 the size of the pen to draw with. The y co-ordinate of both will be 0 at this time, and each y will increase in lock step with the dual DDAs. Each DDA step will generate a new y, y[n+1] which is simply y[n]+1. However, each step will generate two new x coordinates, inner_x[n+1] and outer_x[n+1]. Draw a horizontal line between the inner and outer x-coordinates. Keep progressing this until one of the x coordinates eventually goes negative (it will be the inner radius), at which point is is clamped to zero and both DDAs run until the outer x coordinate goes negative which indicates the quadrant is drawn.

As ever, mirror to the other three quadrants.

Regards,

Paul.
Ik know how to draw a circle. I'd like to know how to draw a decent circle *with a given line width*.

Once you can draw a single pixel circle with a given radius then all you need to do is draw a number of concentric circles to match the number of pixels in your line width - each with a radius of one pixel larger. While it is the simplest approach, it wouldn't be the most efficient method. However, as long as you are buffering the image in RAM until it is complete before refreshing the display I would not expect it to be an issue when considering the overall performance,

Chris
On 3 Jan 2014, at 22:52, wrote:
> Ik know how to draw a circle. I'd like to know how to draw a decent circle *with a given line width*.
> Once you can draw a single pixel circle with a given radius then all you need to do is draw a number of concentric circles to match the number of pixels in your line width - each with a radius of one pixel larger. While it is the simplest approach, it wouldn't be the most efficient method. However, as long as you are buffering the image in RAM until it is complete before refreshing the display I would not expect it to be an issue when considering the overall performance,
This does not work! You will find that it will work pretty well coincident with X and Y axes at 0, 90, 180, and 270 degrees, but at odd multiples of 45 degrees you find that you get missing pixels between the concentric circles. Really, you do

Paul.
---In l..., wrote:

On 3 Jan 2014, at 22:52, wrote:
Ik know how to draw a circle. I'd like to know how to draw a decent circle *with a given line width*.

This does not work! You will find that it will work pretty well coincident with X and Y axes at 0, 90, 180, and 270 degrees, but at odd multiples of 45 degrees you find that you get missing pixels between the concentric circles. Really, you do…

— Paul.

Hmm.. Yes - you are correct. This example will do it but it is a real sledgehammer approach ;-) Given that you have a single-pixel Ellipse function e.g. for a circle with a radius of 20 and a line width of 5:

r := 20;
width := 5;
FOR i := r TO r + width - 1 DO
FOR j := r TO r + width - 1 DO
Graphics.Ellipse(LCD.White, x, y, i, j)
END;
END

Chris.
Paul is right about the missing pixels on the concentric approach.

Em sexta-feira, 3 de janeiro de 2014, escreveu:

>
> ---In l... > 'l...');>, wrote:
> On 3 Jan 2014, at 22:52, > 'cfbs@...');>> > wrote:
> Ik know how to draw a circle. I'd like to know how to draw a decent circle
> *with a given line width*.
> This does not work! You will find that it will work pretty well
> coincident with X and Y axes at 0, 90, 180, and 270 degrees, but at odd
> multiples of 45 degrees you find that you get missing pixels between the
> concentric circles. Really, you do
>
> Paul.
>
> Hmm.. Yes - you are correct. This example will do it but it is a real
> sledgehammer approach ;-) Given that you have a single-pixel Ellipse
> function e.g. for a circle with a radius of 20 and a line width of 5:
>
> r := 20;
> width := 5;
> FOR i := r TO r + width - 1 DO
> FOR j := r TO r + width - 1 DO
> Graphics.Ellipse(LCD.White, x, y, i, j)
> END;
> END
>
> Chris.
>
>
>
--
Skype: felipeanl