Jump to content




Circles 2 - A Simple API that draws circles

api computer lua

18 replies to this topic

#1 EtzGamer

  • Members
  • 11 posts

Posted 03 July 2016 - 10:47 PM

Circles 2


A simple API that draws circles


After some research, I have created an API that efficiently draws circles using basic algorithms. For now, it only draws circles. However, I plan to add other features soon. :)

You may also wish to install the new v2 demo program! [ Installer: pastebin run 8NwC8KxF ]

How to install:
Spoiler

Outdated Demo Program Screenshots:
Spoiler

How to use:
Spoiler

Upcoming Features:
Spoiler

Obsolete Commands:
Spoiler

Known Issues:
Spoiler

Changelog:
Spoiler

Beta Changelog:
Spoiler

Edited by EtzGamer, 08 July 2016 - 02:31 PM.


#2 eniallator

  • Members
  • 56 posts

Posted 04 July 2016 - 03:54 AM

do you know about the for loop in Lua? you have used a lot of while loops when they can be for loops. This would be more efficient and less code :P

#3 EtzGamer

  • Members
  • 11 posts

Posted 04 July 2016 - 03:58 AM

View Posteniallator, on 04 July 2016 - 03:54 AM, said:

do you know about the for loop in Lua? you have used a lot of while loops when they can be for loops. This would be more efficient and less code :P

Never really got around using for loops. :P

But I'll add it in the next version

I do appreciate your feedback :)

#4 EtzGamer

  • Members
  • 11 posts

Posted 04 July 2016 - 02:14 PM

I'm currently working on a much more optimized version of Circles: Circles 2.

It is a complete rewrite of the code and would include drawFilledCircle() and fix number rounding errors (as seen on the 2nd demo program screenshot).

Circles 2 is expected to be up some time tomorrow.

UPDATE:
Circles 2 is now LIVE!

What's new in Circles 2:
-New version scheme :P
-Optimized circles.drawCircle()
-Fixed and optimized circles.drawFilledCircle()

Edited by EtzGamer, 04 July 2016 - 10:37 PM.


#5 LDDestroier

  • Members
  • 1,090 posts
  • LocationACDC Town

Posted 04 July 2016 - 07:46 PM

Can you add a circle function that accounts for the rectangular shape of ComputerCraft pixels?

#6 ReBraLaCC

  • Members
  • 100 posts
  • LocationSublime Text 2

Posted 04 July 2016 - 08:00 PM

maybe idea to make filled circles
function filledCircle(rad,centerx,centery,color)
 for i = 1,rad do
  draw(rad-i+1,centerx,centery,color)
 end
end

maybe it works but its a prototype ;)
nice api!

#7 EtzGamer

  • Members
  • 11 posts

Posted 04 July 2016 - 10:42 PM

View PostReBraLaCC, on 04 July 2016 - 08:00 PM, said:

maybe idea to make filled circles
function filledCircle(rad,centerx,centery,color)
for i = 1,rad do
  draw(rad-i+1,centerx,centery,color)
end
end

maybe it works but its a prototype ;)
nice api!

Thanks :)

If I am not mistaken, the code you got there draws diagonal lines; from the center point of the circle to the edges.

I tried that, but it did not work due to math.floor() rounding issues, thus leaving the circle with some holes :P

I have found a solution to this and is now live, I would like to hear feedback regarding this rewritten API, Circles 2.

View PostEldidiStroyrr, on 04 July 2016 - 07:46 PM, said:

Can you add a circle function that accounts for the rectangular shape of ComputerCraft pixels?

Can you elaborate? :)

Edited by EtzGamer, 04 July 2016 - 10:41 PM.


#8 Lemmmy

  • Members
  • 218 posts

Posted 04 July 2016 - 10:52 PM

For filled circles, you can use the Pythagoras Theorem. However, this algorithm draws a few extra pixels, but it shows one of the ways you can draw them.

for y = -radius, radius do
    for x = -radius, radius do
        if x * x + y * y <= radius * radius then
            --# draw pixel at x + originX, y + originY
        end
    end
end

Another method, and this is the method I would recommend you use for both non-filled and filled, is Bresenham's Midpoint Circle Algorithm. This is the most accurate way to draw a circle, and it is fairly fast. I'd suggest reading up on how it works. Wikipedia shows you an implementation for outlined circles in C and JavaScript, which should be easy to port to Lua.

