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
When I first began programming, I thought that code to draw a circle was gonna be the hardest thing ever. :wink:
Well - it may be slow, but it works. Just curious - what other methods of drawing circles are there? And what does the QB's intrinsic CIRCLE use?
Code:
SUB DC (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
Hey Zack...here's what I came up with when I wondered the same thing. Note my slow line is the squareroot call...I wonder if it can be done with no calls to expensive functions??? Or...using only Boolean logic...Cheers

Code:
'***********************************************
'*Mango-2001
'*This program draws circles the hard way...No Trig..and integers only
'*without using the circle command.  You can slow it down to see what it does
'*by deleting the comment markers of the "slowme" section of the code.
'***********************************************


SCREEN 12
DEFINT A-Z

DO
x = RND * 640      ' x cord
y = RND * 480      ' y cord
c = RND * 15       'color
r = RND * 100      'radius
sin45 = .70711 * r

FOR a = 0 TO sin45
  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

'++++++++++USE THE FOLLOWING LINE TO SLOW THE CODE & SEE HOW IT WORKS++++++++
'FOR slow = 1 TO 100: FOR slow2 = 1 TO 3000: NEXT slow2: NEXT slow
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
NEXT a
LOOP UNTIL INKEY$ <> ""
This compares the methods...
Code:
DECLARE SUB Mcirc (x%, y%, r%, c%)
DECLARE SUB Zcirc (x%, y%, radius%, c%)
DECLARE SUB Pcirc (xc%, yc%, radius%, colr%)
SCREEN 12
CLS
timer2 = TIMER + 1
DO: LOOP WHILE TIMER < timer2

secs = 1

'default method
RANDOMIZE 0
timeme = TIMER + secs
DO WHILE timeme > TIMER
  CIRCLE (RND * 640, RND * 480), RND * 100, RND * 16
  countDeflt = countDeflt + 1
LOOP
CLS


'Mango's method
RANDOMIZE 0
timeme = TIMER + secs
DO WHILE timeme > TIMER
  CALL Mcirc(RND * 640, RND * 480, RND * 100, RND * 16)
  countMango = countMango + 1
LOOP

CLS

'Zack's method
RANDOMIZE 0
timeme = TIMER + secs
DO WHILE timeme > TIMER
  CALL Zcirc(RND * 640, RND * 480, RND * 100, RND * 16)
  countZacko = countZacko + 1
LOOP
CLS

'Plasma's method
RANDOMIZE 0
timeme = TIMER + secs
DO WHILE timeme > TIMER
  CALL Pcirc(RND * 640, RND * 480, RND * 100, RND * 16)
  countPlasm = countPlasm + 1
LOOP



PRINT "default gets"; countDeflt / secs; "circles/sec"
PRINT "Mango gets"; countMango / secs; "circles/sec"
PRINT "Zack gets"; countZacko / secs; "circles/sec"
PRINT "Plasma gets"; countPlasm / secs; "circles/sec"

END

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
Square roots are slow. 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 - 2 * x + 2
      x = x - 1
    end if
    sum = sum + 2 * y + 3
    y = y + 1
  loop

end sub

(This is the same method that QB uses, btw)
Quote:Square roots are slow. Tongue

Plasma...I tweaked mine a bit...looks the same speed as yours!!! May be different if it's compiled, though...dunno...

EDIT!!! Holy Cow...Your's and mine are *SLOWER* compiled than translated???!!!??!?!?!???!!!

What gives??
Quote:
Plasma Wrote:Square roots are slow. Tongue
EDIT!!! Holy Cow...Your's and mine are *SLOWER* compiled than translated???!!!??!?!?!???!!!

What gives??
That happens all the time for me.

Anyway - and what formula does QB use?
Read plasma's post above more carefully ^^^
Quote:
Mango Wrote:
Plasma Wrote:Square roots are slow. Tongue
EDIT!!! Holy Cow...Your's and mine are *SLOWER* compiled than translated???!!!??!?!?!???!!!

What gives??
That happens all the time for me.

Anyway - and what formula does QB use?


It's called the "bresenham" circle method. He also made a "bresenham" line method.

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).
Thanks, DP, didn't notice that bit.

Yes, the Bresenham circle. I've heard of it - now I have to figure out how to draw lines (Bresenham or not).
Offtopic:
What would be faster, x*2 or x+x?

They use different operations right? So one of them mus be a tiny bit faster.

How does the CPU calculate * anyways? Does it convert it to + like:
Code:
7*8 = 8+8+8+8+8+8+8

If so, then using + directly would be faster, right?

And what about: x^y (power of)
Code:
2^8 = 2*2*2*2*2*2*2*2
Which is:
Code:
2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2
2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2
2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2
2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2
2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2
2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2
2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2
2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2
2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2
2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2
2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2
2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2
2 + 2 + 2 + 2 + 2 + 2 + 2 + 2
Which is:
2*128

Which is:
8*32

Which is:
16*16

Which is:
32*8

Which is:
64*4

Which is:
64+64+64+64

Which is:
256


So, how would the computer optimize it? What would be the fastest way to calculate it? 2^8 or using a number of +?

And what is fastest: * or / (assuming whole integers as factors and results)
Pages: 1 2