g.fillPoly bug? #1288
Replies: 23 comments
-
Posted at 2019-12-05 by @gfwilliams Hi! I believe you just hit this: espruino/Espruino#1710 Basically it's expected at the moment because the poly fill algorithm works on a scanline basis and so only handles regular polygons. It's something I plan to improve at some point soon though - it'll likely decrease the rendering speed slightly but it definitely seems like a worthwhile addition. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2019-12-05 by Raik Oh ok. Thanks. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2019-12-05 by @allObjects Did hit the same issue when developing the graphics for the ui elemets in the ui framework: a drawing of the shape looks perfect... filling it messes it up... reason for it, i guess is, that the 'rounding' - wether to turn on a pixel or not - fails on the + side / edges of the shape relative to the (x) axis. That's one reason. The other is that on low resolution per shape - such as on a Pixl.js - every single pixel matters for how the shape is perceived. I tried to draw the shape and then fill it with a filled shape with dimensions of one less pixle... It helped to a certain extent... but was not cheap... so I dropped the idea and went more for having different sets of vertices to get better results - as much as possible. But as hinted: happens only on low resolution. @gfwilliams, wanted to raise that a bit back, but knowing what was going on at that time, I shelved it for - may be - looking into it myself... (with slim chance to that happen... ever(?)... :\ |
Beta Was this translation helpful? Give feedback.
-
Posted at 2019-12-05 by @allObjects Update with picture taken from PixlJs: Attached you see the differences between left an write for all shapes that are not rectangular.
The 'bad and ugly' is always on the right side... Attachments: |
Beta Was this translation helpful? Give feedback.
-
Posted at 2019-12-06 by @gfwilliams Interesting - could be a rounding issue. I know as @allObjects mentioned circles aren't great either. If anyone wants to have a go at improving fillPoly/fillEllipse then the code's here: https://github.com/espruino/Espruino/blob/master/libs/graphics/graphics.c#L441 You can easily build Espruino 'native' on Linux/Mac/Windows(via Linux subsystem for Windows) and can test using code like this: https://github.com/espruino/Espruino/blob/master/tests/test_graphics_ellipse.js Or even just a bit of C code all on its own would be appreciated. I can merge it into Espruino as long as it works well (although if you're copying it rather than making your own it'll need to be compatible with MPLv2's license). |
Beta Was this translation helpful? Give feedback.
-
Posted at 2019-12-06 by @allObjects @gfwilliams, the drawing does it perfect - all 4 sides equal... same shape filled messes it up... the drawing uses another rounding - pixel or not to pixel than the fill algorithm to cut of the filling line. The circles above are made with segments... vertices. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2019-12-08 by Raik I've looked into this: http://alienryderflex.com/polygon_fill/ |
Beta Was this translation helpful? Give feedback.
-
Posted at 2019-12-08 by @MaBecker
Can you please share the code to generate that screen. This is the last test I like to run before creating the pr with the updated code for Ellipses. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2019-12-08 by Robin Sun 2019.12.08 Good Morning @raik and Kudos on your effort to get running in C#.
As your effort is running in C#, it seems to me the major hurdle in C is over. Puzzling?
On which end is your concern? Using a re-written version of the 2007 copyright Darel Rex Finley 'Efficient Polygon Fill Algorithm' code, or your (presumably) re-written version in Javascript that would be part of the Espruino doamin? |
Beta Was this translation helpful? Give feedback.
-
Posted at 2019-12-08 by @allObjects @MaBecker ( and @gfwilliams ) Ellipse/Circle implementation will not affect my ui code. Because of the low resolution and relative small size of the shapes - and the performance(?) I use only vertices - and that is 'plenty good' enough (if fill rendering would work as 'expected'/not overshoot):
This is the code segment (part of uiExt.js module):
The example is ui_...zip file I sent you a bit ago (.../_sbx/projects/uiExampleAllPixl.js) expecting Espruino Web IDE sandbox folder pointing to As said earlier: Drawing the polygons with the vertices does just fine... filling messes them up. (Working on the maze rendering a +-1 in the coordinates has major impact when working with low resolution like Pixle.js.)
Most stunning is that even position on display matters... I know that for some displays the dot pattern is not squares but rectangles: 30 vs 36 units - such as Pixl.js' one - and that may play into it... I though think that on so low resolutions / small screens, this should not be taken into account, because this messes heavily with rendering. I know circles are then slightly ellipses... but guess, these displays are not used for CAD / making pictures of it and then noticing that the circle is not exactly a circle... With so low resolution / small shapes, one pixel off is worse than the fraction the pixel to pixel difference in x-axis direction vs y-axis direction: On Pixle.js, where a button checkbox is as small as 9 pixel in x and y direction and corner happening in space of 2x2 pixels, one pixel off in the corner by rounding (because of considering the 30 vs 36 pixels x vs y size) is 50%... where as the 30 vs 36 is 20% (max 25%, depending from which side you look). The human eye/brain is able to see a circle and a 45 degree bevel, even though it may not exactly by that... but 50% makes the difference between 'seeing' a square with straight vs beveled corners and a circle or a potato (Nothing wrong with potatoes, ...I mean for a food). NB: I stack / overlay to scale shapes, filled - solid - and 'empty' - borders. I intend same render code for very low resolutions - like 128 vs 240 pixels in width... about very close the same absolute physical size of Pixle.js and 2.8" 240x320 TFT... But I had already to deviate and make the size pick different sets of vertices... and vertices are not exactly cheap in space... (even though there may be some enhancements I could do). Attached is screen shot from Pixl.js (2) and Bangle.js emulation (1). Results are though exactly the same... (why???? - not same display driver).Attachments: |
Beta Was this translation helpful? Give feedback.
-
Posted at 2019-12-09 by @gfwilliams Just so you can test - here's @allObjects' code in the emulator (using the 120x120 gfx mode to double up pixels): https://www.espruino.com/ide/emulator.html?gist=d1b9f19415fe7d58dff5fe8bedf7fbd4&upload @raik thanks - that code looks great. It does say public domain, and honestly it's pretty simple and I'm sure I've seen similar pseudocode in a bunch of places. I'll reimplement it for Espruino with the same basic logic (ideally the final rendering stage would use Espruino's fillRect anyway) just to avoid any potential issues. ... I also wonder how hard it'd be to add antialiasing to that. Probably not that painful at all :) |
Beta Was this translation helpful? Give feedback.
-
Posted at 2019-12-09 by @gfwilliams I'll be putting updates to fillPoly on espruino/Espruino#1710 |
Beta Was this translation helpful? Give feedback.
-
Posted at 2019-12-09 by @gfwilliams @allObjects I may have discovered why fillPoly isn't doing quite what you expect. I should have remembered this: https://www.cs.uic.edu/~jbell/CourseNotes/ComputerGraphics/PolygonFilling.html
Could that be the problem? I'm definitely thinking that Espruino should ignore that, but it seems such an expected part of the polygon fill algorithm it may annoy some users?
Actually if you mean http://espruino.com/ide/emulator.html then it is the same display driver. That's the nice thing about it - it really is Espruino running inside the browser :) |
Beta Was this translation helpful? Give feedback.
-
Posted at 2019-12-09 by @allObjects that must be it... but it is obviously not that simple - and costs cycles / memory for code, and so far the differences were minimal to notice with the resolution and most sizes of shapes I used so far (For vector fonts it is though visible, because the font character's nooks an crannies are small shapes... assuming the same filling algorithm(s) is(are) used.) In my emulator I use canvas and have high resolution and rendering is differently / does alias(?) differently. (The 'bad' thing abut my emulator... or would you call that a simulator?). The difference I felt for drawing horizontal / vertical lines / squares / rectangles /along the x- an y-axes: not the pixel is the coordinate, it is the 'spot' between... because when I render a single pixle line on a coord that is an integer, it shows grey over two pixels... I added 0.5 and then it's different. Also drawing exactly the same line with the background color (black) over a previously white one (showing grey), it does not 'remove' / 'expunge' it: it just gets darker grey! For vector fonts I use a same sized font from the underlaying infrastructure (browser / os). For bitmapped fonts I though have same logic as Espruino but without scaling. I built the emulator/simulator(?) less for the exact look, but more for supporting development of logic, faster round-trips (no upload, slowing by BLE upload). extended debug and i(pseudo) independence from device. For a while I even had code in the project and module files that required by the emulation but were inert / no-ops when running on device. Lucky I got rid of that. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2019-12-09 by @MaBecker Just tested fillPoly_irregular with BOARD=LINUX Attachments: |
Beta Was this translation helpful? Give feedback.
-
Posted at 2019-12-09 by @allObjects ...weird: 2nd row and 2nd thru last block... algorithms usually fail only once and it is because +/-1] And most weird is that 2-dots beveled square - in the bottom row - makes it in most left rendering, but fails for all others. This subject shows that 'Numerische Methoden' are not a simple subject - and I had to take the test twice (first time I ignored the need to be pocket calculator savvy / trained... Know about the concepts and how to apply them is fine, but real life requires to be very fluent in usage...) |
Beta Was this translation helpful? Give feedback.
-
Posted at 2019-12-10 by @gfwilliams Interesting - thanks. Looks like that's not ready to merge then ;) The original algorithm ignores the topmost (lowest Y) pixel of each edge, which means that when edges join you only get one point. That works great apart from right at the top of the shape when the top scanline gets missed off completely. Thinking about it, I could probably just special-case the topmost scanline and those issues should be solved |
Beta Was this translation helpful? Give feedback.
-
Posted at 2019-12-10 by @gfwilliams Ok, fixed and merged :) |
Beta Was this translation helpful? Give feedback.
-
Posted at 2019-12-10 by Raik Very nice! :) But it's not yet in the emulator is it? |
Beta Was this translation helpful? Give feedback.
-
Posted at 2019-12-10 by @gfwilliams Not yet, no :) |
Beta Was this translation helpful? Give feedback.
-
Posted at 2019-12-10 by Raik Ahem, did that break the emulator? Seems to have some kind of y-offset now? Edit: Nevermind, seems to work again.
Attachments: |
Beta Was this translation helpful? Give feedback.
-
Posted at 2019-12-11 by @MaBecker Works fine on my side ;) Attachments: |
Beta Was this translation helpful? Give feedback.
-
Posted at 2019-12-11 by @gfwilliams
Looks like you'd put it into double-buffered mode - which ends up being 160px high widescreen |
Beta Was this translation helpful? Give feedback.
-
Posted at 2019-12-05 by Raik
Hi all,
I am fiddling around with the emulator for BangleJs and found something weird.
g.fillPoly does not fill a concave polygon correctly with the "opening on top", code below.
Is this a bug or did I overlook something obvious?
Attachments:
Beta Was this translation helpful? Give feedback.
All reactions