Author Topic: EllipseFill  (Read 7929 times)

0 Members and 1 Guest are viewing this topic.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
EllipseFill
« on: November 03, 2018, 06:18:38 am »
An ellipse filling routine, as fast as (or faster than) CircleFill:

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(1000, 800, 32)
  2.  
  3.  
  4. t# = TIMER
  5. FOR i = 1 TO 1000
  6.     CircleFill 500, 400, 400, -1
  7. t2# = TIMER
  8. FOR i = 1 TO 1000
  9.     EllipseFill 500, 400, 400, 400, -1
  10. t3# = TIMER
  11.  
  12.  
  13. PRINT "Time for CircleFill:"; t2# - t#
  14. PRINT "Time for EllipseFill:"; t3# - t2#
  15.  
  16.  
  17. EllipseFill 500, 400, 400, 200, &HAFFF0000
  18. CircleFill 500, 400, 180, &HFF000000
  19. EllipseFill 500, 400, 20, 160, &HAFFF0000
  20.  
  21.  
  22. EllipseFill 500, 400, 500, 400, &HAFFF0000
  23.  
  24. SUB CircleFill (CX AS LONG, CY AS LONG, R AS LONG, C AS LONG)
  25.     DIM Radius AS LONG, RadiusError AS LONG
  26.     DIM X AS LONG, Y AS LONG
  27.  
  28.     Radius = ABS(R)
  29.     RadiusError = -Radius
  30.     X = Radius
  31.     Y = 0
  32.  
  33.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  34.  
  35.     ' Draw the middle span here so we don't draw it twice in the main loop,
  36.     ' which would be a problem with blending turned on.
  37.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  38.  
  39.     WHILE X > Y
  40.         RadiusError = RadiusError + Y * 2 + 1
  41.         IF RadiusError >= 0 THEN
  42.             IF X <> Y + 1 THEN
  43.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  44.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  45.             END IF
  46.             X = X - 1
  47.             RadiusError = RadiusError - X * 2
  48.         END IF
  49.         Y = Y + 1
  50.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  51.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  52.     WEND
  53.  
  54. SUB EllipseFill (cx AS INTEGER, cy AS INTEGER, rx AS INTEGER, ry AS INTEGER, c AS LONG)
  55.     DIM a AS LONG, b AS LONG
  56.     DIM x AS LONG, y AS LONG
  57.     DIM xx AS LONG, yy AS LONG
  58.     DIM sx AS LONG, sy AS LONG
  59.     DIM e AS LONG
  60.  
  61.     a = 2 * rx * rx
  62.     b = 2 * ry * ry
  63.     x = rx
  64.     xx = ry * ry * (1 - rx - rx)
  65.     yy = rx * rx
  66.     sx = b * rx
  67.  
  68.     DO WHILE sx >= sy
  69.         LINE (cx - x, cy - y)-(cx + x, cy - y), c, BF
  70.         IF y <> 0 THEN LINE (cx - x, cy + y)-(cx + x, cy + y), c, BF
  71.  
  72.         y = y + 1
  73.         sy = sy + a
  74.         e = e + yy
  75.         yy = yy + a
  76.  
  77.         IF (e + e + xx) > 0 THEN
  78.             x = x - 1
  79.             sx = sx - b
  80.             e = e + xx
  81.             xx = xx + b
  82.         END IF
  83.     LOOP
  84.  
  85.     x = 0
  86.     y = ry
  87.     xx = rx * ry
  88.     yy = rx * rx * (1 - ry - ry)
  89.     e = 0
  90.     sx = 0
  91.     sy = a * ry
  92.  
  93.     DO WHILE sx <= sy
  94.         LINE (cx - x, cy - y)-(cx + x, cy - y), c, BF
  95.         LINE (cx - x, cy + y)-(cx + x, cy + y), c, BF
  96.  
  97.         DO
  98.             x = x + 1
  99.             sx = sx + b
  100.             e = e + xx
  101.             xx = xx + b
  102.         LOOP UNTIL (e + e + yy) > 0
  103.  
  104.         y = y - 1
  105.         sy = sy - a
  106.         e = e + yy
  107.         yy = yy + a
  108.  
  109.     LOOP
  110.  
  111.  

Note: I take no credit for this EllipseFill, as I found it on an old archive on my drive and then promptly lost it again while closing tabs and testing things.  I dunno who came up with this originally, but I'll see if I can find where the crap the source was hiding so I can give proper credit where credit is due later.

