If you have a problem or need to report a bug please email : support@dsprobotics.com
There are 3 sections to this support area:
DOWNLOADS: access to product manuals, support files and drivers
HELP & INFORMATION: tutorials and example files for learning or finding pre-made modules for your projects
USER FORUMS: meet with other users and exchange ideas, you can also get help and assistance here
NEW REGISTRATIONS - please contact us if you wish to register on the forum
Users are reminded of the forum rules they sign up to which prohibits any activity that violates any laws including posting material covered by copyright
Size-corrected grid square drawing
6 posts
• Page 1 of 1
Size-corrected grid square drawing
It bothers me (and most others probably as well), how grid squares are actually implemented. It implies sub-pixels at all times, but that is not true. On the default zoom level (or when zooming out to see more), there are no sub-pixels. And that leads to imprecise drawing.
Since a pixel has no size property, it is just a spot that may be on or off. With grid squares you give it a size property, and immediately you run into problems, because a size of n grid squares at default zoom level is ranging from the start of the first pixel to the end of the last pixel. The end of a pixel however is the start of the next pixel and therefore you define a length that's actually 1 pixel farther than in reality.
This has consequences when you try to draw in the exact center of a view or close to the view's boundaries. A bad example for this are the stock scope modules (!), where you can't see the pixels drawn to the far right or far bottom (because they are drawn outside of the view). It not only looks ugly, it is actually hiding information from you that you expect to see in a scope.
Not everyone is experienced enough in Ruby to correctly draw pixel-perfect, so I made a little template that should help you.
Just uncomment either of the drawing instructions to see the effect. The drawing with a brush (aka filled shape) should be self-explanatory, but for the pen drawing there's a bad example as well, so that you see the difference. For that I used a very high thickness value, to make it obvious. Don't forget, both use the full size of the view!
Note, that even this example is only pixel-perfect at the default zoom level. If you zoom in, you would need to correct for the current zoom level as well, and that goes beyond a quick and simple template.
Since a pixel has no size property, it is just a spot that may be on or off. With grid squares you give it a size property, and immediately you run into problems, because a size of n grid squares at default zoom level is ranging from the start of the first pixel to the end of the last pixel. The end of a pixel however is the start of the next pixel and therefore you define a length that's actually 1 pixel farther than in reality.
This has consequences when you try to draw in the exact center of a view or close to the view's boundaries. A bad example for this are the stock scope modules (!), where you can't see the pixels drawn to the far right or far bottom (because they are drawn outside of the view). It not only looks ugly, it is actually hiding information from you that you expect to see in a scope.
Not everyone is experienced enough in Ruby to correctly draw pixel-perfect, so I made a little template that should help you.
Just uncomment either of the drawing instructions to see the effect. The drawing with a brush (aka filled shape) should be self-explanatory, but for the pen drawing there's a bad example as well, so that you see the difference. For that I used a very high thickness value, to make it obvious. Don't forget, both use the full size of the view!
Note, that even this example is only pixel-perfect at the default zoom level. If you zoom in, you would need to correct for the current zoom level as well, and that goes beyond a quick and simple template.
- Code: Select all
def init
@pixel = 1.0 / View.new.defaultGridStep
@colors = { black: Color.new(8, 8, 8),
magenta: Color.new(248, 8, 248)
}
@thick = 40
@pen = Pen.new(@colors[:black], @pixel * @thick)
@brush = Brush.new(@colors[:magenta])
end
def draw(view)
##correct usage of brush
#view.drawRectangle(@brush, [0, 0, view.width - @pixel, view.height - @pixel])
##correct usage of pen
#view.drawRectangle(@pen, [@pixel * (@thick * 0.5), @pixel * (@thick * 0.5), view.width - @pixel * (@thick + 1) , view.height - @pixel * (@thick + 1)])
##wrong usage of pen
#view.drawRectangle(@pen, [0, 0, view.width, view.height])
end
"There lies the dog buried" (German saying translated literally)
- tulamide
- Posts: 2714
- Joined: Sat Jun 21, 2014 2:48 pm
- Location: Germany
Re: Size-corrected grid square drawing
Please note, that this affects everything on the graphic side. I just used drawing as an example. But it has to be taken into account as well when you, for example, resize bitmaps (or want to make them fit a specific view).
On just a 5x5 view, you miss 5% of the information. Imagine you'd do that with audio!
On just a 5x5 view, you miss 5% of the information. Imagine you'd do that with audio!
"There lies the dog buried" (German saying translated literally)
- tulamide
- Posts: 2714
- Joined: Sat Jun 21, 2014 2:48 pm
- Location: Germany
Re: Size-corrected grid square drawing
Thanks for that, Tula!
Somewhat related is the following question: Assuming an integer pxel grid-line thickness, what you do if a grid line does not fall exactly onto a pixel: Do you use some sort of antialiasing or just draw it on the nearest pxel row? I tend to prefer the latter simply because it looks nicer. That's for a background grid. For the graph itself I would use antialiasing (which is a topic of its own).
Somewhat related is the following question: Assuming an integer pxel grid-line thickness, what you do if a grid line does not fall exactly onto a pixel: Do you use some sort of antialiasing or just draw it on the nearest pxel row? I tend to prefer the latter simply because it looks nicer. That's for a background grid. For the graph itself I would use antialiasing (which is a topic of its own).
-
martinvicanek - Posts: 1328
- Joined: Sat Jun 22, 2013 8:28 pm
Re: Size-corrected grid square drawing
Hey,
Yes thanks a lot for that!
It particulary drives me nuts with arrows... It always seems that they're not symetrical
Yes thanks a lot for that!
It particulary drives me nuts with arrows... It always seems that they're not symetrical
"Essential random order for chaotic repetitive sequences"
-
tektoog - Posts: 141
- Joined: Sat Oct 30, 2010 11:49 pm
- Location: Geneva - Switzerland
Re: Size-corrected grid square drawing
martinvicanek wrote:Assuming an integer pxel grid-line thickness, what you do if a grid line does not fall exactly onto a pixel: Do you use some sort of antialiasing or just draw it on the nearest pxel row? I tend to prefer the latter simply because it looks nicer. That's for a background grid. For the graph itself I would use antialiasing (which is a topic of its own).
Definitely fall back to the nearest pixel row and don't use AA! The automatic smoothing algorithm (aka AA) would draw beyond your specifications, blurring the drawing. For example, on a 1-pixel-thick line you could end up with two-pixel-thickness (sometimes -wcs- even 3 pixels) of different shades of your color. If you now animate this, you would have a 1-pixel-line on integers and a 2-pixel-line on sub-pixels - a lot of flickering and ultimately ugly!
I generally switch off smoothing for everything straight (horizontal or vertical). For a scope foreground you have to use smoothing of course, because the shapes will be angular most of the times. It's best to use a "buffer zone" towards the boundaries, meaning, don't use the whole view area for foreground drawing, but leave a few pixels of the area untouched. This way the auto-smoothing can extend into that buffer zone.
tektoog wrote:Hey,
Yes thanks a lot for that!
It particulary drives me nuts with arrows... It always seems that they're not symetrical
There are a few traps with things like arrows. The smoothing as described above of course is also a factor here, but many people also don't take into account the missing sub-pixels and have even-sized tips. As soon as such an even-size tip is rotated, it will move a bit away from the original center. Take two of those and they will look indeed unsymmetrical! Make sure, arrows and other shapes used as pointers of some kind have an uneven tip or size. As a bitmap, use an uneven square size if you plan to rotate. That's especially important for knobs!
"There lies the dog buried" (German saying translated literally)
- tulamide
- Posts: 2714
- Joined: Sat Jun 21, 2014 2:48 pm
- Location: Germany
Re: Size-corrected grid square drawing
It gets worse . . .
That's because they're not! . . well maybe symetrical but not equally mirrored
As can be seen in the code, the two triangles have exactly the same x coordinates but the bottom one starts one pixel earlier and ends one pixel later.
The difference in the y axes is exactly the same yet the lower triangle is one pixel taller.
what's going on?
It particulary drives me nuts with arrows... It always seems that they're not symetrical
That's because they're not! . . well maybe symetrical but not equally mirrored
- Code: Select all
def init
@background_brush = Brush.new Color.new 255
@black_brush = Brush.new Color.new 0,0,0
end
def draw v
v.drawRectangle @background_brush, [0,0,v.width - 0.125,v.height - 0.125]
v.setSmoothingMode 0
v.drawPolygon @black_brush, [[5,5],[7,3],[9,5]]
v.drawPolygon @black_brush, [[5,5.125],[7,7.125],[9,5.125]]
end
As can be seen in the code, the two triangles have exactly the same x coordinates but the bottom one starts one pixel earlier and ends one pixel later.
The difference in the y axes is exactly the same yet the lower triangle is one pixel taller.
what's going on?
-
DaveyBoy - Posts: 131
- Joined: Wed May 11, 2016 9:18 pm
- Location: Leeds UK
6 posts
• Page 1 of 1
Who is online
Users browsing this forum: Google [Bot] and 45 guests