Author Topic: Seeking best ellipse fill function. (For everyone's sake.)  (Read 990 times)

Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #60 on: February 11, 2019, 10:19:36 AM »
Current fill routine for reference.
Code: [Select]
SUB FlatEllipseFill (ox AS INTEGER, oy AS INTEGER, a AS INTEGER, b AS INTEGER, col AS _UNSIGNED LONG)
DIM h2 AS DOUBLE
DIM w2 AS DOUBLE
DIM h2w2 AS DOUBLE
DIM xi AS DOUBLE
DIM dx AS DOUBLE
DIM x AS DOUBLE
DIM y AS DOUBLE
w2 = a * a
h2 = b * b
h2w2 = h2 * w2
xi = a
dx = 0
LINE (ox - a, oy)-(ox + a, oy), col, BF
FOR y = 1 TO b
    FOR x = xi - dx + 1 TO 0 STEP -1
        IF x * x * h2 + y * y * w2 <= h2w2 THEN EXIT FOR
    NEXT
    dx = xi - x
    xi = x
    LINE (ox - xi, oy + y)-(ox + xi, oy + y), col, BF
    LINE (ox - xi, oy - y)-(ox + xi, oy - y), col, BF
NEXT
END SUB


IMO this is optimized for clarity:
Code: [Select]
SUB fEllipse (CX AS LONG, CY AS LONG, xRadius AS LONG, yRadius AS LONG, c AS _UNSIGNED LONG)
    DIM scale AS SINGLE, x AS LONG, y AS LONG
    IF xRadius = 0 OR yRadius = 0 THEN EXIT SUB  '<<<<<<<<<<<<< really do need to skip out with 0
    scale = yRadius / xRadius
    LINE (CX, CY - yRadius)-(CX, CY + yRadius), c, BF
    FOR x = 1 TO xRadius
        y = scale * SQR(xRadius * xRadius - x * x)
        LINE (CX + x, CY - y)-(CX + x, CY + y), c, BF
        LINE (CX - x, CY - y)-(CX - x, CY + y), c, BF
    NEXT
END SUB

STxAxTIC begins to obscure but optimize for speed by going around using the sq root function with this substitution for SQR, reworking this line:
Code: [Select]
y = scale * SQR(xRadius * xRadius - x * x)
to this: (except he reworks for x not y)
Code: [Select]
   
    FOR x = xi - dx + 1 TO 0 STEP -1
        IF x * x * h2 + y * y * w2 <= h2w2 THEN EXIT FOR
    NEXT
    dx = xi - x
    xi = x
Sorry, this would be clearer if I stuck to same variable names and now I see he is changing X's not Y's when drawing 2 lines.
All that to avoid using SQR, wow! That actually clears up that part of Steve's version for me, thanks.

And now, if he did it for octant instead of just quadrant, we would have something that looks like Steves code, after we also replaced the For loops with While loops since For loops are known to be slowest Loop structure.
« Last Edit: February 11, 2019, 10:35:27 AM by bplus »
B = B + ...

Offline Pete

  • Cuz I sez so, varmint!
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #61 on: February 11, 2019, 10:57:38 AM »
Other C programmershave posted this avoid using SQR method online so there is probably some reason for it. My question would be since this project is based on time.... What limits performance the most; using SQR or going from LONG to DOUBLE variables?  In other words, would SQR with LONG be faster or slower than avoiding SQR and using LONG?

Now the one Steve dug up is interesting in that it draws the ellipse in two stages. The only way that could possibly be faster is if part of an ellipse (certain axis) can use fewer calculations; so you use a quicker formula to draw that part and finish it off with the more complex computations in the other part. The problem with that method, as posted, is the boob effect, as Bill puts it. That's some yet unidentified math problem, but seriously, unless that two stage method is faster by design, it should be pitched, rather than corrected, in favor of a single drawing algorithm.

Pete

Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #62 on: February 11, 2019, 11:19:08 AM »
bplus:
Quote
And now, if he did it for octant instead of just quadrant, we would have something that looks like Steves code, after we also replaced the For loops with While loops since For loops are known to be slowest Loop structure.

I was expecting FlatEllipseFill to run twice as long as CircleFill. Wrong! It is already running neck and neck with the proven CircleFill Routine!!!


I added the exit sub if either radius = 0 and I changed all the variables to LONG and I substituted the For loop with a While loop:
I am getting very nearly the same times, sometimes CircleFill faster, sometimes FlatEllipseFill:
Code: [Select]
_TITLE "STATIC Ellipse Fill versus Steve Circle Fill"
DEFINT A-Z
SCREEN _NEWIMAGE(1220, 680, 32)
_SCREENMOVE 100, 20
_DELAY 1

FlatEllipseFill 915, 305, 300, 300, _RGBA32(0, 100, 0, 40)
FlatEllipseFill 915, 305, 300, 300, _RGBA32(0, 100, 0, 40)
INPUT "EllipseFill (fel) overlap test, press enter to continue "; wate$
LINE (0, 0)-(600, 20), _RGB32(0, 0, 0), BF
start## = TIMER
FOR i = 1 TO 10000
    FlatEllipseFill 915, 305, 300, 300, _RGBA32(0, 100, 0, 100)
NEXT
EllipseTime## = TIMER - start##
_PRINTSTRING (800, 615), "Time for 10000 EllipseFills:" + STR$(EllipseTime##)


' ==================================================== compare to the old gold standard

CircleFill 305, 305, 300, _RGBA32(0, 100, 0, 40)
CircleFill 305, 305, 300, _RGBA32(0, 100, 0, 40)
LOCATE 1, 1: INPUT "CircleFill overlap test, press enter to continue "; wate$
LINE (0, 0)-(600, 20), _RGB32(0, 0, 0), BF

start## = TIMER
FOR i = 1 TO 10000
    CircleFill 305, 305, 300, _RGBA32(0, 100, 0, 100)
NEXT
OldCircleTime## = TIMER - start##
_PRINTSTRING (200, 615), "Time for 10000 Circle Fills:" + STR$(OldCircleTime##)

'old circle fill
SUB CircleFill (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
    DIM Radius AS INTEGER, RadiusError AS INTEGER
    DIM X AS INTEGER, Y AS INTEGER

    Radius = ABS(R)
    RadiusError = -Radius
    X = Radius
    Y = 0

    IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB

    ' Draw the middle span here so we don't draw it twice in the main loop,
    ' which would be a problem with blending turned on.
    LINE (CX - X, CY)-(CX + X, CY), C, BF

    WHILE X > Y
        RadiusError = RadiusError + Y * 2 + 1
        IF RadiusError >= 0 THEN
            IF X <> Y + 1 THEN
                LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
                LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
            END IF
            X = X - 1
            RadiusError = RadiusError - X * 2
        END IF
        Y = Y + 1
        LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
        LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
    WEND

END SUB

SUB FlatEllipseFill (ox AS LONG, oy AS LONG, a AS LONG, b AS LONG, col AS _UNSIGNED LONG)
    DIM h2 AS LONG
    DIM w2 AS LONG
    DIM h2w2 AS LONG
    DIM xi AS LONG
    DIM dx AS LONG
    DIM x AS LONG
    DIM y AS LONG
    IF a = 0 OR b = 0 THEN EXIT SUB ' B+ added this
    w2 = a * a
    h2 = b * b
    h2w2 = h2 * w2
    xi = a
    dx = 0
    LINE (ox - a, oy)-(ox + a, oy), col, BF
    y = 0 ' B+ added this to eliminate FOR loop
    WHILE y < b 'b+ no FOR loop
        y = y + 1
        FOR x = xi - dx + 1 TO 0 STEP -1
            IF x * x * h2 + y * y * w2 <= h2w2 THEN EXIT FOR
        NEXT
        dx = xi - x
        xi = x
        LINE (ox - xi, oy + y)-(ox + xi, oy + y), col, BF
        LINE (ox - xi, oy - y)-(ox + xi, oy - y), col, BF
    WEND
END SUB


So even CircleFill can be pitched as FlatEllipseFill could serve as both a Circle Fill and a Flat Ellipse Fill (as I was going to do with Steve's EllipseFill before the nipple problem was discovered).

Oh dang it, another For loop yet to go!
« Last Edit: February 11, 2019, 11:40:55 AM by bplus »
B = B + ...

Offline Pete

  • Cuz I sez so, varmint!
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #63 on: February 11, 2019, 11:44:44 AM »
We already went over variable types that won't work. Just try this...

FlatEllipseFill 915, 305, 400, 200, _RGBA32(0, 100, 0, 40)

That's not an ellipse with variable types using LONG, but it becomes an ellipse if you use DOUBLE variable types. I haven't looked into the number results to see where the number results fail. I know Bill used LONG and INTEGER, which is too limited a type for this... but I just threw in DOUBLE everywhere, which is overkill. I decided to work on some of the numbers and post back...

Pete



« Last Edit: February 11, 2019, 12:21:49 PM by Pete »

Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #64 on: February 11, 2019, 12:04:40 PM »
We already went over LONG won't work. Just try this...

FlatEllipseFill 915, 305, 400, 200, _RGBA32(0, 100, 0, 40)

That's not an ellipse with LONG variable types, but it becomes an ellipse if you use DOUBLE variable types. I haven't looked into the number results to see where the number results fail. Hopefully, it's not some bug in QB64, but get this, 202, a larger number, works! I just don't have much patience when it comes to puzzles I guess, especially when I can skip right to a solution.

So if it is as fast using DOUBLE, great. If not, that's an issue. Maybe it can be fixed to use LONG by using SQR, or finding out what's wrong with LONG. I'll let you guys determine that, if you wish.

Pete

Sorry, missed that. It's probably the H2W2 number, squaring a square, say a = 400 b = 200 a^2 *b^2 = 6.4 x 10^9
but you say 202 works???
B = B + ...

Offline Pete

  • Cuz I sez so, varmint!
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #65 on: February 11, 2019, 12:08:56 PM »
I just edited the post, because it was confusing.

I tried some work with the numbers and this seems to be working out so far...

DIM h2 AS DOUBLE
DIM w2 AS DOUBLE
DIM h2w2 AS DOUBLE
DIM xi AS INTEGER
DIM dx AS INTEGER
DIM x AS INTEGER
DIM y AS INTEGER

I don't need to use a variety of variable types in my work, so feel free to tear into this as needed. I may look into it a _bit more, too.

So far, so good. Running several simulations and it looks to be behaving. Apparently, only the right side of that equation needs to have DOUBLE as the variable type.

Pete
« Last Edit: February 11, 2019, 12:55:46 PM by Pete »

Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #66 on: February 11, 2019, 12:56:12 PM »
From experimenting with following, I think you have to type them all to cover the max value w2h2 can take:
Code: [Select]
_TITLE "long type test"
DIM test AS LONG, big AS _INTEGER64
test = 100 'test olny made it to 215 ^ 4 !!!
big = test * test * test * test
WHILE big > 0 AND test < 1500
    test = test + 1
    big = test * test * test * test
WEND
PRINT test, big, (test - 1) ^ 4

switch test from LONG type to _INTEGER64
« Last Edit: February 11, 2019, 12:57:25 PM by bplus »
B = B + ...

Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #67 on: February 11, 2019, 01:17:45 PM »
As Pete warned this code did pick up errors at certain a, b with everything LONG, but runs fine with everything at _INTEGER64:
Code: [Select]
_TITLE "Flat Ellipse Fill (dimensions) test" 'edit: fix title

SCREEN _NEWIMAGE(1000, 700, 32)
_SCREENMOVE 180, 20
'B+ 2019-02-10 resave this code to
'just test this code for proper filling without overlap, timed tests are else where

FOR i = 0 TO 350 'draw ellipse at various heights

    CLS
    PRINT "b Radius"; i; "   press any to get to 400, <backspace> to go back one, <esc> for next test."

    FlatEllipseFill 500, 350, 400, i, _RGBA(255, 255, 255, 40)
    'k$ = ""
    'WHILE LEN(k$) = 0: k$ = INKEY$: WEND
    'IF k$ = CHR$(8) THEN i = i - 2
    'IF k$ = CHR$(27) THEN EXIT FOR
    _DISPLAY
    _LIMIT 5
NEXT

FOR i = 0 TO 350 'draw ellipse at various heights

    CLS
    PRINT "b Radius"; i; "   press any to get to 400, <backspace> to go back one, <esc> for next test."

    FlatEllipseFill 500, 350, i, 345, _RGBA(255, 255, 255, 40)
    'k$ = ""
    'WHILE LEN(k$) = 0: k$ = INKEY$: WEND
    'IF k$ = CHR$(8) THEN i = i - 2
    'IF k$ = CHR$(27) THEN EXIT FOR
    _DISPLAY
    _LIMIT 5

NEXT

CLS
WHILE _KEYDOWN(32) = 0 'check all sorts random stuff
    FlatEllipseFill RND * 1000, RND * 700, RND * 100, RND * 100, _RGBA32(255 * RND, 255 * RND, 255 * RND, 100 * RND)
    _DISPLAY
    _LIMIT 1
WEND


SUB FlatEllipseFill (ox AS _INTEGER64, oy AS _INTEGER64, a AS _INTEGER64, b AS _INTEGER64, col AS _UNSIGNED LONG)
    DIM h2 AS _INTEGER64
    DIM w2 AS _INTEGER64
    DIM h2w2 AS _INTEGER64
    DIM xi AS _INTEGER64
    DIM dx AS _INTEGER64
    DIM x AS _INTEGER64
    DIM y AS _INTEGER64
    IF a = 0 OR b = 0 THEN EXIT SUB ' B+ added this
    w2 = a * a
    h2 = b * b
    h2w2 = h2 * w2
    xi = a
    dx = 0
    LINE (ox - a, oy)-(ox + a, oy), col, BF
    y = 0 ' B+ added this to eliminate FOR loop
    WHILE y < b 'b+ no FOR loop
        y = y + 1
        x = xi - dx + 2
        WHILE x >= 1
            x = x - 1
            IF x * x * h2 + y * y * w2 <= h2w2 THEN EXIT WHILE
        WEND
        dx = xi - x
        xi = x
        LINE (ox - xi, oy + y)-(ox + xi, oy + y), col, BF
        LINE (ox - xi, oy - y)-(ox + xi, oy - y), col, BF
    WEND
END SUB


I confess a certain a bias to keeping everything out of float types.
« Last Edit: February 11, 2019, 01:20:12 PM by bplus »
B = B + ...

Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #68 on: February 11, 2019, 01:24:15 PM »
Flat Ellipse Fill with all variables at _INTEGER64 is still running neck and neck with Circle Fill, sometimes one or the other has the better time but Circle Fill has the lowest time that I've seen over many tests.

Code: [Select]
_TITLE "STATIC Ellipse Fill versus Steve Circle Fill"
DEFINT A-Z
SCREEN _NEWIMAGE(1220, 680, 32)
_SCREENMOVE 100, 20
_DELAY 1

FlatEllipseFill 915, 305, 300, 300, _RGBA32(0, 100, 0, 40)
FlatEllipseFill 915, 305, 300, 300, _RGBA32(0, 100, 0, 40)
INPUT "Flat EllipseFill overlap test, press enter to continue "; wate$
LINE (0, 0)-(600, 20), _RGB32(0, 0, 0), BF
start## = TIMER
FOR i = 1 TO 10000
    FlatEllipseFill 915, 305, 300, 300, _RGBA32(0, 100, 0, 100)
NEXT
EllipseTime## = TIMER - start##
_PRINTSTRING (800, 615), "Time for 10000 Flat Ellipse Fills:" + STR$(EllipseTime##)


' ==================================================== compare to the old gold standard

CircleFill 305, 305, 300, _RGBA32(0, 100, 0, 40)
CircleFill 305, 305, 300, _RGBA32(0, 100, 0, 40)
LOCATE 1, 1: INPUT "CircleFill overlap test, press enter to continue "; wate$
LINE (0, 0)-(600, 20), _RGB32(0, 0, 0), BF

start## = TIMER
FOR i = 1 TO 10000
    CircleFill 305, 305, 300, _RGBA32(0, 100, 0, 100)
NEXT
OldCircleTime## = TIMER - start##
_PRINTSTRING (200, 615), "Time for 10000 Circle Fills:" + STR$(OldCircleTime##)

'old circle fill
SUB CircleFill (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
    DIM Radius AS INTEGER, RadiusError AS INTEGER
    DIM X AS INTEGER, Y AS INTEGER

    Radius = ABS(R)
    RadiusError = -Radius
    X = Radius
    Y = 0

    IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB

    ' Draw the middle span here so we don't draw it twice in the main loop,
    ' which would be a problem with blending turned on.
    LINE (CX - X, CY)-(CX + X, CY), C, BF

    WHILE X > Y
        RadiusError = RadiusError + Y * 2 + 1
        IF RadiusError >= 0 THEN
            IF X <> Y + 1 THEN
                LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
                LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
            END IF
            X = X - 1
            RadiusError = RadiusError - X * 2
        END IF
        Y = Y + 1
        LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
        LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
    WEND

END SUB

SUB FlatEllipseFill (ox AS _INTEGER64, oy AS _INTEGER64, a AS _INTEGER64, b AS _INTEGER64, col AS _UNSIGNED LONG)
    DIM h2 AS _INTEGER64
    DIM w2 AS _INTEGER64
    DIM h2w2 AS _INTEGER64
    DIM xi AS _INTEGER64
    DIM dx AS _INTEGER64
    DIM x AS _INTEGER64
    DIM y AS _INTEGER64
    IF a = 0 OR b = 0 THEN EXIT SUB ' B+ added this
    w2 = a * a
    h2 = b * b
    h2w2 = h2 * w2
    xi = a
    dx = 0
    LINE (ox - a, oy)-(ox + a, oy), col, BF
    y = 0 ' B+ added this to eliminate FOR loop
    WHILE y < b 'b+ no FOR loop
        y = y + 1
        x = xi - dx + 2
        WHILE x >= 1
            x = x - 1
            IF x * x * h2 + y * y * w2 <= h2w2 THEN EXIT WHILE
        WEND
        dx = xi - x
        xi = x
        LINE (ox - xi, oy + y)-(ox + xi, oy + y), col, BF
        LINE (ox - xi, oy - y)-(ox + xi, oy - y), col, BF
    WEND
END SUB

B = B + ...

Offline Pete

  • Cuz I sez so, varmint!
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #69 on: February 11, 2019, 01:47:32 PM »
Would using INTEGERS run any faster? My tests I've been running showed me that what I posted previously is true, that only the right side of that equation needed more range, so...

DIM xi AS _INTEGER64
DIM dx AS _INTEGER64
DIM x AS _INTEGER64
DIM y AS _INTEGER64

Could be changed to...

DIM xi AS INTEGER
DIM dx AS INTEGER
DIM x AS INTEGER
DIM y AS INTEGER

Yep, just tested some runs. So you could use...

DIM h2 AS _INTEGER64
DIM w2 AS _INTEGER64
DIM h2w2 AS _INTEGER64
DIM xi AS INTEGER
DIM dx AS INTEGER
DIM x AS INTEGER
DIM y AS INTEGER

In any event, it looks like we have something coming along that meets the requirements nicely. By we, I mean you guys. Sorry I can't be a bigger contributor here. This just isn't my area, but it's fun, and I managed to conjure up a couple of bug fixes.

Pete

Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #70 on: February 11, 2019, 06:22:51 PM »
Concerning optimizing Type Declarations, I think (or intuit) choosing the largest type needed to do and contain all calculations for all the variables involved and to specially avoid mixing float types with integer types.
B = B + ...

Offline STxAxTIC

  • Library Staff
  • Your mom would love me.
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #71 on: February 11, 2019, 10:22:27 PM »
Ooookay where were we? First thought: a speed comparison between a raw circle fill versus an ellipse fill is somewhat of a foregone conclusion. Circles are the simplest shape in the universe, so they had better fill in quickly. Is there room for both functions in the new up-and-coming Toolbox? Hell yes, for two reasons: (i) the forum is empty right now and real estate over there is cheap, and (ii) people who still call them "ovals" probably never heard of ellipses, so those folks may be left wondering how to fill in their circles despite having glazed over a solution.

As an aside, it's lovely that the ellipse and circle-filling functions run at comparable speeds, so minimalists can just download an ellipse-filling routine and be done with the question.

After 5 forum pages I think we may have a few products. You guys are incredibly resilient for sticking to this.

Offline Pete

  • Cuz I sez so, varmint!
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #72 on: February 12, 2019, 04:29:44 AM »
So here's what we have so far with two things I added/changed...

1) Added new variable to reduce equation steps: yyw2 = y * y * w2
2) Substituted DO/LOOP in place of FOR/LOOP for speed considerations.

Code: [Select]
SCREEN _NEWIMAGE(1000, 700, 32)
_SCREENMOVE 180, 0

FlatEllipseFill 500, 350, 350, 200, _RGBA(255, 255, 255, 40)

SUB FlatEllipseFill (ox AS INTEGER, oy AS INTEGER, a AS INTEGER, b AS INTEGER, col AS _UNSIGNED LONG)
IF a = 0 OR b = 0 THEN EXIT SUB
DIM h2 AS _INTEGER64
DIM w2 AS _INTEGER64
DIM h2w2 AS _INTEGER64
DIM yyw2 AS _INTEGER64
DIM xi AS INTEGER
DIM dx AS INTEGER
DIM x AS INTEGER
DIM y AS INTEGER
w2 = a * a
h2 = b * b
h2w2 = h2 * w2
xi = a
dx = 0
y = 0
LINE (ox - a, oy)-(ox + a, oy), col, BF
DO
    y = y + 1
    yyw2 = y * y * w2
    x = xi - dx + 1
    DO
        IF x * x * h2 + yyw2 <= h2w2 THEN EXIT DO
        x = x - 1
    LOOP
    dx = xi - x
    xi = x
    LINE (ox - xi, oy + y)-(ox + xi, oy + y), col, BF
    LINE (ox - xi, oy - y)-(ox + xi, oy - y), col, BF
LOOP UNTIL y = b
END SUB

I don't think it is as elegant with these changes, but since speed is the goal, so be it.

A DO/LOOP actually requires one additional statement than a FOR/NEXT, but if you guys are sure it's still faster, it's all good this way. 

There might be some more optimization possible in these equations and this geometric progression looping approach. Maybe Steve could use his index approach to cut down the number of loops needed, but my guess would be the added conditional statements might add too much time and make it a push at best.

I posted a quick demo using this method at: https://www.tapatalk.com/groups/qbasic/viewtopic.php?f=648955&t=39432

Pete
« Last Edit: February 12, 2019, 05:09:53 AM by Pete »

Offline SMcNeill

  • QB64 Developer
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #73 on: February 12, 2019, 07:00:25 AM »
DO...LOOP is faster than FOR...NEXT just from the way they’re translated into C.  I’ll post a few simple examples in a different topic later, so as to not clutter up this one, but DO will always outperform FOR, from my experience.  (Only by a little, but when speed is the goal, each microsecond adds up.)

Offline Pete

  • Cuz I sez so, varmint!
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #74 on: February 12, 2019, 10:12:35 AM »
The thing Fell likes best about this thread is the KTMB Principle. (Keep the monkeys busy!)

Well, in terms of speed, should we be careful what we wish for, because if DO/LOOP is faster than FOR/NEXT, that's isn't so bad, but do you think GOTO could be faster, still?

Code: [Select]
SCREEN _NEWIMAGE(1000, 700, 32)
_SCREENMOVE 180, 0

FlatEllipseFill 500, 350, 350, 200, _RGBA(255, 255, 255, 40)

SUB FlatEllipseFill (ox AS INTEGER, oy AS INTEGER, a AS INTEGER, b AS INTEGER, col AS _UNSIGNED LONG)
IF a = 0 OR b = 0 THEN EXIT SUB
DIM h2 AS _INTEGER64
DIM w2 AS _INTEGER64
DIM h2w2 AS _INTEGER64
DIM yyw2 AS _INTEGER64
DIM xi AS INTEGER
DIM dx AS INTEGER
DIM x AS INTEGER
DIM y AS INTEGER
w2 = a * a
h2 = b * b
h2w2 = h2 * w2
xi = a
dx = 0
y = 0
LINE (ox - a, oy)-(ox + a, oy), col, BF
100
y = y + 1
yyw2 = y * y * w2
x = xi - dx + 1
101
IF x * x * h2 + yyw2 <= h2w2 THEN 102
x = x - 1
GOTO 101
102
dx = xi - x
xi = x
LINE (ox - xi, oy + y)-(ox + xi, oy + y), col, BF
LINE (ox - xi, oy - y)-(ox + xi, oy - y), col, BF
IF y < b THEN 100
END SUB