As for your demo, try this and see how it performs for you:
OPTION _EXPLICIT
_TITLE "Rainbow Ring" 'bplus 2019-07-07
'DoubleRing mod by Steve 2019-07-08
' QB64 X 64 v 1.3
CONST xmax = 1220, ymax = 760, PI = 3.141592653589793
SCREEN _NEWIMAGE(xmax, ymax, 32)
_SCREENMOVE 100, 0
RANDOMIZE TIMER
DIM SHARED graphicsCalls AS _INTEGER64
DIM offset, start, test
start = TIMER
FOR test = 1 TO 20
CLS
offset = offset + PI / 120
'compare two subs comment out one or the other next 2 lines
'rainbowRing xmax / 2, ymax / 2, 250, 50, offset
'ring xmax / 2, ymax / 2, 250, 50, offset
Doublering xmax / 2, ymax / 2, 250, 50, offset
_DISPLAY
NEXT
PRINT "The number of graphics calls was:"; graphicsCalls
PRINT "Time:"; TIMER - start
_DISPLAY
SUB Doublering (x, y, outerR, innerR, offset)
DIM pm2, pd3, pd6, a, aStep, x1, y1, x2, y2, c AS _UNSIGNED LONG
pm2 = PI * 2
pd3 = PI / 3
pd6 = pd3 / 2 'pd6 aligns red at 90 degrees bottom of circle and light almost white cyan at top, looks good Steve!
'aStep = 1 / (20.1 * pm2 * outerR) 'this is what I used for screen shot
FOR a = 0 TO pm2 STEP 1 / outerR ' <<<<<<<<<<<<<<<<<<<<<<<<<<<< is this the flaw to this method????
x1 = x + outerR * COS(a - pd6 + offset)
y1 = y + outerR * SIN(a - pd6 + offset)
x2 = x + innerR * COS(a - pd6 + offset)
y2 = y + innerR * SIN(a - pd6 + offset)
IF a < pd3 THEN
c = _RGB32(255 * a / pd3, 255, 0)
ELSEIF a < 2 * pd3 THEN
c = _RGB32(255, 255 - 255 * (a - pd3) / pd3, 0)
ELSEIF a < 3 * pd3 THEN
c = _RGB32(255, 0, 255 * (a - 2 * pd3) / pd3)
ELSEIF a < 4 * pd3 THEN
c = _RGB32(255 - 255 * (a - 3 * pd3) / pd3, 0, 255)
ELSEIF a < 5 * pd3 THEN
c = _RGB32(0, 255 * (a - 4 * pd3) / pd3, 255)
ELSE
c = _RGB32(0, 255, 255 - 255 * (a - 5 * pd3) / pd3)
END IF
LINE (x1, y1)-(x2, y2), c
LINE (x1 + 1, y1)-(x2 + 1, y2), c
graphicsCalls = graphicsCalls + 1
NEXT
END SUB
SUB rainbowRing (x, y, outerR, innerR, offset) 'no lines, do arc/circle style
DIM pm2, pd3, pd6, r, a, aStep, x1, y1, x2, y2, c AS _UNSIGNED LONG
pm2 = PI * 2
pd3 = PI / 3
pd6 = pd3 / 2 'pd6 aligns red at 90 degrees bottom of circle and light almost white cyan at top, looks good Steve!
FOR r = innerR TO outerR 'step 1? seems to be OK
'how many pixels 2*PI*R around the curve = how many steps needed to take around circle?
'aStep = 1 / (pm2 * outerR) 'nope not efficient
aStep = 1 / (pm2 * r) '<<<< EDIT/UPDATE: aha!! this makes all the difference !!! (first tried outerR)
FOR a = 0 TO pm2 STEP aStep '>>>>>>>>>>> yeah seems to cover well and does not seem like allot
x1 = x + r * COS(a - pd6 + offset)
y1 = y + r * SIN(a - pd6 + offset)
IF a < pd3 THEN
c = _RGB32(255 * a / pd3, 255, 0)
ELSEIF a < 2 * pd3 THEN
c = _RGB32(255, 255 - 255 * (a - pd3) / pd3, 0)
ELSEIF a < 3 * pd3 THEN
c = _RGB32(255, 0, 255 * (a - 2 * pd3) / pd3)
ELSEIF a < 4 * pd3 THEN
c = _RGB32(255 - 255 * (a - 3 * pd3) / pd3, 0, 255)
ELSEIF a < 5 * pd3 THEN
c = _RGB32(0, 255 * (a - 4 * pd3) / pd3, 255)
ELSE
c = _RGB32(0, 255, 255 - 255 * (a - 5 * pd3) / pd3)
END IF
PSET (x1, y1), c
graphicsCalls = graphicsCalls + 1
NEXT
NEXT
END SUB
SUB ring (x, y, outerR, innerR, offset)
DIM pm2, pd3, pd6, a, aStep, x1, y1, x2, y2, c AS _UNSIGNED LONG
pm2 = PI * 2
pd3 = PI / 3
pd6 = pd3 / 2 'pd6 aligns red at 90 degrees bottom of circle and light almost white cyan at top, looks good Steve!
'aStep = 1 / (20.1 * pm2 * outerR) 'this is what I used for screen shot
FOR a = 0 TO pm2 STEP .00005 ' <<<<<<<<<<<<<<<<<<<<<<<<<<<< is this the flaw to this method????
x1 = x + outerR * COS(a - pd6 + offset)
y1 = y + outerR * SIN(a - pd6 + offset)
x2 = x + innerR * COS(a - pd6 + offset)
y2 = y + innerR * SIN(a - pd6 + offset)
IF a < pd3 THEN
c = _RGB32(255 * a / pd3, 255, 0)
ELSEIF a < 2 * pd3 THEN
c = _RGB32(255, 255 - 255 * (a - pd3) / pd3, 0)
ELSEIF a < 3 * pd3 THEN
c = _RGB32(255, 0, 255 * (a - 2 * pd3) / pd3)
ELSEIF a < 4 * pd3 THEN
c = _RGB32(255 - 255 * (a - 3 * pd3) / pd3, 0, 255)
ELSEIF a < 5 * pd3 THEN
c = _RGB32(0, 255 * (a - 4 * pd3) / pd3, 255)
ELSE
c = _RGB32(0, 255, 255 - 255 * (a - 5 * pd3) / pd3)
END IF
LINE (x1, y1)-(x2, y2), c
graphicsCalls = graphicsCalls + 1
NEXT
END SUB
Ring takes 6 seconds on my PC, rainbowring takes 3.6 seconds, and DoubleRing takes all of 0.16 seconds.
Our step here is: 1 / outerR (or 1/250)
Compared vs: .00005 (or 1/20000)
Even if we count drawing double lines, that's 500 lines drawn, vs 20000 lines...
So, just a weeee bit faster. ;)
It may change the dimensions of our circle by a pixel, but overall, it seems worth it just for the boost in performance speed.