In order to draw filled circles, you can change the algorithm slightly, so instead of:
plot(x0 + x, y0 + y)
plot(x0 - x, y0 + y)
and similar lines, you instead do:
paintutils.drawLine(x0 - x, y0 + y, x0 + x, y0 + y)

Generally, I would also suggest allowing the user to pass in their own term objects to draw the circles with, instead of having to redirect to the term object just to use paintutils. This means you need to implement line drawing. Luckily, Bresenham also came up with a line drawing algorithm. Allowing users to pass in their own term object would let them use your API in a buffer such as a framebuffer, or BLittle's drawing buffer.

Edited by Lemmmy, 04 July 2016 - 10:52 PM.


#9 LDDestroier

  • Members
  • 1,090 posts
  • LocationACDC Town

Posted 04 July 2016 - 11:24 PM

View PostEtzGamer, on 04 July 2016 - 10:42 PM, said:

View PostEldidiStroyrr, on 04 July 2016 - 07:46 PM, said:

Can you add a circle function that accounts for the rectangular shape of ComputerCraft pixels?

Can you elaborate? :)

The characters for ComputerCraft are not square, they are 5x7. So, like, this new circle render function would make the circle 7/5 of the radius wider.

#10 Lemmmy

  • Members
  • 218 posts

Posted 05 July 2016 - 12:15 AM

View PostEldidiStroyrr, on 04 July 2016 - 11:24 PM, said:

The characters for ComputerCraft are not square, they are 5x7. So, like, this new circle render function would make the circle 7/5 of the radius wider.

what are you on, characters are 1:1.5 w:h ratio, so they are 6x9 not 5x7

standard text characters are 5:7 though but regular drawing chars don't include that whitespace of course

Edited by Lemmmy, 05 July 2016 - 12:16 AM.


#11 Bomb Bloke

    Hobbyist Coder

  • Moderators
  • 7,099 posts
  • LocationTasmania (AU)

Posted 05 July 2016 - 01:36 AM

Also somewhat worth noting that if you're using the teletext characters to draw things, then the "pixels" are effectively square - so in cases where eg BLittle's buffer is being used, you wouldn't want to apply any scaling.

#12 EtzGamer

  • Members
  • 11 posts

Posted 05 July 2016 - 09:16 AM

View PostLemmmy, on 04 July 2016 - 10:52 PM, said:

For filled circles, you can use the Pythagoras Theorem. However, this algorithm draws a few extra pixels, but it shows one of the ways you can draw them.

for y = -radius, radius do
	for x = -radius, radius do
		if x * x + y * y <= radius * radius then
			--# draw pixel at x + originX, y + originY
		end
	end
end

Another method, and this is the method I would recommend you use for both non-filled and filled, is Bresenham's Midpoint Circle Algorithm. This is the most accurate way to draw a circle, and it is fairly fast. I'd suggest reading up on how it works. Wikipedia shows you an implementation for outlined circles in C and JavaScript, which should be easy to port to Lua.

In order to draw filled circles, you can change the algorithm slightly, so instead of:
plot(x0 + x, y0 + y)
plot(x0 - x, y0 + y)
and similar lines, you instead do:
paintutils.drawLine(x0 - x, y0 + y, x0 + x, y0 + y)

Generally, I would also suggest allowing the user to pass in their own term objects to draw the circles with, instead of having to redirect to the term object just to use paintutils. This means you need to implement line drawing. Luckily, Bresenham also came up with a line drawing algorithm. Allowing users to pass in their own term object would let them use your API in a buffer such as a framebuffer, or BLittle's drawing buffer.

Thanks for the suggestion!

I'll definitely consider including these Bresenham's Midpoint Circle Algorithm into the API in the near future. :)

However, I may not include Pythagoras Theorem as it is 'not efficient' from the drawing of extra pixels.
EDIT : I have implemented Pythagorean Theorem into Circles 2 Beta v2.0.1b as it was found to be faster. :D

But I'll definitely compare these algorithms and time them, seeing which one is faster.

Also, could you emphasize on 'allowing the user to pass in their own term objects to draw the circles with'?

Edited by EtzGamer, 06 July 2016 - 02:22 AM.


