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

0 Members and 1 Guest are viewing this topic.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #30 on: February 10, 2019, 12:01:16 pm »
Your attention to detail is indispensible plus! I wonder it the algorithm can be torn apart to find out why that happens... The thing seems to be *so* optimized that it became fragile. As soon as I get near a PC I will join your efforts...


Probably I am starting to become PIA.

I am next going to submit CircleFill to same test.
« Last Edit: February 10, 2019, 12:03:15 pm by bplus »

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #31 on: February 10, 2019, 12:18:28 pm »
Don't give up. I don't know a single person who gets a program to run correctly from the first time out of the gate, unless it's that Hello World guru.

I don't see an obvious pattern in the results you posted, which means something in the algorithm is crunching numbers with probably some decimal off in the wrong direction.

BTW- you probably meant PITA, instead of PIA, you PITA!

Pete :D
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #32 on: February 10, 2019, 12:22:22 pm »
Well hurray, CircleFill still holds up!

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #33 on: February 10, 2019, 03:26:53 pm »
Here's my fix to the 1 to 400 problem. Hey, check it carefully, as I flipped through it fast. No patience for this crap, sorry.

Anyway, if it works it works because it simply checks the boundaries set byt the fist line statements and doesn't let the second set of line statements overlap them, which was causing the initial problem at radius entries like 45, 67, etc.

Code: QB64: [Select]
  1. _TITLE "Ellipsefill from Steve"
  2. SCREEN _NEWIMAGE(1000, 700, 32)
  3. _SCREENMOVE 180, 20
  4. 'B+ 2019-02-10 resave this code to
  5. 'just test this code for proper filling without overlap, timed tests are else where
  6.  
  7. FOR i = 1 TO 400 'draw ellipse at various heights
  8.     CLS
  9.     PRINT "b Radius"; i; " Press any to get to 400, <backspace> to go back one, <esc> for next test."
  10.     EllipseFill 500, 350, 400, i, _RGBA(255, 255, 255, 40)
  11.     k$ = ""
  12.     WHILE LEN(k$) = 0: k$ = INKEY$: WEND
  13.     IF k$ = CHR$(8) THEN i = i - 2
  14.     IF k$ = CHR$(27) THEN EXIT FOR
  15.  
  16. WHILE _KEYDOWN(32) = 0 'check all sorts random stuff
  17.     EllipseFill RND * 1000, RND * 700, RND * 100, RND * 100, _RGBA32(255 * RND, 255 * RND, 255 * RND, 100 * RND)
  18.     _LIMIT 1
  19.  
  20. ' with Steve's EllipseFill, who needs CircleFill? fix for 0 radii 2019-02-05
  21. ' Is this fast enough for general circle fill (June 2018):  https://www.qb64.org/forum/index.php?topic=298.msg1942#msg1942
  22. '  EllipseFill SMcNeill (Nov 3, 2018) https://www.qb64.org/forum/index.php?topic=755.msg6506#msg6506
  23. SUB EllipseFill (cx AS INTEGER, cy AS INTEGER, rx AS INTEGER, ry AS INTEGER, c AS _UNSIGNED LONG)
  24.  
  25. DIM sx AS LONG, sy AS LONG
  26.  
  27. IF rx = 0 OR ry = 0 THEN EXIT SUB 'nothing to draw, B+ added this to avoid errors when b was 0
  28.  
  29. a = 2 * rx * rx
  30. b = 2 * ry * ry
  31. x = rx
  32. xx = ry * ry * (1 - 2 * rx)
  33. yy = rx * rx
  34. sx = b * rx
  35.  
  36. DO WHILE sx >= sy 'no = ? , nope that didn't help
  37.     LINE (cx - x, cy - y)-(cx + x, cy - y), c, BF
  38.     IF y <> 0 THEN LINE (cx - x, cy + y)-(cx + x, cy + y), c, BF
  39.     y = y + 1
  40.     sy = sy + a
  41.     e = e + yy
  42.     yy = yy + a
  43.  
  44.     IF (e + e + xx) > 0 THEN 'add = ? nope no fix
  45.         x = x - 1
  46.         sx = sx - b
  47.         e = e + xx
  48.         xx = xx + b
  49.     END IF
  50. oldy = y ' Pete's fix
  51. x = 0
  52. y = ry
  53. xx = rx * ry
  54.  
  55. yy = rx * rx * (1 - 2 * ry)
  56. e = 0
  57. sx = 0
  58. sy = a * ry
  59.  
  60.     LINE (cx - x, cy - y)-(cx + x, cy - y), c, BF
  61.     LINE (cx - x, cy + y)-(cx + x, cy + y), c, BF
  62.     DO
  63.         x = x + 1
  64.         sx = sx + b
  65.         e = e + xx
  66.         xx = xx + b
  67.     LOOP UNTIL (e + e + yy) > 0 'add = ? nope no fix
  68.     y = y - 1
  69.     sy = sy - a
  70.     e = e + yy
  71.     yy = yy + a
  72. LOOP UNTIL y < oldy
  73.  
  74.  
  75.  
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #34 on: February 10, 2019, 03:53:06 pm »
Nice Pete! I will run time tests on this fix.

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #35 on: February 10, 2019, 03:58:18 pm »
Hey did you guys find out that different ways of expressing equations are calculated faster? Case in point, I tend to own code, and I started changing things like - r + r to - 2 * r. I was about to change things like ry * ry to ry ^2, but then I thought I'd ask here first. If - r + r, or whatever it was, would run faster than the 2 * r I changed it to, then by all means, change it back before you do the speed tests. That way, you have apples to apples, should it make a difference.

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #36 on: February 10, 2019, 04:47:51 pm »
OK they are still running neck and neck, the gold standard running a very large radius circle 10000 time versus EllipseFill now with latest fix from Pete in a timed test. So the Ellipse fill can be used both for CircleFill and EllipseFill when ellipse needed has axis parallel to x, y axis, otherwise use TiltedEllipseFill for angular Ellipse fills.
« Last Edit: February 10, 2019, 04:51:32 pm by bplus »

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #37 on: February 10, 2019, 04:51:55 pm »
Did you check what I posted above about switching up some of the math calcs? I don't want such a change to impede the speed.

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #38 on: February 10, 2019, 04:53:37 pm »
Did you check what I posted above about switching up some of the math calcs? I don't want such a change to impede the speed.