Edit: Original routine that I'd posted was created by unknown author.  Version up now has been modified to remove streaking (as described by bplus below) and improve performance slightly, by yours truly.  Enjoy!
« Last Edit: November 03, 2018, 06:53:09 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 + ...
    • View Profile
Re: EllipseFill
« Reply #1 on: November 03, 2018, 12:57:30 pm »
Steve, you are on a hot streak! One great post after another.

From another forum I learned that if you have code for an ellipse, you don't need to also carry code for a circle.

Oh, one more test...

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: EllipseFill
« Reply #2 on: November 03, 2018, 01:03:17 pm »
Fails! but sure does look neat.

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(1000, 700, 32)
  2.  
  3.  
  4. t# = TIMER
  5. FOR i = 1 TO 1000
  6.     CircleFill 500, 400, 400, -1
  7. t2# = TIMER
  8. FOR i = 1 TO 1000
  9.     EllipseFill 500, 400, 400, 400, -1
  10. t3# = TIMER
  11.  
  12.  
  13. PRINT "Time for CircleFill:"; t2# - t#
  14. PRINT "Time for EllipseFill:"; t3# - t2#
  15.  
  16.  
  17. WHILE _KEYDOWN(27) = 0
  18.     EllipseFill RND * 1000, RND * 700, RND * 100, RND * 100, _RGBA32(255 * RND, 255 * RND, 255 * RND, 100 * RND)
  19.     _LIMIT 5
  20.  
  21. SUB CircleFill (CX AS LONG, CY AS LONG, R AS LONG, C AS LONG)
  22.     DIM Radius AS LONG, RadiusError AS LONG
  23.     DIM X AS LONG, Y AS LONG
  24.  
  25.     Radius = ABS(R)
  26.     RadiusError = -Radius
  27.     X = Radius
  28.     Y = 0
  29.  
  30.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  31.  
  32.     ' Draw the middle span here so we don't draw it twice in the main loop,
  33.     ' which would be a problem with blending turned on.
  34.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  35.  
  36.     WHILE X > Y
  37.         RadiusError = RadiusError + Y * 2 + 1
  38.         IF RadiusError >= 0 THEN
  39.             IF X <> Y + 1 THEN
  40.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  41.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  42.             END IF
  43.             X = X - 1
  44.             RadiusError = RadiusError - X * 2
  45.         END IF
  46.         Y = Y + 1
  47.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  48.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  49.     WEND
  50.  
  51. SUB EllipseFill (cx AS INTEGER, cy AS INTEGER, rx AS INTEGER, ry AS INTEGER, c AS _UNSIGNED LONG)
  52.     DIM a AS LONG, b AS LONG
  53.     DIM x AS LONG, y AS LONG
  54.     DIM xx AS LONG, yy AS LONG
  55.     DIM sx AS LONG, sy AS LONG
  56.     DIM e AS LONG
  57.  
  58.     a = 2 * rx * rx
  59.     b = 2 * ry * ry
  60.     x = rx
  61.     xx = ry * ry * (1 - rx - rx)
  62.     yy = rx * rx
  63.     sx = b * rx
  64.  
  65.     DO WHILE sx >= sy
  66.         LINE (cx - x, cy - y)-(cx + x, cy - y), c, BF
  67.         LINE (cx - x, cy + y)-(cx + x, cy + y), c, BF
  68.  
  69.         y = y + 1
  70.         sy = sy + a
  71.         e = e + yy
  72.         yy = yy + a
  73.  
  74.         IF (e + e + xx) > 0 THEN
  75.             x = x - 1
  76.             sx = sx - b
  77.             e = e + xx
  78.             xx = xx + b
  79.         END IF
  80.     LOOP
  81.  
  82.     x = 0
  83.     y = ry
  84.     xx = rx * ry
  85.     yy = rx * rx * (1 - ry - ry)
  86.     e = 0
  87.     sx = 0
  88.     sy = a * ry
  89.  
  90.     DO WHILE sx <= sy
  91.         LINE (cx - x, cy - y)-(cx + x, cy - y), c, BF
  92.         LINE (cx - x, cy + y)-(cx + x, cy + y), c, BF
  93.  
  94.         x = x + 1
  95.         sx = sx + b
  96.         e = e + xx
  97.         xx = xx + b
  98.  
  99.         IF (e + e + yy) > 0 THEN
  100.             y = y - 1
  101.             sy = sy - a
  102.             e = e + yy
  103.             yy = yy + a
  104.         END IF
  105.     LOOP
  106.  
  107.  
  108.  
