Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
Tags

TIC-80

Fantasy computer for making, playing and sharing tiny games. · By Nesbox

Draw circle function

A topic by Raidez created Jan 27, 2017 Views: 994 Replies: 2
Viewing posts 1 to 3
(+1)

Sorry for my bad language, I'm french !



I don't see function for drawing circle, so I made it:

function _360(x,y,r,color,fill)
 if not fill then
  for a=1,360,1 do --draw outline only
   dx=math.cos(a)*r+x
   dy=math.sin(a)*r+y
   pix(dx,dy,color)
  end
 else
  for r=r,1,-1 do --draw circle for each radius (for fill circle)
   for a=1,360,1 do
    dx=math.cos(a)*r+x
    dy=math.sin(a)*r+y
    pix(dx,dy,color)
   end
  end
 end
end


function _bresenham(x,y,r,color)
 --see <a href="<a href=" https:="" fr.wikipedia.org="" wiki="" algorithme_de_trac%c3%a9_d%27arc_de_cercle_de_bresenham"=""></a><a href="<a href=" https:="" fr.wikipedia.org="" wiki="" algorithme_de_trac%c.."="">https://fr.wikipedia.org/wiki/Algorithme_de_trac%C...</a>">https://fr.wikipedia.org/wiki/Algorithme_de_trac%C....">https://fr.wikipedia.org/wiki/Algorithme_de_trac%C...
 px=0
 py=r
 m=5-4*r
 
 while(px<=py) do
  pix((px+x),(py+y),color) 
  pix((py+x),(px+y),color)
  pix((-px+x),(py+y),color)
  pix((-py+x),(px+y),color)
  pix((px+x),(-py+y),color)
  pix((py+x),(-px+y),color)
  pix((-px+x),(-py+y),color)
  pix((-py+x),(-px+y),color)
 
  if m>0 then
   py=py-1
   m=m-8*py
  end
 
  px=px+1
  m=m+8*px+4
 end
end


function _andres(x,y,r,color,fill)
 --see <a href="<a href=" https:="" fr.wikipedia.org="" wiki="" algorithme_de_trac%c3%a9_de_cercle_d%27andres"="">https://fr.wikipedia.org/wiki/Algorithme_de_trac%C...</a>">https://fr.wikipedia.org/wiki/Algorithme_de_trac%C...
 px=x
 py=y
 
 d=r-1
 a=r
 --a=r-1
 b=0
 
 while(a>=b) do
  if not fill then
   pix((px+b),(py+a),color)
   pix((px+a),(py+b),color)
   pix((px-b),(py+a),color)
   pix((px-a),(py+b),color)
   pix((px+b),(py-a),color)
   pix((px+a),(py-b),color)
   pix((px-b),(py-a),color)
   pix((px-a),(py-b),color)
  else
   line((px+b),(py-a),(px+b),(py+a),color)
   line((px+a),(py-b),(px+a),(py+b),color)
   line((px-b),(py-a),(px-b),(py+a),color)
   line((px-a),(py-b),(px-a),(py+b),color)
  end
 
  if d>=2*b then
   d=d-2*b-1
   b=b+1
  elseif d<2*(r-a) then
   d=d+2*a-1
   a=a-1
  else
   d=d+2*(a-b-1)
   a=a-1
   b=b+1
  end
 end
end


function _axis(cx,cy,r,color,fill)
 if not fill then
  for y=-r,r,1 do --outline
   for x=-r,r,1 do
    if (x*x+y*y)<=(r*r) then
     pix(cx+x,cy+y,color)
    end
   end
  end
 
  r=r-1
  for y=-r,r,1 do --unfill
   for x=-r,r,1 do
    if (x*x+y*y)<=(r*r) then
     pix(cx+x,cy+y,-1)
    end
   end
  end
 else
  for y=-r,r,1 do
   for x=-r,r,1 do
    if (x*x+y*y)<=(r*r) then
     pix(cx+x,cy+y,color)
    end
   end
  end
 end
end


function circ(x,y,r,color,algo)
 if algo=="360" then
  --don't use it, it's false/incomplete
  --_360(x,y,r,color,true)
 elseif algo=="bresenham" then
  _bresenham(x,y,r,color)
  _andres(x,y,(r),color,true)
 elseif algo=="andres" then
  _andres(x,y,r,color,true)
 elseif algo=="axis" then
  _axis(x,y,r,color,true)
 end
end


function circb(x,y,r,color,algo)
 if algo=="360" then
  --don't use it, it's false/incomplete
  --_360(x,y,r,color,false)
 elseif algo=="bresenham" then
  _bresenham(x,y,r,color)
 elseif algo=="andres" then
  _andres(x,y,r,color,false)
 elseif algo=="axis" then
  _axis(x,y,r,color,false)
 end
end 


There are a lot of algorithm to drawing circle, but after comparison, I suggest to use Andres's method:

function _andres(x,y,r,color,fill)
 --see https://fr.wikipedia.org/wiki/Algorithme_de_trac%C....
 px=x
 py=y
 d=r-1
 a=r
 --a=r-1
 b=0
 while(a>=b) do
  if not fill then
   pix((px+b),(py+a),color)
   pix((px+a),(py+b),color)
   pix((px-b),(py+a),color)
   pix((px-a),(py+b),color)
   pix((px+b),(py-a),color)
   pix((px+a),(py-b),color)
   pix((px-b),(py-a),color)
   pix((px-a),(py-b),color)
  else
   line((px+b),(py-a),(px+b),(py+a),color)
   line((px+a),(py-b),(px+a),(py+b),color)
   line((px-b),(py-a),(px-b),(py+a),color)
   line((px-a),(py-b),(px-a),(py+b),color)
  end
  if d>=2*b then
   d=d-2*b-1
   b=b+1
  elseif d<2*(r-a) then
   d=d+2*a-1
   a=a-1
  else
   d=d+2*(a-b-1)
   a=a-1
   b=b+1
  end
 end
end

function circ(x,y,r,color)
 _andres(x,y,r,color,true)
end

function circb(x,y,r,color)
 _andres(x,y,r,color,false)
end
Developer

Thanks for the code snippets, very informative.

I'm thinking about dedicated place for such snippets, maybe on Github Wiki https://github.com/nesbox/tic.computer/wiki

Developer

Added your example to the Wiki

https://github.com/nesbox/tic.computer/wiki/Code-e...

Thanks