Support

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

Size-corrected grid square drawing

Post any examples or modules that you want to share here

Size-corrected grid square drawing

Postby tulamide » 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.

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: 2688
Joined: Sat Jun 21, 2014 2:48 pm
Location: Germany

Re: Size-corrected grid square drawing

Postby tulamide » Sat Apr 25, 2020 11:05 am

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!
"There lies the dog buried" (German saying translated literally)
tulamide
 
Posts: 2688
Joined: Sat Jun 21, 2014 2:48 pm
Location: Germany

Re: Size-corrected grid square drawing

Postby martinvicanek » Sat Apr 25, 2020 2:22 pm

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).
User avatar
martinvicanek
 
Posts: 1319
Joined: Sat Jun 22, 2013 8:28 pm

Re: Size-corrected grid square drawing

Postby tektoog » Sat Apr 25, 2020 5:10 pm

Hey,
Yes thanks a lot for that! :D
It particulary drives me nuts with arrows... It always seems that they're not symetrical :shock: :(
"Essential random order for chaotic repetitive sequences"
User avatar
tektoog
 
Posts: 141
Joined: Sat Oct 30, 2010 11:49 pm
Location: Geneva - Switzerland

Re: Size-corrected grid square drawing

Postby tulamide » Sat Apr 25, 2020 10:08 pm

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! :D
It particulary drives me nuts with arrows... It always seems that they're not symetrical :shock: :(

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: 2688
Joined: Sat Jun 21, 2014 2:48 pm
Location: Germany

Re: Size-corrected grid square drawing

Postby DaveyBoy » Wed May 06, 2020 7:31 am

It gets worse . . .

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

Image

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


Arrows Anomaly.fsm
(618 Bytes) Downloaded 941 times


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?
User avatar
DaveyBoy
 
Posts: 131
Joined: Wed May 11, 2016 9:18 pm
Location: Leeds UK


Return to User Examples

Who is online

Users browsing this forum: No registered users and 34 guests