`_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:

`_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) ???