Qbasicnews.com

Full Version: Code to draw a circle
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
X+X is faster than x*2

* is faster than / or \.

Powers of 2 can be Shifted left or right. Faster by a mile.

for big multipliers, I generaly use muls or Imuls.
x/sqrt(100*d-y)
for half a circle D being dimensions d=10 for 100 pixels tall
Quote:Plasma's would be fast because of the less calc. His code only calculates 1/8th of the circle and plots in each 8th-drant(1/2 of a quadrant if there is such a term).

My method also uses the 1/8 circle technique...although mine was a reinvented wheel...anyway...in my second post on this thread, I made a speed comparison for CIRCLE vs Plasma's, mine, and Zack's methods...CIRCLE is fastest, mine (with the slow root call) and Plasma's (with the more complex logic syntax) were virtual equals, coming in second, and Zack's method was the laggard. Do other's get different results on their platforms?

Just curious
If this is a speed contest, then I get to optimize mine. Tongue

Code:
defint a-z
sub circle2 (xc, yc, radius, colr)

  x = radius
  sum = 1 - radius
  do
    pset (xc+x, yc+y), colr
    pset (xc+y, yc+x), colr
    pset (xc-y, yc+x), colr
    pset (xc-x, yc+y), colr
    pset (xc-x, yc-y), colr
    pset (xc-y, yc-x), colr
    pset (xc+y, yc-x), colr
    pset (xc+x, yc-y), colr
    if y >= x then
      exit do
    elseif sum > 0 then
      sum = sum - x - x + 2
      x = x - 1
    end if
    sum = sum + y + y + 3
    y = y + 1
  loop

end sub

