is there a method to draw/fill a rounded rectangle? #7344
Replies: 2 comments
-
Posted at 2021-12-29 by Andreas_Rozek well, since I could not find an existing method, I quickly hacked one myself (good enough for my own purposes):
The two functions have been designed to be added to the Attachments: Posted at 2021-12-30 by RaoulDuke Funny, i would have thought Bresenham´s would be a lot faster. It seems to be (i just checked in the emulator, not on the real hardware), but only below a radius of about 12. Most of the code is straight from Wikipedia, no optimization at all:
Posted at 2021-12-30 by HughB Could you share the Wikipedia link? I would be interested in reading it. Posted at 2021-12-30 by Andreas_Rozek this code is more compact than mine and doesn't need Math.sin, at least - but I'd have to modify it in order to be able to draw and/or fill a rounded rectangle. Radii below 12 are certainly the most common ones. Thanks a lot for this contribution! Posted at 2021-12-30 by RaoulDuke Here it is . For some reason, only the german Wikipedia page mentions the cirlce algorithm. Look under "Kreisvariante des Algorithmus". Posted at 2021-12-30 by HilmarSt Nice functionaliy, may be you are willing to extend it a little bit: My proposal is:
where
On the other way round, maybe Posted at 2021-12-30 by RaoulDuke Why not just draw a filled circle, then a larger dark circle on top of that? That is how real moon phases work, after all :) Posted at 2021-12-30 by RaoulDuke Here is a version for filled rectangles. Performance is roughly the same, faster for r<=12, slower for larger radii. Performance is an issue here, on my Bangle2, "bFillRoundedRectangle(10,10,160,160,13);" takes about 85ms. For UI use, i think a LUT for rounded corners would be the best approach. All coordinates needed for a circle covering the complete screen would take up just 52 bytes.
Posted at 2021-12-30 by HilmarSt Good point. Posted at 2021-12-30 by Andreas_Rozek Here is an implementation of your moon phase image (based on Bresenham's circle algorithm - yes, I'm able to learn!):
(see GitHub for the current source code and an animated demo) Have fun! Attachments: Posted at 2021-12-30 by Andreas_Rozek Great, thank you! Concerning performance: you are using the C implementation of Bresenham which assumes that multiplications take longer than additions. However, in Espruino, variable lookup may be more expensive than any kind of addition/multiplication. Thus, the BASIC implementation might be more efficient than yours (this is the one I used for the moon phase visualization). It would be interesting to analyze that dependency... Posted at 2021-12-30 by Andreas_Rozek Here is my implementation of Please note: the Bresenham algorithm makes a few assumptions (e.g.,
It would be interesting to see how that performs compared to the C variant. Attachments: Posted at 2021-12-30 by Andreas_Rozek Last, but not least: the
Now I have everything I need - thank you very much for your assistance! Attachments: Posted at 2021-12-30 by Andreas_Rozek no, they do not (do not mix up moon phases with lunar eclipses!) Moon phases appear because the sun shines on one half of the moon and we (on earth) are looking on it from the side... Posted at 2021-12-30 by RaoulDuke Right, i was thinking of an eclipse... Posted at 2021-12-30 by HilmarSt Wonderful! Posted at 2022-01-10 by Andreas_Rozek meanwhile, I've implemented g.drawRoundRect and g.fillRoundRect as external modules which may easily be loaded into your program.
Posted at 2022-01-10 by diego Thanks, this is great! It's now part of my "toolkit", :P Posted at 2022-01-10 by Ronin This is the code I use for rounded rects in my programs:
Posted at 2022-01-11 by Andreas_Rozek Documentation complete Additionally, there is also a method to draw filled circular rings (g.fillRing) which might become handy when implementing analog clocks Posted at 2022-01-11 by Andreas_Rozek The function to draw a moon phase has been converted into an external module that may be Posted at 2022-01-11 by myownself Interesting. I've written one too, but it is very different. I'll share later (currently on my phone). Posted at 2022-01-11 by myownself @Andreas_Rozek - this is my function, implementing an Andres circle. Heavily based on example implementations on French Wikipedia . I think it can probably be optimised more, and ultimately I also want to draw this a bit at a time. My best approach to that so far is having an array per octant and pushing/unshifting on each iteration for each circle so that I can step through later, but I think I can improve on that. I spent a lot of thinking about allocating a fixed length array for the coordinates, but I've come to the conclusion that it isn't possible to know the length a priori (at least, I think that is the case).
Posted at 2022-01-12 by Andreas_Rozek this looks as if you would draw concentric rings with an increasing radius. How can you prove, that discretisation does not produce small "holes" in your ring? Addendum: I'm currently reading the french Wikipedia entry (well, after translation into german - my french is not good enough for maths) and it seems to be a characteristic of that algorithm that no holes are left Posted at 2022-01-12 by myownself Yes, that is exactly how I came to that algorithm. I had been trying to create a solid ring. At one point in desperation I started with the same polygon approach you tried, but I stopped when I hit the point limit. It isn't described on the English wikipedia, I don't think I saw it on the German one either even though it lists many more circle drawing algorithms than the English one. I haven't been able to read the original paper by Andres, it is paywalled, but I have read some of his later papers* and others that expand on the work. If you want to see the proof (or just out of interest) they can be found online.
Posted at 2022-01-12 by Andreas_Rozek It always surprises me to see how many ways there are to solve a given problem - and what brilliant solutions some people were able to invent! Posted at 2022-02-11 by @gfwilliams Just to say there's now the ability to fill a rounded rect in cutting edge firmwares, with:
draw is not yet implemented Posted at 2022-02-11 by Andreas_Rozek Thank you very much, @gfwilliams! Posted at 2022-02-11 by eyecreate @gfwilliams Thanks for this! I gave up using rounded rectangles in my app due to effort vs benefit to implement, but will use this once it is in a stable release. Is there a way to mark apps as needing something from a specific firmware version? Posted at 2022-02-14 by @gfwilliams
Not right now - there's another thread on this, but the best bet right now would be to either check process.env.VERSION in your code, or maybe even call Posted at 2025-02-07 by momentumv I wrote a different approach for moon-phase drawing using a polygon fill:
I wrote this to shade out a moon image, though you could of course just use a white circle. Posted at 2025-02-07 by @gfwilliams I guess this is a little different than just a rounded rect? For rects, For this, what you're doing looks good. I'd argue it's faster to use fillPoly than trying to draw individual lines - once it has the data it's pretty quick. If you want to speed this up, a few things can help:
And a few things I noticed:
If you want to test the two for speed, I'd paste something along the lines of this into the console:
And then your other implementation and see what the difference is Posted at 2025-02-07 by momentumv Gordon, yes, I probably should have made a new topic and just linked to this older moondraw. Thanks for the feedback, typo catches and suggestions! I'm making a watchface that is a bit of a mashup between Pebble's Fair Circadian, but with the moon phase not as a 'shake to show' but always in the center. I'm using the filled Arcs from graphics_utils. Getting good image graphics on the quite constrained screen is proving challenging as well, I had naively thought I would be able to do a reasonable greyscale image of the moon, but it always looks terrible since it's just dithering instead of true greyscale. I've settled on doing a filled white circle with a 1 bit yellow 'texture' and then the moonshade all stacked in a drawimages call. Posted at 2025-02-07 by @MaBecker
Wow, can’t find it on the reference page |
Beta Was this translation helpful? Give feedback.
-
It's there, just right at the bottom as it's not in all builds: https://www.espruino.com/Reference#l_Graphics_fillRect
|
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-12-29 by Andreas_Rozek
...I can't find one in the reference - but the layout library draws such rectangles around buttons.
Beta Was this translation helpful? Give feedback.
All reactions