[Oberon] FPGA - Simple Graph Fill
Jörg
joerg.straube at iaeth.ch
Sat Nov 10 09:21:21 CET 2018
A little bit „brute force“ (I mean not as elegant as Bresenham) but this is fairly fast as well:
Draws a filled circle at (150/150) with radius 100.
MODULE Circle; (* jr/10nov18 *)
IMPORT Display;
PROCEDURE Fill*;
VAR x, y, R, R2, lim: INTEGER;
BEGIN
R := 100;
R2 := R*R;
FOR y := 0 TO R DO
lim := R2 - y*y; x := 0; WHILE x*x <= lim DO INC(x) END;
Display.ReplConst(Display.white, 150-x, 150+y, 2*x, 1, Display.paint);
Display.ReplConst(Display.white, 150-x, 150-y, 2*x, 1, Display.paint)
END;
END Fill;
END Circle.Fill
Jörg
> Am 09.11.2018 um 19:10 schrieb Jörg Straube <joerg.straube at iaeth.ch>:
>
> Wim used as error term „d“ the first derivative
> Magnus used the second derivative (error in x and y are easier to calculate but need to be cumulated (=integrated) to come to „d“, in his code called „f“)
>
> Both algos draw horizontal lines several times.
> Two of the lines have to be drawn always, the other two only when y changes.
>
> Jörg
>
>> Am 09.11.2018 um 18:49 schrieb Magnus Karlsson <magnus at saanlima.com>:
>>
>> Here is the code I used in a project to draw a filled circle using a routine to draw a horizontal line (adapted from Adafruit GFX arduino library):
>>
>> void circle(int x0, int y0, int r) {
>> int f = 1 - r;
>> int ddF_x = 1;
>> int ddF_y = -2 * r;
>> int x = 0;
>> int y = r;
>>
>> hline(x0 - r, x0 + r, y0);
>> hline(x0, x0, y0 + r);
>> hline(x0, x0, y0 - r);
>>
>> while (x < y) {
>> if (f >= 0) {
>> y--;
>> ddF_y += 2;
>> f += ddF_y;
>> }
>> x++;
>> ddF_x += 2;
>> f += ddF_x;
>> hline(x0 - x, x0 + x, y0 + y);
>> hline(x0 - x, x0 + x, y0 - y);
>> hline(x0 - y, x0 + y, y0 + x);
>> hline(x0 - y, x0 + y, y0 - x);
>> }
>> }
>>
>> Magnus
>>
>>
>>> On 11/9/2018 7:16 AM, Wim Niemann wrote:
>>> Hi,
>>>
>>> bug solved.
>>> The trace says '0 303 201 north start'. Now the color must become the fill color 8 but a few lines further on the trace prints again '0 303 201'.
>>>
>>> Like Jörg says, the order of S, E, N, W is not relevant. I'm sorry for the confusion but the directions East and South-East stemmed from the outline algorithm and were not related to a flood fill.
>>>
>>> The recursion can be replaced by iteration but a quick internet search indicated you still push new candidate pixels on a stack. For larger images, this is really memory and cpu intensive. From memory, I believe it is possible to iterate top down and do two scans left and right to prevent a pixel stack but I don't have an example by hand.
>>>
>>> Here's another approach which draws a filled circle in a single color without flood-fill:
>>>
>>> The 'Bresenham circle' version in 'Foley and van Dam' differs slightly from the Oberon version and is presented in C: (kudos for keeping it human readable)
>>>
>>> void MidpointCircle(int radius, int color)
>>> /* Assumes the center of circle is at origin. */
>>> {
>>> int x = 0;
>>> int y = radius;
>>> int d = 1 - radius;
>>> CirclePoints(x, y, color); /* draw eight-fold symmetric points */
>>> while (y > x) {
>>> if (d < 0) { /* Select E */
>>> d += 2*x + 3;
>>> } else { /* Select SE */
>>> d += 2*(x-y) + 5;
>>> y--;
>>> }
>>> x++;
>>> CirclePoints(x, y, color);
>>> }
>>> }
>>>
>>> This version either draws pixels at the same horizontal line or decreases y to a new scanline. Instead of drawing the eight pixels you can fill a horizontal line section when y is decreased to obtained a filled circle.
>>>
>>> A border color can then be achieved by drawing an outline in the border color.
>>>
>>> Wim
>>> --
>>> Oberon at lists.inf.ethz.ch mailing list for ETH Oberon and related systems
>>> https://lists.inf.ethz.ch/mailman/listinfo/oberon
>>>
>>
>> --
>> Oberon at lists.inf.ethz.ch mailing list for ETH Oberon and related systems
>> https://lists.inf.ethz.ch/mailman/listinfo/oberon
More information about the Oberon
mailing list