ellipse alpha test.PNG
* ellipse alpha test.PNG (Filesize: 161.96 KB, Dimensions: 1005x723, Views: 321)
« Last Edit: November 03, 2018, 01:05:22 pm by bplus »

Offline TerryRitchie

  • Seasoned Forum Regular
  • Posts: 495
  • Semper Fidelis
    • View Profile
Re: EllipseFill
« Reply #3 on: November 03, 2018, 01:50:31 pm »
Steve, you are on a hot streak! One great post after another.

My SMcNeill examples folder is getting quite large with code snippets :)
In order to understand recursion, one must first understand recursion.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: EllipseFill
« Reply #4 on: November 03, 2018, 02:45:52 pm »
Steve, you are on a hot streak! One great post after another.

From another forum I learned that if you have code for an ellipse, you don't need to also carry code for a circle.

Oh, one more test...

Exactly!  After all, a circle is nothing more than an ellipse whose Xradius is the same as the Yradius.  Think of it exactly as you would a square -- nothing more than a rectangle whose length is the same as its width.

If you can draw a rectangle, you can create a square.  If you can draw an ellipse, you can create a circle.

This is a little slower than CircleFill, but for the added flexibility, and the minor performance lost, I think it's more than acceptable as a "go to routine", in most instances.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: EllipseFill
« Reply #5 on: November 03, 2018, 02:52:34 pm »
Well I would use it to replace circle fill because the time is so close but it is failing the alpha test, it's lines are overlapping and leaving streaks which I thought you might see in screen shot above.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: EllipseFill
« Reply #6 on: November 03, 2018, 02:56:58 pm »
I'm on my iPad right now; didn't zoom in that close to look good.  I'll play around with it later; it might be something easy enough to correct.  :)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: EllipseFill
« Reply #7 on: November 03, 2018, 03:24:22 pm »
Try this version, bplus, and see if it fixes the line issue for you:

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(1000, 800, 32)
  2.  
  3.  
  4. t# = TIMER
  5. FOR i = 1 TO 1000
  6.     CircleFill 500, 400, 400, -1
  7. t2# = TIMER
  8. FOR i = 1 TO 1000
  9.     EllipseFill 500, 400, 200, 400, -1
  10. t3# = TIMER
  11.  
  12.  
  13. PRINT "Time for CircleFill:"; t2# - t#
  14. PRINT "Time for EllipseFill:"; t3# - t2#
  15.  
  16.  
  17. EllipseFill 500, 400, 400, 200, &H7FFFFF00
  18. CircleFill 500, 400, 180, &HFF000000
  19. EllipseFill 500, 400, 20, 160, &H7FF00FF0
  20.  
  21.  
  22. SUB CircleFill (CX AS LONG, CY AS LONG, R AS LONG, C AS LONG)
  23.     DIM Radius AS LONG, RadiusError AS LONG
  24.     DIM X AS LONG, Y AS LONG
  25.  
  26.     Radius = ABS(R)
  27.     RadiusError = -Radius
  28.     X = Radius
  29.     Y = 0
  30.  
  31.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  32.  
  33.     ' Draw the middle span here so we don't draw it twice in the main loop,
  34.     ' which would be a problem with blending turned on.
  35.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  36.  
  37.     WHILE X > Y
  38.         RadiusError = RadiusError + Y * 2 + 1
  39.         IF RadiusError >= 0 THEN
  40.             IF X <> Y + 1 THEN
  41.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  42.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  43.             END IF
  44.             X = X - 1
  45.             RadiusError = RadiusError - X * 2
  46.         END IF
  47.         Y = Y + 1
  48.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  49.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  50.     WEND
  51.  
  52. SUB EllipseFill (cx AS INTEGER, cy AS INTEGER, rx AS INTEGER, ry AS INTEGER, c AS LONG)
  53.     DIM a AS LONG, b AS LONG
  54.     DIM x AS LONG, y AS LONG
  55.     DIM xx AS LONG, yy AS LONG
  56.     DIM sx AS LONG, sy AS LONG
  57.     DIM e AS LONG
  58.  
  59.     a = 2 * rx * rx
  60.     b = 2 * ry * ry
  61.     x = rx
  62.     xx = ry * ry * (1 - rx - rx)
  63.     yy = rx * rx
  64.     sx = b * rx
  65.  
  66.     DO WHILE sx >= sy
  67.         LINE (cx - x, cy - y)-(cx + x, cy - y), c
  68.         IF y <> -y THEN LINE (cx - x, cy + y)-(cx + x, cy + y), c, BF
  69.         y = y + 1
  70.         sy = sy + a
  71.         e = e + yy
  72.         yy = yy + a
  73.  
  74.         IF (e + e + xx) > 0 THEN
  75.             x = x - 1
  76.             sx = sx - b
  77.             e = e + xx
  78.             xx = xx + b
  79.         END IF
  80.     LOOP
  81.  
  82.     x = 0
  83.     y = ry
  84.     xx = rx * ry
  85.     yy = rx * rx * (1 - ry - ry)
  86.     e = 0
  87.     sx = 1
  88.     sy = a * ry
  89.  
  90.     DO WHILE sx <= sy
  91.  
  92.         LINE (cx - x, cy - y)-(cx + x, cy - y), c, BF
  93.         LINE (cx - x, cy + y)-(cx + x, cy + y), c, BF
  94.  
  95.         DO
  96.             x = x + 1
  97.             sx = sx + b
  98.             e = e + xx
  99.             xx = xx + b
  100.         LOOP UNTIL (e + e + yy) > 0
  101.  
  102.         y = y - 1
  103.         sy = sy - a
  104.         e = e + yy
  105.         yy = yy + a
  106.  
  107.     LOOP
  108.  
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: EllipseFill
« Reply #8 on: November 03, 2018, 03:33:33 pm »
Thanks Steve,

