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

Offline Pete

  • Cuz I sez so, varmint!
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #90 on: February 12, 2019, 01:50:51 PM »
Steve, Yes, I thought of using STATIC that way, too, but no go, because all of those values are subject to change when a new different sized ellipse is made. I mean as a constant, sure w2 will always be a * a, but each time a new ellipse is made, with a new value for a, that equation has to be redone in the sub.

Mark, I'll get rid of the GOTO. Thanks for testing that.

This looks like my finished modifications. I also removed the y = 0 part, as I presume if this gets put into the tool box forum we will talk about renaming the variables to less commonly used names, names unique to the sub.

Code: [Select]
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 x AS INTEGER
DIM y AS INTEGER
w2 = a * a
h2 = b * b
h2w2 = h2 * w2
x = a
LINE (ox - a, oy)-(ox + a, oy), col, BF
DO
    y = y + 1
    yyw2 = y * y * w2
    x = SQR((h2w2 - yyw2) / h2)
    LINE (ox - x, oy + y)-(ox + x, oy + y), col, BF
    LINE (ox - x, oy - y)-(ox + x, oy - y), col, BF
LOOP UNTIL y = b
END SUB

Pete
« Last Edit: February 12, 2019, 06:07:32 PM by Pete »

Offline STxAxTIC

  • Library Staff
  • Your mom would love me.
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #91 on: February 12, 2019, 02:43:02 PM »
I'm blown away that a version of the function that includes SQR is actually performing quickly!

A deep bow for having the balls to try that out again!

As for variable names - scope should save us. As part of good design, we should avoid globals (DIM SHAREDs) whenever possible, and there should be no collision whatsoever between simple variables like "y" causing interference. If it's *other* functions/subs/elements in someone's program that cause a problem with variable names, we shouldn't be obligated to hold their hand on this. Then again, qb64 functions have a bug (I refuse to call this a feature, it's a genuine "bad part") where functions can edit variables passed to them. Just terrible, and I always code to avoid being bitten by this. If we need to muck around with variable names to save people from being confused, then so be it I suppose.

Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #92 on: February 12, 2019, 02:53:40 PM »
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


I commented out one line in above code and now it is consistently matching or beating the Gold Standard Circle fill AND matching Circle fill's lowest time.

Here is the code for test I am using:
Code: [Select]
_TITLE "STATIC Ellipse Fill versus Steve Circle Fill"
'2019-02-12 add Pete's variation


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

