Size-corrected grid square drawing
Posted: Thu Apr 23, 2020 3:30 pm
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