Yes, overlap fixed but now time is 1.32 for circle and 2.47 for ellipse, so I will keep circle but use this for ellipse because I don't think I will find better.
ellipsefill.PNG
* ellipsefill.PNG (Filesize: 82.83 KB, Dimensions: 1001x735, Views: 256)

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: EllipseFill
« Reply #9 on: November 03, 2018, 03:41:59 pm »
Thanks Steve,

Yes, overlap fixed but now time is 1.32 for circle and 2.47 for ellipse, so I will keep circle but use this for ellipse because I don't think I will find better.

I found better:

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(1000, 800, 32)
  2.  
  3.  
  4. t# = TIMER
  5. FOR i = 1 TO 1000
  6.     CircleFill 500, 400, 400, -1
  7. t2# = TIMER
  8. FOR i = 1 TO 1000
  9.     EllipseFill 500, 400, 400, 400, -1
  10. t3# = TIMER
  11.  
  12.  
  13. PRINT "Time for CircleFill:"; t2# - t#
  14. PRINT "Time for EllipseFill:"; t3# - t2#
  15.  
  16.  
  17. EllipseFill 500, 400, 400, 200, &HAFFF0000
  18. CircleFill 500, 400, 180, &HFF000000
  19. EllipseFill 500, 400, 20, 160, &HAFFF0000
  20.  
  21.  
  22. EllipseFill 500, 400, 500, 400, &HAFFF0000
  23.  
  24. SUB CircleFill (CX AS LONG, CY AS LONG, R AS LONG, C AS LONG)
  25.     DIM Radius AS LONG, RadiusError AS LONG
  26.     DIM X AS LONG, Y AS LONG
  27.  
  28.     Radius = ABS(R)
  29.     RadiusError = -Radius
  30.     X = Radius
  31.     Y = 0
  32.  
  33.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  34.  
  35.     ' Draw the middle span here so we don't draw it twice in the main loop,
  36.     ' which would be a problem with blending turned on.
  37.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  38.  
  39.     WHILE X > Y
  40.         RadiusError = RadiusError + Y * 2 + 1
  41.         IF RadiusError >= 0 THEN
  42.             IF X <> Y + 1 THEN
  43.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  44.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  45.             END IF
  46.             X = X - 1
  47.             RadiusError = RadiusError - X * 2
  48.         END IF
  49.         Y = Y + 1
  50.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  51.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  52.     WEND
  53.  
  54. SUB EllipseFill (cx AS INTEGER, cy AS INTEGER, rx AS INTEGER, ry AS INTEGER, c AS LONG)
  55.     DIM a AS LONG, b AS LONG
  56.     DIM x AS LONG, y AS LONG
  57.     DIM xx AS LONG, yy AS LONG
  58.     DIM sx AS LONG, sy AS LONG
  59.     DIM e AS LONG
  60.  
  61.     a = 2 * rx * rx
  62.     b = 2 * ry * ry
  63.     x = rx
  64.     xx = ry * ry * (1 - rx - rx)
  65.     yy = rx * rx
  66.     sx = b * rx
  67.  
  68.     DO WHILE sx >= sy
  69.         LINE (cx - x, cy - y)-(cx + x, cy - y), c, BF
  70.         IF y <> 0 THEN LINE (cx - x, cy + y)-(cx + x, cy + y), c, BF
  71.  
  72.         y = y + 1
  73.         sy = sy + a
  74.         e = e + yy
  75.         yy = yy + a
  76.  
  77.         IF (e + e + xx) > 0 THEN
  78.             x = x - 1
  79.             sx = sx - b
  80.             e = e + xx
  81.             xx = xx + b
  82.         END IF
  83.     LOOP
  84.  
  85.     x = 0
  86.     y = ry
  87.     xx = rx * ry
  88.     yy = rx * rx * (1 - ry - ry)
  89.     e = 0
  90.     sx = 0
  91.     sy = a * ry
  92.  
  93.     DO WHILE sx <= sy
  94.         LINE (cx - x, cy - y)-(cx + x, cy - y), c, BF
  95.         LINE (cx - x, cy + y)-(cx + x, cy + y), c, BF
  96.  
  97.         DO
  98.             x = x + 1
  99.             sx = sx + b
  100.             e = e + xx
  101.             xx = xx + b
  102.         LOOP UNTIL (e + e + yy) > 0
  103.  
  104.         y = y - 1
  105.         sy = sy - a
  106.         e = e + yy
  107.         yy = yy + a
  108.  
  109.     LOOP
  110.  
  111.  

