Discuss Scratch

Alberknyis
Scratcher
1000+ posts

Draw a Ring, but Quickly

Using some trickery, people were able to draw some very fast squares and very fast triangles. As I was playing around with Scratch, a shape drawing challenge lightbulbed in my head… What if the challenge was to draw an object that was round? And so, the challenge that would be easy if there were a pen erasing function:

Given the length of the ring from the center to the edge (or some input which that value can be determined), and the thickness of the ring (or again, some value which that could be determined from), and assuming the hole of the ring is at the center, what's the fastest way to draw such a ring?

I feel that any answer won't be as fast as the previous polygon challenges, seeing how no matter what the only way to make a clean round edge for a ring is probably to account for almost every pixel on the edge, but feel free to prove me wrong.

By the way, bonus points if the program is able to draw a sector of the ring only (like someone took a bite out of a doughnut, except the teeth are knives). I'll be working on this myself, but I'm not nearly as fast as you guys.

Benchmark to compare your function to:

define draw ring (circle radius) (width radius)
pen up
set [pi v] to [3.14159265]
set [dir v] to [0]
set [dir change v] to ((360) / ([ceiling v] of (((2) * (pi)) * (circle radius))))
set pen size to ((width radius) * (2))
go to x: (([sin v] of (dir)) * ((circle radius) - (width radius))) y: (([cos v] of (dir)) * ((circle radius) - (width radius)))
pen down
repeat ([ceiling v] of (((2) * (pi)) * (circle radius)))
change [dir v] by (dir change)
go to x: (([sin v] of (dir)) * ((circle radius) - (width radius))) y: (([cos v] of (dir)) * ((circle radius) - (width radius)))
end
pen up
(I'll put this in a project if requested)

stop [all v] ::stack
sippingcider
Scratcher
500+ posts

Draw a Ring, but Quickly

Trickery? Witchcraft!

Speaking of, here is some possible sorcery:

If you know the background color:

define draw ring (circle radius) (width radius)
set pen color to (ringColor)
set pen size to (circle radius)
pen down
pen up
set pen color to (backGroundColor)
set pen size to ((circle radius) - (width radius))
pen down
pen up

--_Nova_--
Scratcher
1000+ posts

Draw a Ring, but Quickly

sippingcider wrote:

Trickery? Witchcraft!

Speaking of, here is some possible sorcery:

If you know the background color:

define draw ring (circle radius) (width radius)
set pen color to (ringColor)
set pen size to (circle radius)
pen down
pen up
set pen color to (backGroundColor)
set pen size to ((circle radius) - (width radius))
pen down
pen up

This isn't going to work with examples like the ones above, with shapes generated on top of one another.

sippingcider
Scratcher
500+ posts

Draw a Ring, but Quickly

--_Nova_-- wrote:

This isn't going to work with examples like the ones above, with shapes generated on top of one another.

Well what if the shapes don't want to be generated on top of each other? They need space to blossom and be creative

But all jokes aside, I wonder if there is a way to keep track of the partial shapes inside the circle so this method could be used…seems like it could be way of doing some real powerful code magic.
gtoal
Scratcher
1000+ posts

Draw a Ring, but Quickly

neither fastest nor best but possibly coolest :-) … https://scratch.mit.edu/projects/249324997/

(use turbo mode for speed)

Last edited by gtoal (Sept. 29, 2018 23:17:12)

DadOfMrLog
Scratcher
1000+ posts

Draw a Ring, but Quickly

It is possible to draw a ring without moving the pen by using a really weird ‘feature’ of transparency that acts like a pen eraser (in Scratch 2).

I wrote a project about a year ago that does it, though I never bothered to share it (since it's not ‘future-proof’)…

Hang on…

Aha, here you go: https://scratch.mit.edu/projects/187757638/
(yeah, still unshared; click to draw a random ring at cursor)

Won't work in Scratch 3, of course, but it's a kinda fun quirk of Scratch 2…

Enjoy!

Last edited by DadOfMrLog (Oct. 4, 2018 02:44:35)



Alternate account: TheLogFather –– HowTos and useful custom blocks (see studio). Examples below…


- String manipulation - - - X to power of Y - - - Clone point to clone - Detect New Scratcher - Speed tests studio -

DadOfMrLog
Scratcher
1000+ posts

Draw a Ring, but Quickly

In case anyone's wondering, and can't be bothered to download the sb2 for above unshared project, the non-refresh custom block that draws the ring using the (real!) pen-erasing sorcery looks like this:

define draw ring, outer (o) inner (i) colour (rgb)
set pen size to (o)
set pen color to ((16777216)+(0)) // note these are the RGB colour-picker versions of the block
pen down // have to 'prepare' any part of canvas to be erased by drawing in above colour to start with
set pen color to (((16777216)*(254))+(rgb))
pen down // then draw anything over it, as long as it has *some* transparency
set pen size to (i)
set pen color to ((16777216)+(0))
repeat (24) // overdrawing 24 times with above colour erases the pen canvas
pen down
end
pen up

(The project still has some unnecessary “pen up” blocks in there, but I've removed them from above script. Replacing the “repeat 24” loop with 24 “pen down” blocks removes the need for it to be non-refresh, since they will all then get done in one refresh anyway.)

Note that the max pen size is 255, so that limits the size of the outer ring using this method (though it's easy enough to work around that if necessary, since you can just use some other method to draw a larger circle, and then erase the inside with 24x “pen down”, assuming the inside has size<256 – though even if inside size is >255, you still just need to draw the appropriate inner circle 24x to erase it).


The eraser trick only works on parts of the canvas that were first drawn on using a colour with alpha=1 (e.g. 16777216, though larger alpha just ‘tints’ the erase), then drawn using some transparency (hence the 16777216*254 in the second “set pen color” block above – fully opaque drawing cannot be erased), and all drawn within the same refresh (so you can't go back and erase something that was already committed to the pen canvas on a previous frame, unfortunately).

Last edited by DadOfMrLog (Oct. 8, 2018 20:38:41)



Alternate account: TheLogFather –– HowTos and useful custom blocks (see studio). Examples below…


- String manipulation - - - X to power of Y - - - Clone point to clone - Detect New Scratcher - Speed tests studio -

infinitytec
Scratcher
1000+ posts

Draw a Ring, but Quickly


Probably inefficient and definitely quite random.


Not here much, but sometimes I lurk.
God has a plan. He has a plan for everything, and everyone.

Powered by DjangoBB

Standard | Mobile