Skip to main content
March 18, 2014
Question

One Dot Overshoot

  • March 18, 2014
  • 1 reply
  • 918 views

Salutations gentlemen.

I'm trying to render a series of high precision lines, like those in a reticle. To that end, I'm attempting to control the rendering of the lines in device space. The issue I'm having at the moment is that I get lines that are one dot wider than expected, which I term overshoot. For example, if I use the following code fragment:

72 100 div 1 scale

[ 100 720 1 18 102 720 1 18 104 720 1 18 ] rectfill

assuming an output device with a resolution that is a multiple of 100 (e.g. 300 dpi, 600 dpi, etc.) the resulting lines are one dot wider than I would expect. In the example, if rendered at 300 dpi, I would expect lines that are 3 dots wide separated by spaces 3 dots wide, but instead I get lines that are 4 dots wide with spaces that are 2 dots wide. I use rectfill here instead of lineto to avoid the path centering issue (the leading edge of the line begins at a specified coordinate and proceeds for the specified width). Also note that the length of the lines are not required to be at such a high degree of precision. I can trim one dot off the resulting lines to compensate for this behaviour, but I wish to understand why the rendering works this way.

This topic has been closed for replies.

1 reply

Legend
March 18, 2014

The grid fitting rules are your enemy. If any part of a device pixel is inside the path it is marked.

To control rendering in device space you need to do rounding and edge adjustment IN DEVICE SPACE. Typically the proposed path is converted to device space, tweaked, then turned back to user space for specification.

Have you investigated the setstrokeadjust operator, which was designed for needs such as yours.

March 18, 2014

I've tried setstrokeadjust, but it has no effect. I use idtransform to find the dimension of a single unit in device space, then trim that from the width of the lines. I'd like to understand the logic behind the rasterization that yields the extra dot in device space and learn the best approach to controlling how many dots are yielded for each element rendered. Is there a way to control rasterization such that a dot would not be coloured unless at least half of it is within boundaries of a coloured area in user space? I get the impression that even if an infinitesimally small part of the dot extends into a coloured area that the dot will be coloured.

I thought perhaps it was an alignment issue, so I tried using transform to get the starting coordinates of where the edge of the line begins in device space, rounding it to the nearest whole number, then using itransform to get the adjusted user space coordinates, but I still get the extra dot on the lines. I must be missing something somewhere.

Legend
March 18, 2014

The rule is pretty simple and cannot be changed. Imagine working with graph paper. Draw exact thin lines in device coordinates for your path construction. All the pixels through which the path construction passes will be filled. There is uncertainty with lines that exactly run along a pixel boundary.

You can work with this but it requires working with device space. Unround all coordinates so none are exact, so it is clear inside which cells you are drawing. So long as all figures are slightly smaller than their required size (by less than a pixel) and - critically - properly aligned OFF pixel boundaries, you should get what you seek. Using itransform is good, but you are probably missing out the rounding away from pixel edges..

All this breaks down when you make a PDF because for screen display there are rules rather more like what you specify and antialiasing. Indeed, some printers will do this too, but it is nonstandard.