This is now running AT THE EXACT SAME SPEED AS CIRCLEFILL on my machine.  And, I'm not seeing any lines in the output.   Try it out and see what you think.  :D
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: EllipseFill
« Reply #10 on: November 03, 2018, 03:48:29 pm »
Excellent! CircleFill: 1.8671875, EllipseFill: 1.59375

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: EllipseFill
« Reply #11 on: November 03, 2018, 03:52:05 pm »
Excellent! CircleFill: 1.8671875, EllipseFill: 1.59375

In QB64x64, I get EllipseFill running faster than CircleFill, as well.
In QB64x32, I get them running at almost the exact same speed.

I think I've found a nice little replacement for CircleFill with this routine.  :D
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: EllipseFill
« Reply #12 on: November 03, 2018, 04:22:18 pm »
Well if that don't beat all!

We couldn't find a faster way to do circles faster until started trying ellipse! I am getting faster circle fill with ellipse fill.

Nice one, Steve!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: EllipseFill
« Reply #13 on: November 03, 2018, 05:22:42 pm »
Well if that don't beat all!

We couldn't find a faster way to do circles faster until started trying ellipse! I am getting faster circle fill with ellipse fill.

Nice one, Steve!

I think it's good enough now, it's earned itself a spot over in my forum as well: http://qb64.freeforums.net/thread/9/circlefill-ellipsefill