'pete's variation 2019-02-12
SUB FlatEllipseFill1 (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

'vince variation on Steve  2019-02-12
SUB FlatEllipseFill2 (x0, y0, rx, ry, c AS _UNSIGNED LONG)
    a = 2 * rx * rx
    b = 2 * ry * ry


    x = 0
    y = ry
    dx = ry * ry
    dy = rx * rx * (1 - 2 * ry)
    e = 0
    sx = 0
    sy = a * ry

    DO WHILE sx <= sy
        LINE (x0 - x, y0 + y)-STEP(2 * x, 0), c, BF
        LINE (x0 - x, y0 - y)-STEP(2 * x, 0), c, BF

        x = x + 1
        sx = sx + b
        e = e + dx
        dx = dx + b

        IF 2 * e + dy > 0 THEN
            y = y - 1
            sy = sy - a
            e = e + dy
            dy = dy + a
        END IF
    LOOP

    x1 = x0 - x
    x2 = x0 + x
    y1 = y0 - y

    x = rx
    y = 0
    dx = ry * ry * (1 - 2 * rx)
    dy = rx * rx
    e = 0
    sx = b * rx
    sy = 0

    x3 = x0 - x

    DO WHILE sx >= sy
        LINE (x0 - x, y0 + y)-(x1, y0 + y), c, BF
        LINE (x0 - x, y0 - y)-(x1, y0 - y), c, BF
        LINE (x0 + x, y0 + y)-(x2, y0 + y), c, BF
        LINE (x0 + x, y0 - y)-(x2, y0 - y), c, BF

        y = y + 1
        sy = sy + a
        e = e + dy
        dy = dy + a

        IF 2 * e + dx > 0 THEN
            x = x - 1
            sx = sx - b
            e = e + dx
            dx = dx + b
        END IF
    LOOP

    LINE (x1, y1)-(x2, y0 + y), c, BF

END SUB


'pete's reversion back to SQR   WTH? it's fine time wise!
'pete's final? 2019-02-12  variation
SUB FlatEllipseFill3 (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 x AS INTEGER
    DIM y AS INTEGER
    w2 = a * a
    h2 = b * b
    h2w2 = h2 * w2
    x = a
    LINE (ox - a, oy)-(ox + a, oy), col, BF
    DO
        y = y + 1
        yyw2 = y * y * w2
        x = SQR((h2w2 - yyw2) / h2)
        LINE (ox - x, oy + y)-(ox + x, oy + y), col, BF
        LINE (ox - x, oy - y)-(ox + x, oy - y), col, BF
    LOOP UNTIL y = b
END SUB

'bplus reversion back to SQR  nope over twice the time!
SUB FlatEllipseFill4 (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, xr2 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
    xr2 = xRadius * xRadius
    FOR x = 1 TO xRadius
        y = scale * SQR(xr2 - 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



HA! I see a Y = 0 in circle fill code, maybe we could apply what we have learned to optimize it more. Radius = ABS(R) ???
« Last Edit: February 12, 2019, 03:08:59 PM by bplus »
B = B + ...

Offline Pete

  • Cuz I sez so, varmint!
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #93 on: February 12, 2019, 03:15:48 PM »
Mark, I tried your test program against my ellipse fill, #3 in your list, and got a better speed test than circle fill...


Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #94 on: February 12, 2019, 03:20:44 PM »
Dang! what's your system, my tests are running well under 17 secs.

I will try this in 32 bit QB64.

BTW, be sure to run tests with Browser OFF.
« Last Edit: February 12, 2019, 03:21:58 PM by bplus »
B = B + ...

Offline Pete

  • Cuz I sez so, varmint!
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #95 on: February 12, 2019, 03:25:09 PM »
LOL. My kid has the gaming computers. I'm on a $200 laptop that can't keep up with my typing most of the time! :D

OK 3 more tests with browser off. 225 total seconds for 3 runs for mine, 227 total seconds for Circle Fill. Basically a tie of 75 seconds each. Funny that both were slower with the browser off, but with so many things in Windows running in the background, who knows?

Pete
« Last Edit: February 12, 2019, 03:53:49 PM by Pete »

Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #96 on: February 12, 2019, 04:13:28 PM »
OK I wrote timings down. This ran allot closer than I expected.
Quote
My system is Windows 10 64 bit laptop, intel core i5

Running tests on QB64, 32 bit version
circle Fill      Pete's Fill
14.3945         14.5039
14.3945         14.3984
14.2891         14.3945
14.2851         14.3984
14.3945         14.4039

circle Fill    STATIC Fill mod B+
14.2305         14.4531
14.2891         14.4492
14.3945         14.4531
14.1758         14.3984
14.2305         14.3984


Running tests on QB64, 64 bit version
circle Fill      Pete's Fill
16.8672         17.0313
16.9258         16.8672
16.8125         16.9219
16.8125         16.8125
16.8711         17.0352

circle Fill      STATIC Fill mod B+
16.9219         16.9766
16.9258         16.9766
16.8164         16.8711
16.8125         16.8672
16.8125         16.8125      
B = B + ...

Offline Pete

  • Cuz I sez so, varmint!
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #97 on: February 12, 2019, 05:04:24 PM »
No real speed variance with SQR, pretty cool! Mark, if you wondered why your try at SQR was twice as slow, it was because if used SQR in a loop. Mine just uses it it once per every two lines.

The double draw method Steve submitted is about 20% slower, and the changes Vince made slowed it down about 20% more. Oops. Feel free to challenge that, anyone.

I don't think I want to bother making a hash table form here, but that's where I'd go next to remove SQR from my modification. If we can establish that there is a limit for how wide an ellipse can be, then that's certainly possible. I'm only presuming it would be faster though, I don't know for certain.

I favor the SQR one I came up with, just because it is so simplistic. It would also piss off the C people who posted the other one Bill found, with the inner x loop. Pissing off C people with BASIC just makes me happy!  Oh, if you guys think I'm the only one, check this out, it's hilarious... https://social.microsoft.com/Forums/en-US/ed0e97aa-ea86-49dd-b5b0-01fd41c82cf2/using-com-port-with-qb64

Although... who knows, maybe someone will post some other method that eats our collective lunch. Stay tuned!

Pete

Offline STxAxTIC

  • Library Staff
  • Your mom would love me.
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #98 on: February 12, 2019, 05:25:44 PM »
Weird, I wasn't aware that I found my function somewhere, because I remember using a whiteboard and the equation of the ellipse to derive my most recent submission. Once a function is simple enough though, it becomes an irreducible mousetrap, and sortof a universal truth. Translation: I bet other smart people derived the same thing, it just *has* to be true. We're too late in computing history to have actually discovered something here.

Offline Pete

  • Cuz I sez so, varmint!
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #99 on: February 12, 2019, 06:06:56 PM »
https://stackoverflow.com/questions/10322341/simple-algorithm-for-drawing-filled-ellipse-in-c-c

That's why I like to use unique variables, like pete!

Well kudos for grinding it out on your own! I was about half way there, when you posted. After that, I looked around at some stuff on the net and determined I was just heading in the same direction, except that SQR thing was bugging me, so I went on with that after making some tests to see if Steve's find was out of the running. I couldn't see how working on the boob effect would be productive, if the routine ended up being slower, which it is. So on to this single draw system, which looks like the one we will wind up with, unless someone

This is fun stuff, and again kudos. What we need now is either a new method or a way to speed up that SQR calculation in my modification. I wonder how much the internal works grinds out the SQR calculations? It only needs to be rounded as an integer. I mean we could use a square root algorithm to do that, since a hash table is a bit of overkill. It's still a bit tricky to calculate square roots, and requires loops to approximate, even with the "trick" division.

Pete
« Last Edit: February 12, 2019, 06:08:31 PM by Pete »

Offline STxAxTIC

  • Library Staff
  • Your mom would love me.
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #100 on: February 12, 2019, 06:18:21 PM »
Say, there's a mother load of info!

The one with the ascii *-characters in the curved shape is a dead ringer for my method. They even use the same Leibnitz "dx" notation for the tiny increments because this is the same exact setup used to find the area of the ellipse. Calculus is a language after all, you say certain things the same way. Staring at it harder: yikes, do they not have a LINE statement?

I see someone even attempted to do the tilted case but chickened out before arriving at any code. I know exactly why this is, and is why I was so stubborn about solving that issue this week too. The reason? A tilted ellipse does not permit (that I could derive) a strict XY-equation for its position - there's always an extra parameter. After conceding to this, I unleashed the tilted function that takes the punch and uses an extra variable.

At this exact point, I'm not even sure which is the fastest anymore. As the dust settles on this, can anyone (namely Pete or bplus) paste the newest and the greatest below this? Are we going to need a separate function for just circles?
« Last Edit: February 12, 2019, 07:11:06 PM by STxAxTIC »

Offline Pete

  • Cuz I sez so, varmint!
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #101 on: February 12, 2019, 11:22:21 PM »
Bill: I don't think we need a separate circle routine. As long as the height and the width are the same... BAM, circle. Every bit as fast, too.

The two fastest routines are yours, as modified with different variable types and DO/LOOP replacing FOR/NEXT, and yours with my modifications to substitute SQR for the inner loop. The SQR one is just a tad faster in my tests.

Guys: Do you know in th e last loop x is always zero? That means this routine puts down a horizontal line and dots the top and bottom of any ellipse. I hope that's OK with everyone. Oh, to see what I'm yacking about, here are the numbers...

Code: [Select]
FOR a = 1 TO 10
    FOR b = 1 TO 10
        CALL p(a, b)
    NEXT
NEXT

SUB p (a, b)
DIM h2 AS _INTEGER64
DIM w2 AS _INTEGER64
DIM h2w2 AS _INTEGER64
DIM yyw2 AS _INTEGER64
DIM x AS INTEGER
DIM y AS INTEGER
w2 = a * a
h2 = b * b
h2w2 = h2 * w2
DO
    y = y + 1
    yyw2 = y * y * w2
    x = SQR((h2w2 - yyw2) / h2)
    PRINT y; a; b; x; (h2w2 - yyw2) / h2
    SLEEP
LOOP UNTIL y = b
PRINT "============================="
END SUB

I got rid of one more line and a variable in my SQR code. I'll repost it here. What I want to do now is compare it with ellipses of varying size. I also want to make sure I'm getting the same x values as the one that avoids SQR with an inner loop.

Latest SQR code:
Code: [Select]
SUB FlatEllipseFill5 (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 x AS INTEGER
DIM y AS INTEGER
w2 = a * a
h2 = b * b
h2w2 = h2 * w2
LINE (ox - a, oy)-(ox + a, oy), col, BF
DO WHILE y < b
    y = y + 1
    x = SQR((h2w2 - y * y * w2) / h2)
    LINE (ox - x, oy + y)-(ox + x, oy + y), col, BF
    LINE (ox - x, oy - y)-(ox + x, oy - y), col, BF
LOOP
END SUB

You have to admit, it's pretty freakin' optimized.

Edit: removed unnecessary x = a statement. Thanks Mark!

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

Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #102 on: February 12, 2019, 11:33:30 PM »
You don't need x = a either but won't count for much.
B = B + ...

Offline Pete

  • Cuz I sez so, varmint!
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #103 on: February 13, 2019, 12:02:29 AM »
Wow, thanks. I forgot that the single line uses a, not x. Woohoo, another one bites the dust. I'm putting together a test now just to make sure the SQR one does the same size lines as the loop one. I'll let you guys know the results soon.

Pete

Offline SMcNeill

  • QB64 Developer
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #104 on: February 13, 2019, 12:25:05 AM »
Change the division to integer division.  It shaves off about a second on my test runs and still doesn't generate any duplicate lines from my preliminary testing:

Code: [Select]
SUB FlatEllipseFill6 (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 x AS INTEGER
    DIM y AS INTEGER
    w2 = a * a
    h2 = b * b
    h2w2 = h2 * w2
    LINE (ox - a, oy)-(ox + a, oy), col, BF
    DO WHILE y < b
        y = y + 1
        x = SQR((h2w2 - y * y * w2) \ h2) ' <<<< HERE
        LINE (ox - x, oy + y)-(ox + x, oy + y), col, BF
        LINE (ox - x, oy - y)-(ox + x, oy - y), col, BF
    LOOP
END SUB