Author Topic: circle[BB2D]  (Read 4542 times)

0 Members and 1 Guest are viewing this topic.

Offline Paul

  • Pentium
  • *****
  • Posts: 1490
  • Karma: 47
    • View Profile
circle[BB2D]
« on: December 28, 2006 »
I've been trying to make a circle function that draws a circle but it leaves out some pixels. can anyone tell me why?

Graphics 800,600
SetBuffer BackBuffer()
LockBuffer BackBuffer()
circle1(300,255 Shl 16)
UnlockBuffer BackBuffer()

Flip
WaitKey()


Function circle1(radius,col)
   d=(Sqr((radius^2)*2))/2
   For x=-d To d
      For y=-d To d
         WritePixelFast(x+400,y+300,col)
      Next
   Next
   For dist=d To radius
      Steps#=180/(dist*Pi*2);Lower number = highr quality
      a#=0
      Repeat
         a#=a#+steps#
         WritePixelFast(Sin(a#)*dist+400,Cos(a#)*dist+300,col)
         ;x=Sin(a#)*dist+400
         ;y=Cos(a#)*dist+300
      Until a#=>360
   Next

End Function

Function circle2(radius,col)
   For dist=0 To radius
      Steps#=180/(dist*Pi*2);change 180 for diffren speed and quality... in my theory it should be perfect at 360 buy it isnt
      a#=0
      Repeat
         a#=a#+steps#
         WritePixelFast(Sin(a#)*dist+400,Cos(a#)*dist+300,col)
         ;x=Sin(a#)*dist+400
         ;y=Cos(a#)*dist+300
      Until a#=>360
   Next

End Function
« Last Edit: July 21, 2007 by Shockwave »
I will bite you - http://s5.bitefight.se/c.php?uid=31059
Challenge Trophies Won:

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: circle
« Reply #1 on: December 28, 2006 »
Sorry, I don't have blitz installed but I take it you're referring to strange patterns of unfilled pixels appearing towards the outside of your circles which become just radiating lines of pixels the larger you make your circles. You could make the angle step smaller the larger you make your circle to fix this but that would mean a lot of unnecessary re-filling of pixels towards the middle of the circe. Another method of filling circles is to use a bit of pythagroras in something like:

Code: [Select]

/top row to bottom row of circle
for y=-radius to radius

/use pythagoras right angle triangle to find half the width of the current row
    half_row_width=sqr(radius^2-y^2)

/add centre coords and fill row
    for x=-half_row_width to half_row_width
        fill_pixel centre_x+x,centre_y+y,color
    next

next

I'm not sure what the blitz commands are for this but it should be something like that.

Offline Paul

  • Pentium
  • *****
  • Posts: 1490
  • Karma: 47
    • View Profile
Re: circle
« Reply #2 on: December 28, 2006 »
I think thats what i'm doing but i get this effect

http://www.yourfilehost.com/media.php?cat=other&file=1534test.zip

Graphics 800,600
SetBuffer BackBuffer()
While Not KeyHit(1)
   ac=Input$("this should be 360")
   if ac=<0 then ac=360
   Cls
   
   LockBuffer BackBuffer()
   circle2(300,255,ac)
   UnlockBuffer BackBuffer()
   Flip
Wend
Function circle2(radius,col,ac=360)
   For dist=0 To radius
      Steps#=ac/(dist*Pi*2);change 180 for diffren speed and quality... in my theory it should be perfect at 360 buy it isnt
      a#=0
      Repeat
         a#=a#+steps#
         WritePixelFast(Sin(a#)*dist+400,Cos(a#)*dist+300,col)
         ;x=Sin(a#)*dist+400
         ;y=Cos(a#)*dist+300
      Until a#=>360
   Next

End Function
I will bite you - http://s5.bitefight.se/c.php?uid=31059
Challenge Trophies Won:

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17412
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: circle
« Reply #3 on: December 28, 2006 »
I think that there is also a command called oval that lets you draw them?
Shockwave ^ Codigos
Challenge Trophies Won:

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: circle
« Reply #4 on: December 28, 2006 »
Yep paul, that was the effect I was meaning and it's caused by a large circle needing many more pixels filled at the edges than are needed at the middle. The little bit of code I posted (with some modification for it to work in blitz) will fill it completely and only fill each pixel once.

EDIT: I get a memory access violation with the exe, writepixelfast in blitz doesn't do any bounds checking for any offscreen coords so you need to test for that in your code else you might find some strange things happening to windows icons or pointers as you overwrite bits of memory you're not supposed to.
« Last Edit: December 28, 2006 by Stonemonkey »

Offline Paul

  • Pentium
  • *****
  • Posts: 1490
  • Karma: 47
    • View Profile
Re: circle
« Reply #5 on: December 28, 2006 »
http://www.yourfilehost.com/media.php?cat=other&file=4405test.zip new .exe

I then im doing what you say
I start with the radius 0 and go out to the circle size.
For dist=o To radius

next
and each time i calculate the circumference and divide by 360 to get each step. but it still jumps sometimes. and probably does some double instead. 
I will bite you - http://s5.bitefight.se/c.php?uid=31059
Challenge Trophies Won:

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: circle
« Reply #6 on: December 28, 2006 »
If you compare the code you'll see that I'm doing something different, instead of filling lines radiating from the centre this fills each horizontal line starting from the top:

Code: [Select]
Function fill_circle(radius,col)

    centre_x=400
    centre_y=300

    for y=-radius to radius

        half_row_width=sqr(radius^2-y^2)

        for x=-half_row_width to half_row_width
            writepixelfast(centre_x+x,centre_y+y,color)
        next

    next

end function


you should still put in some bounds checking though, or just use writepixel instead of writepixelfast.
« Last Edit: December 28, 2006 by Stonemonkey »

Offline Paul

  • Pentium
  • *****
  • Posts: 1490
  • Karma: 47
    • View Profile
Re: circle
« Reply #7 on: December 28, 2006 »
THX this works perfectly:)
Sry that i diddnt get it first time

thx again

oval wouldnt work because im doing something different
I will bite you - http://s5.bitefight.se/c.php?uid=31059
Challenge Trophies Won:

Offline mike_g

  • Amiga 1200
  • ****
  • Posts: 435
  • Karma: 34
    • View Profile
Re: circle
« Reply #8 on: December 29, 2006 »
Just a different version that I came up with that checks the screen bounds:
Code: [Select]
Function F_CIRCLE(cx, cy, rad)
LockBuffer
inc# = Float(360/(rad*Pi*2))
steps = 90/inc#
For i = 0 To steps
x1 = (cx - rad * Cos(deg#))
y1 = (cy - rad * Sin(deg#))
x2 = (cx*2)-x1
y2 = (cy*2)-y1

If x1 < 0 Then x1 = 0
If x2 >= GraphicsWidth() Then x2 =GraphicsWidth()-1
If y1 < 0 Then y1 = 0
If y2 >= GraphicsHeight() Then y2 = GraphicsHeight()-1

For x = x1 To x2
WritePixelFast x, y1, $ffffff
Next
For x = x1 To x2
WritePixelFast x, y2, $ffffff
Next
deg# = deg# + inc#
Next
UnlockBuffer
End Function