https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: EllipseFill
« Reply #14 on: November 03, 2018, 07:22:59 pm »
And, after playing around with EllipseFill, I also now have a second way to do CircleFill:

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(1000, 800, 32)
  2.  
  3.  
  4. t# = TIMER
  5. FOR i = 1 TO 1000
  6.     NewCircleFill 500, 400, 400, -1
  7. t2# = TIMER
  8.  
  9. FOR i = 1 TO 1000
  10.     CircleFill 500, 400, 400, -1
  11. t3# = TIMER
  12.  
  13. FOR i = 1 TO 1000
  14.     EllipseFill 500, 400, 400, 400, -1
  15. t4# = TIMER
  16.  
  17.  
  18. PRINT "Time for NewCircleFill:"; t2# - t#
  19. PRINT "Time for CircleFill:"; t3# - t2#
  20. PRINT "Time for EllipseFill:"; t4# - t3#
  21.  
  22.  
  23. EllipseFill 500, 400, 400, 200, &HAFFF0000
  24. CircleFill 500, 400, 180, &HFF000000
  25. EllipseFill 500, 400, 20, 160, &HAFFF0000
  26.  
  27.  
  28. EllipseFill 500, 400, 500, 400, &HAFFF0000
  29.  
  30. SUB CircleFill (CX AS LONG, CY AS LONG, R AS LONG, C AS LONG)
  31.     DIM Radius AS LONG, RadiusError AS LONG
  32.     DIM X AS LONG, Y AS LONG
  33.  
  34.     Radius = ABS(R)
  35.     RadiusError = -Radius
  36.     X = Radius
  37.     Y = 0
  38.  
  39.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  40.  
  41.     ' Draw the middle span here so we don't draw it twice in the main loop,
  42.     ' which would be a problem with blending turned on.
  43.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  44.  
  45.     WHILE X > Y
  46.         RadiusError = RadiusError + Y * 2 + 1
  47.         IF RadiusError >= 0 THEN
  48.             IF X <> Y + 1 THEN
  49.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  50.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  51.             END IF
  52.             X = X - 1
  53.             RadiusError = RadiusError - X * 2
  54.         END IF
  55.         Y = Y + 1
  56.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  57.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  58.     WEND
  59.  
  60. SUB NewCircleFill (cx AS INTEGER, cy AS INTEGER, r AS INTEGER, c AS LONG)
  61.     DIM x AS LONG
  62.     DIM y AS LONG
  63.     DIM e AS LONG
  64.  
  65.     x = r
  66.     e = -x
  67.  
  68.     DO WHILE x >= y
  69.         LINE (cx - x, cy - y)-(cx + x, cy - y), c, BF
  70.         IF y <> 0 THEN LINE (cx - x, cy + y)-(cx + x, cy + y), c, BF
  71.  
  72.         y = y + 1
  73.         e = e + y + y
  74.         IF e > 0 THEN
  75.             x = x - 1
  76.             e = e - x - x
  77.         END IF
  78.     LOOP
  79.     x = r
  80.     e = -x
  81.     y = 0
  82.  
  83.     DO WHILE x >= y
  84.         LINE (cx - y, cy - x)-(cx + y, cy - x), c, BF
  85.         LINE (cx - y, cy + x)-(cx + y, cy + x), c, BF
  86.         DO
  87.             y = y + 1
  88.             e = e + y + y
  89.         LOOP UNTIL e > 0
  90.         x = x - 1
  91.         e = e - x - x
  92.     LOOP
  93.  
  94.  
  95.  
  96. SUB EllipseFill (cx AS INTEGER, cy AS INTEGER, rx AS INTEGER, ry AS INTEGER, c AS LONG)
  97.     DIM a AS LONG, b AS LONG
  98.     DIM x AS LONG, y AS LONG
  99.     DIM xx AS LONG, yy AS LONG
  100.     DIM sx AS LONG, sy AS LONG
  101.     DIM e AS LONG
  102.  
  103.     a = 2 * rx * rx
  104.     b = 2 * ry * ry
  105.     x = rx
  106.     xx = ry * ry * (1 - rx - rx)
  107.     yy = rx * rx
  108.     sx = b * rx
  109.  
  110.     DO WHILE sx >= sy
  111.         LINE (cx - x, cy - y)-(cx + x, cy - y), c, BF
  112.         IF y <> 0 THEN LINE (cx - x, cy + y)-(cx + x, cy + y), c, BF
  113.  
  114.         y = y + 1
  115.         sy = sy + a
  116.         e = e + yy
  117.         yy = yy + a
  118.  
  119.         IF (e + e + xx) > 0 THEN
  120.             x = x - 1
  121.             sx = sx - b
  122.             e = e + xx
  123.             xx = xx + b
  124.         END IF
  125.     LOOP
  126.  
  127.     x = 0
  128.     y = ry
  129.     xx = rx * ry
  130.     yy = rx * rx * (1 - ry - ry)
  131.     e = 0
  132.     sx = 1
  133.     sy = a * ry
  134.  
  135.     DO WHILE sx <= sy
  136.         LINE (cx - x, cy - y)-(cx + x, cy - y), c, BF
  137.         LINE (cx - x, cy + y)-(cx + x, cy + y), c, BF
  138.  
  139.         DO
  140.             x = x + 1
  141.             sx = sx + b
  142.             e = e + xx
  143.             xx = xx + b
  144.         LOOP UNTIL (e + e + yy) > 0
  145.  
  146.         y = y - 1
  147.         sy = sy - a
  148.         e = e + yy
  149.         yy = yy + a
  150.  
  151.     LOOP
  152.  

NewCircleFill is as fast as the old version, or faster, on my machine.  I'm curious how it'll perform for other folks, on different systems, so kindly share results, if you don't mind.  :)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!