The real limiting factor here, though, is the video memory access. Take the psets out of all the circle subs in your benchmark and try it again. (You won't be able to compare QB's circle, but it's going to be the fastest anyway...)
Quote:If this is a speed contest, then I get to optimize mine. Tongue

...
The real limiting factor here, though, is the video memory access. Take the psets out of all the circle subs in your benchmark and try it again. (You won't be able to compare QB's circle, but it's going to be the fastest anyway...)

Hey Plasma...I just edited your new code into the speed test (my second post of this thread). Still...my root-calling code is as fast (a tad faster on my machine, bit I'm willing to call it equal ;-)) as yours.

BTW...What do you mean eliminate the pset? This seems fundamental to the test.

Cheers,

M
We're not testing the speed of PSET, we're testing the speed of the algorithm. All the circle routines will set the same number of pixels, so removing the PSETs just removes the performance ceiling caused by the video memory access. Try it.
Quote:We're not testing the speed of PSET, we're testing the speed of the algorithm. All the circle routines will set the same number of pixels, so removing the PSETs just removes the performance ceiling caused by the video memory access. Try it.

help me out here...you suggest that, eg, your code look like:

Code:
defint a-z
sub circle2 (xc, yc, radius, colr)

  x = radius
  sum = 1 - radius
  do
    z1= (xc+x, yc+y), colr
    z2= (xc+y, yc+x), colr
    z3= (xc-y, yc+x), colr
    z4= (xc-x, yc+y), colr
    z5= (xc-x, yc-y), colr
    z6= (xc-y, yc-x), colr
    z7= (xc+y, yc-x), colr
    z8= (xc+x, yc-y), colr
    if y >= x then
      exit do
    elseif sum > 0 then
      sum = sum - x - x + 2
      x = x - 1
    end if
    sum = sum + y + y + 3
    y = y + 1
  loop

end sub

????
Just remove all the PSETs. Remark the line out, delete it, whatever.

Code:
DEFINT A-Z
SUB Mcirc (x, y, r, c)
a = .707 * r
WHILE a
  b = SQR((r * r) - (a * a))
  'PSET (x + a, y + b), c
  'PSET (x - a, y + b), c
  'PSET (x + a, y - b), c
  'PSET (x - a, y - b), c
  'PSET (x + b, y - a), c
  'PSET (x + b, y + a), c
  'PSET (x - b, y + a), c
  'PSET (x - b, y - a), c
  a = a - 1
WEND
END SUB


SUB Pcirc (xc, yc, radius, colr)

  x = radius
  sum = 1 - radius
  DO
    'PSET (xc + x, yc + y), colr
    'PSET (xc + y, yc + x), colr
    'PSET (xc - y, yc + x), colr
    'PSET (xc - x, yc + y), colr
    'PSET (xc - x, yc - y), colr
    'PSET (xc - y, yc - x), colr
    'PSET (xc + y, yc - x), colr
    'PSET (xc + x, yc - y), colr
    IF y >= x THEN
      EXIT DO
    ELSEIF sum > 0 THEN
      sum = sum - x - x + 2
      x = x - 1
    END IF
    sum = sum + y + y + 3
    y = y + 1
  LOOP

END SUB

SUB Zcirc (x%, y%, radius%, c%)
   DO WHILE Degrees% < 361
      Radians! = (3.14159 / 180) * Degrees%
      PlotX! = radius% * SIN(Radians!)
      PlotY! = radius% * COS(Radians!)
      'PSET (x% + PlotX!, y% - PlotY!), c%
      Degrees% = Degrees% + 1
   LOOP

END SUB

If you want, you can substitute variable assignments for the PSETs. However, since all the routines have two additions or subtractions per pixel on the coordinates, the speeds all drop a relative amount.

Code:
DEFINT A-Z
SUB Mcirc (x, y, r, c)
a = .707 * r
WHILE a
  b = SQR((r * r) - (a * a))
  'PSET (x + a, y + b), c
  x1 = x + a: y1 = y + b
  'PSET (x - a, y + b), c
  x1 = x - a: y1 = y + b
  'PSET (x + a, y - b), c
  x1 = x + a: y1 = y - b
  'PSET (x - a, y - b), c
  x1 = x - a: y1 = y - b
  'PSET (x + b, y - a), c
  x1 = x + a: y1 = y - a
  'PSET (x + b, y + a), c
  x1 = x + a: y1 = y + a
  'PSET (x - b, y + a), c
  x1 = x - a: y1 = y + a
  'PSET (x - b, y - a), c
  x1 = x - a: y1 = y - a
  a = a - 1
WEND
END SUB


SUB Pcirc (xc, yc, radius, colr)

  x = radius
  sum = 1 - radius
  DO
    'PSET (xc + x, yc + y), colr
    x1 = xc + x: y1 = yc + y
    'PSET (xc + y, yc + x), colr
    x1 = xc + y: y1 = yc + x
    'PSET (xc - y, yc + x), colr
    x1 = xc - y: y1 = yc + x
    'PSET (xc - x, yc + y), colr
    x1 = xc - x: y1 = yc + y
    'PSET (xc - x, yc - y), colr
    x1 = xc - x: y1 = yc - y
    'PSET (xc - y, yc - x), colr
    x1 = xc - y: y1 = yc - x
    'PSET (xc + y, yc - x), colr
    x1 = xc + y: y1 = yc - x
    'PSET (xc + x, yc - y), colr
    x1 = xc + x: y1 = yc - y
    IF y >= x THEN
      EXIT DO
    ELSEIF sum > 0 THEN
      sum = sum - x - x + 2
      x = x - 1
    END IF
    sum = sum + y + y + 3
    y = y + 1
  LOOP

END SUB

SUB Zcirc (x%, y%, radius%, c%)
   DO WHILE Degrees% < 361
      Radians! = (3.14159 / 180) * Degrees%
      PlotX! = radius% * SIN(Radians!)
      PlotY! = radius% * COS(Radians!)
      'PSET (x% + PlotX!, y% - PlotY!), c%
      x1% = x% + PlotX!: y1% = y% - PlotY!
      Degrees% = Degrees% + 1
   LOOP

END SUB
Quote:Just remove all the PSETs. Remark the line out, delete it, whatever.

OK...I see. Your method is 2x faster, before video overhead. With video overhead, they are same, for all practical purposes.

Whadda know...Mango considers a problem and develops what he feels is a reasonable solution...and another cleverer solution already exists that's twice as good...man...that's the story of programming life...

Good thing I don't do this for a living :-)

Cheers, and thanks for teaching me something.
Pages: 1 2