This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Exerro's profile picture

generating a circle

Started by Exerro, 04 January 2013 - 06:29 AM
Exerro #1
Posted 04 January 2013 - 07:29 AM
does anyone know how to generate a circle…i have been thinking of this for hours and for some reason cant think of how to :l i would like to make a circle function for my graphics library
Goof #2
Posted 04 January 2013 - 08:14 AM
it is not something you can do in one cell / position…
you have to write a large display, which contains the outline of the circle. If im not right, then please dont blame, me… then its just me, have to improve my mind, a bit…
like this:
ScreenShot:
KaBooMa #3
Posted 04 January 2013 - 08:39 AM
Doing a tiny bit of math, I think this should work.

Spoiler


function distance(x1,y1,x2,y2)
return math.sqrt((x2-x1)^2+(y2-y1)^2)
end

function Circle(x,y,r)
for tx=x-r,x+r do
for ty=y-r,y+r do
if (distance(tx,ty,x,y) >= r and distance(tx,ty,x,y) <= r+0.5) then
term.setCursorPos(tx,ty)
term.write("X")
end
end
end
end

Should work out…I had it running in my own draw api and it should work.
Viproz #4
Posted 04 January 2013 - 08:40 AM
if you want an algorithm for circle just look on google : https://www.google.fr/webhp?q=circle+algorithm&oq=circle+algorithm
KaBooMa #5
Posted 04 January 2013 - 08:48 AM
Here you go actually. I did some editing to show you some more stuff :)/> Hope this helps you.

Spoiler


function distance(x1,y1,x2,y2)
  return math.sqrt((x2-x1)^2+(y2-y1)^2)
end

function Circle(x,y,r)
  for tx=x-r,x+r do
    for ty=y-r,y+r do
 if (tx == x and ty == y) then -- Midpoint drawing
        term.setCursorPos(tx,ty)
        term.write("O")
      elseif (distance(tx,ty,x,y) >= r and distance(tx,ty,x,y) <= r+0.5) then -- Outside drawing
        term.setCursorPos(tx,ty)
        term.write("X")
 elseif (distance(tx,ty,x,y) <= r+0.5) then -- Inside drawing
        term.setCursorPos(tx,ty)
        term.write("-")
 end
    end
  end
end

term.clear()

Circle(15,8,5)

term.setCursorPos(1,1)
Exerro #6
Posted 04 January 2013 - 08:55 AM
kabooma i modified your code a bit and it doesnt work…

function sky.graphics.circle(x,y,rad,fill,colour)
for tx=x-rad,x+rad do
  for ty=y-rad,y+rad do
   if (math.sqrt((tx-ty)^2+(x-y)^2) >= rad and math.sqrt((tx-ty)^2+(x-y)^2) <= rad+0.5) then
	sky.graphics.pixel(tx,ty,colour,2," ")
   end
  end
end
end
(might be because i mixed the variables up) but thanks anyway i got something working

edit:

function sky.graphics.circle(x,y,rad,fill,colour)
for tx=x-rad,x+rad do
  for ty=y-rad,y+rad do
   if (math.sqrt((tx-x)^2+(ty-y)^2) >= rad and math.sqrt((tx-x)^2+(ty-y)^2) <= rad+0.5) then
	sky.graphics.pixel(tx,ty,colour,2," ")
   end
  end
end
end
i put the variables in the wrong order but it still doesnt quite work (it misses some corners)
KaBooMa #7
Posted 04 January 2013 - 08:59 AM
Ya I actually took a look into the circles and stuff and played with the range and if you get to making big big circles, it actually doesn't make it just right. That is very simple to fix…Just a set of math I just happened to miss…Opps ^.^ Anyways, this below you can run in a program, and play with, and see how it works to recode to your likings. Change the radius and so on, and it should be easy for you to understand.

Spoiler


function distance(x1,y1,x2,y2)
  return math.sqrt((x2-x1)^2+(y2-y1)^2)
end

function Circle(x,y,r)
  for tx=x-r,x+r do
	for ty=y-r,y+r do
if (tx == x and ty == y) then -- Midpoint drawing
		term.setCursorPos(tx,ty)
		term.write("O")
	  elseif (distance(tx,ty,x,y) >= r and distance(tx,ty,x,y) <= r+(r/distance(tx,ty,x,y))) then -- Outside drawing
		term.setCursorPos(tx,ty)
		term.write("X")
elseif (distance(tx,ty,x,y) <= r+(r/distance(tx,ty,x,y))) then -- Inside drawing
		term.setCursorPos(tx,ty)
		term.write("-")
end
	end
  end
end

term.clear()

Circle(15,8,2)

term.setCursorPos(1,1)

Some circles can seem…chunky. Really you just need to play with it to fix that if it annoys you. I think I am done with circles for the time being. :)/>
Exerro #8
Posted 04 January 2013 - 09:01 AM
awesome thanks :D/> ill try this one now

edit: works great thx…any possibility of modifying it to make a circle on the screen (the circles look more like ovals)

current code :
Spoiler

function sky.graphics.circle(x,y,r,colour,fill)
for tx=x-r,x+r do
  for ty=y-r,y+r do
   if (math.sqrt((x-tx)^2+(y-ty)^2) >= r and math.sqrt((x-tx)^2+(y-ty)^2) <= r+(r/math.sqrt((x-tx)^2+(y-ty)^2))) then
    sky.graphics.pixel(tx,ty,colour,2," ")
   elseif (math.sqrt((x-tx)^2+(y-ty)^2) <= r+(r/math.sqrt((x-tx)^2+(y-ty)^2))) and fill then
    sky.graphics.pixel(tx,ty,colour,2," ")
   end
  end
end
end
KaBooMa #9
Posted 04 January 2013 - 09:08 AM
Ya your edit would I think be similar to this:



function sky.graphics.circle(x,y,rad,fill,color)
  for tx=x-r,x+r do
    for ty=y-r,y+r do
      if (math.sqrt((tx-x)^2+(ty-y)^2) >= r and math.sqrt((tx-x)^2+(ty-y)^2) <= r+(r/math.sqrt((tx-x)^2+(ty-y)^2))) then -- Outside drawing
        sky.graphics.pixel(tx,ty,color,2," ")
 elseif (math.sqrt((tx-x)^2+(ty-y)^2) <= r+(r/math.sqrt((tx-x)^2+(ty-y)^2))) then -- Inside drawing
        sky.graphics.pixel(tx,ty,color,2," ")
 end
    end
  end
end

About the ovals. They simply look like ovals just because oh how a terminal character isn't to a 1:1 ratio. That is not fixable due to just how it is…Everything looks "skinnier" than it really is. That is about circle as you get a circle on a terminal :)/> To my best of knowledge that is.