Pete

Yes, nothing with the math was changed that I could see.
Here is the test code for time:
Code: QB64: [Select]
  1. _TITLE "Steves EllipseFill (right) vrs gold standard CircleFill (left), 2 tests take about 17 secs each after you press enter."
  2.  
  3. DEFINT A-Z
  4. SCREEN _NEWIMAGE(1220, 680, 32)
  5. _SCREENMOVE 100, 20
  6.  
  7. EllipseFill 915, 305, 300, 300, _RGBA32(0, 100, 0, 40)
  8. EllipseFill 915, 305, 300, 300, _RGBA32(0, 100, 0, 40)
  9. INPUT "EllipseFill (fel) overlap test, press enter to continue "; wate$
  10. LINE (0, 0)-(600, 20), _RGB32(0, 0, 0), BF
  11. start## = TIMER
  12. FOR i = 1 TO 10000
  13.     EllipseFill 915, 305, 300, 300, _RGBA32(0, 100, 0, 100)
  14. EllipseTime## = TIMER - start##
  15. _PRINTSTRING (800, 615), "Time for 10000 EllipseFills:" + STR$(EllipseTime##)
  16.  
  17.  
  18. ' ==================================================== compare to the old gold standard
  19.  
  20. CircleFill 305, 305, 300, _RGBA32(0, 100, 0, 40)
  21. CircleFill 305, 305, 300, _RGBA32(0, 100, 0, 40)
  22. LOCATE 1, 1: INPUT "CircleFill overlap test, press enter to continue "; wate$
  23. LINE (0, 0)-(600, 20), _RGB32(0, 0, 0), BF
  24.  
  25. start## = TIMER
  26. FOR i = 1 TO 10000
  27.     CircleFill 305, 305, 300, _RGBA32(0, 100, 0, 100)
  28. OldCircleTime## = TIMER - start##
  29. _PRINTSTRING (200, 615), "Time for 10000 Circle Fills:" + STR$(OldCircleTime##)
  30.  
  31. 'old circle fill
  32. SUB CircleFill (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
  33.     DIM Radius AS INTEGER, RadiusError AS INTEGER
  34.     DIM X AS INTEGER, Y AS INTEGER
  35.  
  36.     Radius = ABS(R)
  37.     RadiusError = -Radius
  38.     X = Radius
  39.     Y = 0
  40.  
  41.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  42.  
  43.     ' Draw the middle span here so we don't draw it twice in the main loop,
  44.     ' which would be a problem with blending turned on.
  45.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  46.  
  47.     WHILE X > Y
  48.         RadiusError = RadiusError + Y * 2 + 1
  49.         IF RadiusError >= 0 THEN
  50.             IF X <> Y + 1 THEN
  51.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  52.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  53.             END IF
  54.             X = X - 1
  55.             RadiusError = RadiusError - X * 2
  56.         END IF
  57.         Y = Y + 1
  58.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  59.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  60.     WEND
  61.  
  62.  
  63. ' now with Pete's fix for overlap 2019-02-10
  64. ' with Steve's EllipseFill, who needs CircleFill? fix for 0 radii 2019-02-05
  65. ' Is this fast enough for general circle fill (June 2018):  https://www.qb64.org/forum/index.php?topic=298.msg1942#msg1942
  66. '  EllipseFill SMcNeill (Nov 3, 2018) https://www.qb64.org/forum/index.php?topic=755.msg6506#msg6506
  67. SUB EllipseFill (cx AS INTEGER, cy AS INTEGER, rx AS INTEGER, ry AS INTEGER, c AS _UNSIGNED LONG)
  68.     DIM a AS LONG, b AS LONG
  69.     DIM x AS LONG, y AS LONG
  70.     DIM xx AS LONG, yy AS LONG
  71.     DIM sx AS LONG, sy AS LONG
  72.     DIM e AS LONG
  73.  
  74.     IF rx = 0 OR ry = 0 THEN EXIT SUB 'nothing to draw, B+ added this to avoid errors when b was 0
  75.  
  76.     a = 2 * rx * rx
  77.     b = 2 * ry * ry
  78.     x = rx
  79.     xx = ry * ry * (1 - rx - rx)
  80.     yy = rx * rx
  81.     sx = b * rx
  82.  
  83.     DO WHILE sx >= sy 'no = ? , nope that didn't help
  84.         LINE (cx - x, cy - y)-(cx + x, cy - y), c, BF
  85.         IF y <> 0 THEN LINE (cx - x, cy + y)-(cx + x, cy + y), c, BF
  86.  
  87.         y = y + 1
  88.         sy = sy + a
  89.         e = e + yy
  90.         yy = yy + a
  91.  
  92.         IF (e + e + xx) > 0 THEN 'add = ? nope no fix
  93.             x = x - 1
  94.             sx = sx - b
  95.             e = e + xx
  96.             xx = xx + b
  97.         END IF
  98.     LOOP
  99.     oldy = y ' Pete's fix
  100.     x = 0
  101.     y = ry
  102.     xx = rx * ry
  103.     yy = rx * rx * (1 - ry - ry)
  104.     e = 0
  105.     sx = 0
  106.     sy = a * ry
  107.  
  108.     DO '   Pete's fix eliminate >   WHILE sx <= sy ' no  =  ? fixed once but mostly no fix
  109.         LINE (cx - x, cy - y)-(cx + x, cy - y), c, BF
  110.         LINE (cx - x, cy + y)-(cx + x, cy + y), c, BF
  111.  
  112.         DO
  113.             x = x + 1
  114.             sx = sx + b
  115.             e = e + xx
  116.             xx = xx + b
  117.         LOOP UNTIL (e + e + yy) > 0 'add = ? nope no fix
  118.  
  119.         y = y - 1
  120.         sy = sy - a
  121.         e = e + yy
  122.         yy = yy + a
  123.  
  124.     LOOP UNTIL y < oldy ' pete's fix
  125.  
  126.  
  127.  

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #39 on: February 10, 2019, 05:16:27 pm »
No, reread it. I mean I changed a couple of lines from r + r to 2 * r. I'll post this one with all of the changes I can find to condense the math using powers, * 2, etc. Maybe it runs faster one way or the other, but I just like the math better with 2*, ^2, etc. If it makes no speed difference, it doesn't matter how you want to go about posting the finished product. Just know I changed 2 lines in the one you tested and you can change them back, for conformity sake, if you wish. Either way, yes, it produces the exact same math results.

So here is one I completely converted, unless I missed something.

Code: QB64: [Select]
  1. _TITLE "Ellipsefill from Steve"
  2. SCREEN _NEWIMAGE(1000, 700, 32)
  3. _SCREENMOVE 180, 20
  4. ' Pete changed math operations so r * r is now R^2, r + r is 2 * r, etc.
  5. 'B+ 2019-02-10 resave this code to
  6. 'just test this code for proper filling without overlap, timed tests are else where
  7.  
  8. FOR i = 1 TO 400 'draw ellipse at various heights
  9.     CLS
  10.     PRINT "b Radius"; i; " Press any to get to 400, <backspace> to go back one, <esc> for next test."
  11.     EllipseFill 500, 350, 400, i, _RGBA(255, 255, 255, 40)
  12.     k$ = ""
  13.     WHILE LEN(k$) = 0: k$ = INKEY$: WEND
  14.     IF k$ = CHR$(8) THEN i = i - 2
  15.     IF k$ = CHR$(27) THEN EXIT FOR
  16.  
  17. WHILE _KEYDOWN(32) = 0 'check all sorts random stuff
  18.     EllipseFill RND * 1000, RND * 700, RND * 100, RND * 100, _RGBA32(255 * RND, 255 * RND, 255 * RND, 100 * RND)
  19.     _LIMIT 1
  20.  
  21. ' with Steve's EllipseFill, who needs CircleFill? fix for 0 radii 2019-02-05
  22. ' Is this fast enough for general circle fill (June 2018):  https://www.qb64.org/forum/index.php?topic=298.msg1942#msg1942
  23. '  EllipseFill SMcNeill (Nov 3, 2018) https://www.qb64.org/forum/index.php?topic=755.msg6506#msg6506
  24. SUB EllipseFill (cx AS INTEGER, cy AS INTEGER, rx AS INTEGER, ry AS INTEGER, c AS _UNSIGNED LONG)
  25.  
  26. DIM sx AS LONG, sy AS LONG
  27.  
  28. IF rx = 0 OR ry = 0 THEN EXIT SUB 'nothing to draw, B+ added this to avoid errors when b was 0
  29.  
  30. a = 2 * rx ^ 2
  31. b = 2 * ry ^ 2
  32. x = rx
  33. xx = ry ^ 2 * (1 - 2 * rx)
  34. yy = rx ^ 2
  35. sx = b * rx
  36.  
  37. DO WHILE sx >= sy 'no = ? , nope that didn't help
  38.     LINE (cx - x, cy - y)-(cx + x, cy - y), c, BF
  39.     IF y <> 0 THEN LINE (cx - x, cy + y)-(cx + x, cy + y), c, BF
  40.     y = y + 1
  41.     sy = sy + a
  42.     e = e + yy
  43.     yy = yy + a
  44.  
  45.     IF (2 * e + xx) > 0 THEN 'add = ? nope no fix
  46.         x = x - 1
  47.         sx = sx - b
  48.         e = e + xx
  49.         xx = xx + b
  50.     END IF
  51.  
  52. oldy = y ' Pete's fix
  53. x = 0
  54. y = ry
  55. xx = rx * ry
  56.  
  57. yy = rx ^ 2 * (1 - 2 * ry)
  58. e = 0
  59. sx = 0
  60. sy = a * ry
  61.  
  62.     LINE (cx - x, cy - y)-(cx + x, cy - y), c, BF
  63.     LINE (cx - x, cy + y)-(cx + x, cy + y), c, BF
  64.     DO
  65.         x = x + 1
  66.         sx = sx + b
  67.         e = e + xx
  68.         xx = xx + b
  69.     LOOP UNTIL (2 * e + yy) > 0 'add = ? nope no fix
  70.     y = y - 1
  71.     sy = sy - a
  72.     e = e + yy
  73.     yy = yy + a
  74. LOOP UNTIL y < oldy ' Pete's fix applied here.
  75.  
  76.  
« Last Edit: February 10, 2019, 05:35:07 pm by Pete »
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • Steve’s QB64 Archive Forum
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #40 on: February 10, 2019, 06:18:28 pm »
R + R is faster than 2 * R
R * R is faster than R ^ 2

Certain operations have more overhead than others.  If you’re going to optimize for speed, choose the operator with the fastest performance.  ;)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #41 on: February 10, 2019, 06:25:40 pm »
That's what I wanted to know.

So, my fix applied with the fastest math method according to Steve would be...

Code: QB64: [Select]
  1. _TITLE "Ellipsefill from Steve"
  2. SCREEN _NEWIMAGE(1000, 700, 32)
  3. _SCREENMOVE 180, 20
  4. 'B+ 2019-02-10 resave this code to
  5. 'just test this code for proper filling without overlap, timed tests are else where
  6.  
  7. FOR i = 1 TO 400 'draw ellipse at various heights
  8.     CLS
  9.     PRINT "b Radius"; i; " Press any to get to 400, <backspace> to go back one, <esc> for next test."
  10.     EllipseFill 500, 350, 400, i, _RGBA(255, 255, 255, 40)
  11.     k$ = ""
  12.     WHILE LEN(k$) = 0: k$ = INKEY$: WEND
  13.     IF k$ = CHR$(8) THEN i = i - 2
  14.     IF k$ = CHR$(27) THEN EXIT FOR
  15.  
  16. WHILE _KEYDOWN(32) = 0 'check all sorts random stuff
  17.     EllipseFill RND * 1000, RND * 700, RND * 100, RND * 100, _RGBA32(255 * RND, 255 * RND, 255 * RND, 100 * RND)
  18.     _LIMIT 1
  19.  
  20. ' with Steve's EllipseFill, who needs CircleFill? fix for 0 radii 2019-02-05
  21. ' Is this fast enough for general circle fill (June 2018):  https://www.qb64.org/forum/index.php?topic=298.msg1942#msg1942
  22. '  EllipseFill SMcNeill (Nov 3, 2018) https://www.qb64.org/forum/index.php?topic=755.msg6506#msg6506
  23. SUB EllipseFill (cx AS INTEGER, cy AS INTEGER, rx AS INTEGER, ry AS INTEGER, c AS _UNSIGNED LONG)
  24.  
  25. DIM sx AS LONG, sy AS LONG
  26.  
  27. IF rx = 0 OR ry = 0 THEN EXIT SUB 'nothing to draw, B+ added this to avoid errors when b was 0
  28.  
  29. a = 2 * rx * rx
  30. b = 2 * ry * ry
  31. x = rx
  32. xx = ry * ry * (1 - rx - rx)
  33. yy = rx * rx
  34. sx = b * rx
  35.  
  36. DO WHILE sx >= sy
  37.     LINE (cx - x, cy - y)-(cx + x, cy - y), c, BF
  38.     IF y <> 0 THEN LINE (cx - x, cy + y)-(cx + x, cy + y), c, BF
  39.     y = y + 1
  40.     sy = sy + a
  41.     e = e + yy
  42.     yy = yy + a
  43.  
  44.     IF (e + e + xx) > 0 THEN
  45.         x = x - 1
  46.         sx = sx - b
  47.         e = e + xx
  48.         xx = xx + b
  49.     END IF
  50. oldy = y ' Pete's fix. Get the last fill position.
  51. x = 0
  52. y = ry
  53. xx = rx * ry
  54.  
  55. yy = rx * rx * (1 - ry - ry)
  56. e = 0
  57. sx = 0
  58. sy = a * ry
  59.  
  60.     LINE (cx - x, cy - y)-(cx + x, cy - y), c, BF
  61.     LINE (cx - x, cy + y)-(cx + x, cy + y), c, BF
  62.     DO
  63.         x = x + 1
  64.         sx = sx + b
  65.         e = e + xx
  66.         xx = xx + b
  67.     LOOP UNTIL (e + e + yy) > 0
  68.     y = y - 1
  69.     sy = sy - a
  70.     e = e + yy
  71.     yy = yy + a
  72. LOOP UNTIL y < oldy ' Pete's fix applied here.
  73.  
  74.  
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #42 on: February 10, 2019, 06:34:06 pm »
That's what I wanted to know.

So, my fix applied with the fastest math method according to Steve would be...

Code: QB64: [Select]
  1. _TITLE "Ellipsefill from Steve"
  2. SCREEN _NEWIMAGE(1000, 700, 32)
  3. _SCREENMOVE 180, 20
  4. 'B+ 2019-02-10 resave this code to
  5. 'just test this code for proper filling without overlap, timed tests are else where
  6.  
  7. FOR i = 1 TO 400 'draw ellipse at various heights
  8.     CLS
  9.     PRINT "b Radius"; i; " Press any to get to 400, <backspace> to go back one, <esc> for next test."
  10.     EllipseFill 500, 350, 400, i, _RGBA(255, 255, 255, 40)
  11.     k$ = ""
  12.     WHILE LEN(k$) = 0: k$ = INKEY$: WEND
  13.     IF k$ = CHR$(8) THEN i = i - 2
  14.     IF k$ = CHR$(27) THEN EXIT FOR
  15.  
  16. WHILE _KEYDOWN(32) = 0 'check all sorts random stuff
  17.     EllipseFill RND * 1000, RND * 700, RND * 100, RND * 100, _RGBA32(255 * RND, 255 * RND, 255 * RND, 100 * RND)
  18.     _LIMIT 1
  19.  
  20. ' with Steve's EllipseFill, who needs CircleFill? fix for 0 radii 2019-02-05
  21. ' Is this fast enough for general circle fill (June 2018):  https://www.qb64.org/forum/index.php?topic=298.msg1942#msg1942
  22. '  EllipseFill SMcNeill (Nov 3, 2018) https://www.qb64.org/forum/index.php?topic=755.msg6506#msg6506
  23. SUB EllipseFill (cx AS INTEGER, cy AS INTEGER, rx AS INTEGER, ry AS INTEGER, c AS _UNSIGNED LONG)
  24.  
  25. DIM sx AS LONG, sy AS LONG
  26.  
  27. IF rx = 0 OR ry = 0 THEN EXIT SUB 'nothing to draw, B+ added this to avoid errors when b was 0
  28.  
  29. a = 2 * rx * rx
  30. b = 2 * ry * ry
  31. x = rx
  32. xx = ry * ry * (1 - rx - rx)
  33. yy = rx * rx
  34. sx = b * rx
  35.  
  36. DO WHILE sx >= sy
  37.     LINE (cx - x, cy - y)-(cx + x, cy - y), c, BF
  38.     IF y <> 0 THEN LINE (cx - x, cy + y)-(cx + x, cy + y), c, BF
  39.     y = y + 1
  40.     sy = sy + a
  41.     e = e + yy
  42.     yy = yy + a
  43.  
  44.     IF (e + e + xx) > 0 THEN
  45.         x = x - 1
  46.         sx = sx - b
  47.         e = e + xx
  48.         xx = xx + b
  49.     END IF
  50. oldy = y ' Pete's fix. Get the last fill position.
  51. x = 0
  52. y = ry
  53. xx = rx * ry
  54.  
  55. yy = rx * rx * (1 - ry - ry)
  56. e = 0
  57. sx = 0
  58. sy = a * ry
  59.  
  60.     LINE (cx - x, cy - y)-(cx + x, cy - y), c, BF
  61.     LINE (cx - x, cy + y)-(cx + x, cy + y), c, BF
  62.     DO
  63.         x = x + 1
  64.         sx = sx + b
  65.         e = e + xx
  66.         xx = xx + b
  67.     LOOP UNTIL (e + e + yy) > 0
  68.     y = y - 1
  69.     sy = sy - a
  70.     e = e + yy
  71.     yy = yy + a
  72. LOOP UNTIL y < oldy ' Pete's fix applied here.
  73.  
  74.  

And that is what I had in my timed tests and that is why I said Pete made no math changes.

we could change:
    a = 2 * rx * rx
    b = 2 * ry * ry

to a = rx*rx + rx*rx
    b = ry*ry + ry * ry
« Last Edit: February 10, 2019, 06:39:31 pm by bplus »

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • Steve’s QB64 Archive Forum
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #43 on: February 10, 2019, 06:43:47 pm »
Quote
    a = 2 * rx * rx

to a = rx*rx + rx*rx

You’ll just be slower....

You’re going from 2 multiplication operations to 2 multiplication operations AND an addition operation.

Maybe:  a1 = rx * rx: a = a1 + a1  (If lookup times are faster)
« Last Edit: February 10, 2019, 06:45:44 pm by SMcNeill »
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Seeking best ellipse fill function. (For everyone's sake.)
« Reply #44 on: February 10, 2019, 06:48:18 pm »
Yep! Confirmed I changed it back.