#13 Bomb Bloke

    Hobbyist Coder

  • Moderators
  • 7,099 posts
  • LocationTasmania (AU)

Posted 05 July 2016 - 11:39 AM

View PostEtzGamer, on 05 July 2016 - 09:16 AM, said:

Also, could you emphasize on 'allowing the user to pass in their own term objects to draw the circles with'?

Allow this sort of thing:

local mon = peripheral.wrap("right")

local oldTerm = term.redirect(mon)

circles.drawCircle(5, 10, 10, colours.yellow)

term.redirect(oldTerm)

... to instead be performed via this sort of thing:

local mon = peripheral.wrap("right")

circles.drawCircle(5, 10, 10, colours.yellow, mon)


#14 Lemmmy

  • Members
  • 218 posts

Posted 05 July 2016 - 12:18 PM

View PostBomb Bloke, on 05 July 2016 - 11:39 AM, said:

View PostEtzGamer, on 05 July 2016 - 09:16 AM, said:

Also, could you emphasize on 'allowing the user to pass in their own term objects to draw the circles with'?

Allow this sort of thing:

local mon = peripheral.wrap("right")

local oldTerm = term.redirect(mon)

circles.drawCircle(5, 10, 10, colours.yellow)

term.redirect(oldTerm)

... to instead be performed via this sort of thing:

local mon = peripheral.wrap("right")

circles.drawCircle(5, 10, 10, colours.yellow, mon)

More common usages include redirecting to a framebuffer from Lyqyd's framebuffer API, a surface from CrazedProgrammer's Surface API, windows from ComputerCraft's window API, windows from Bomb Bloke's BLittle API and more.

#15 EtzGamer

  • Members
  • 11 posts

Posted 06 July 2016 - 02:30 AM

Circles Beta v2.0.1b is out now!


v2.0.1b Changelog:
-Used Pythagorean Theorem to replace existing drawCircle() algorithm (it's more accurate)
-Accounted ComputerCraft's 6:9 color block ratio for a more accurate circle Removed for now.

EDIT:
There is a severe issue that was discovered in the code. In the mean time, please use the stable build instead.


EDIT 2:
A hotfix has been issued and the issue has been resolved! The version number will not change. Thanks for your patience :)/>

Edited by EtzGamer, 09 July 2016 - 04:55 AM.


#16 EtzGamer

  • Members
  • 11 posts

Posted 08 July 2016 - 10:23 AM

View PostEldidiStroyrr, on 04 July 2016 - 07:46 PM, said:

Can you add a circle function that accounts for the rectangular shape of ComputerCraft pixels?

Circles Beta v2.0.2b / v2.0.3b is out now!


v2.0.2b / v2.0.3b Changelog:
-Accounted ComputerCraft's 6:9 color block ratio for a more accurate circle :D

Edited by EtzGamer, 08 July 2016 - 02:28 PM.


#17 EtzGamer

  • Members
  • 11 posts

Posted 08 July 2016 - 02:28 PM

Circles Beta v2.0.3r is out now!


v2.0.3r Changelog:
-Accounted ComputerCraft's 6:9 color block ratio for a more accurate circle :D/>
-Used Pythagorean Theorem to replace existing drawCircle() algorithm (it's more accurate)
-Removed drawFilledCircle() function for now.

Edited by EtzGamer, 09 July 2016 - 04:57 AM.


#18 Lemmmy

  • Members
  • 218 posts

Posted 08 July 2016 - 03:27 PM

View PostEtzGamer, on 08 July 2016 - 02:28 PM, said:

-Used Pythagorean Theorem to replace existing drawCircle() algorithm (it's more efficient and accurate)

I said it wasn't, and it isn't - implement Bresenham's Midpoint Circle Algorithm instead.

#19 EtzGamer

  • Members
  • 11 posts

Posted 09 July 2016 - 07:00 AM

View PostLemmmy, on 08 July 2016 - 03:27 PM, said:

View PostEtzGamer, on 08 July 2016 - 02:28 PM, said:

-Used Pythagorean Theorem to replace existing drawCircle() algorithm (it's more efficient and accurate)

I said it wasn't, and it isn't - implement Bresenham's Midpoint Circle Algorithm instead.

I got my facts wrong about it being efficient; my bad. But the midpoint circle algorithm will be implemented alongside.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users