holoviz-topics / imagen

ImaGen: Generic Python library for 0D, 1D and 2D pattern distributions
https://imagen.holoviz.org/
BSD 3-Clause "New" or "Revised" License
31 stars 16 forks source link

Imagen.Line doesn't always reach the edge #44

Closed jlstevens closed 9 years ago

jlstevens commented 9 years ago

Try looking at this pattern:

imagen.Line(thickness=0.1, xdensity=9, ydensity=9, smoothing=0, orientation=55*np.pi/120)[:]

The line doesn't reach the edge! And here is the raw array:

array([[ 0.,  0.,  0.,  0.,  0., -0., -0., -0., -0.],
       [ 0.,  0.,  0.,  0.,  1., -0., -0., -0., -0.],
       [ 0.,  0.,  0.,  0.,  1., -0., -0., -0., -0.],
       [ 0.,  0.,  0.,  0.,  1., -0., -0., -0., -0.],
       [ 0.,  0.,  0.,  0.,  1., -0., -0., -0., -0.],
       [ 0.,  0.,  0.,  0.,  1., -0., -0., -0., -0.],
       [ 0.,  0.,  0.,  0.,  1., -0., -0., -0., -0.],
       [ 0.,  0.,  0.,  0.,  1., -0., -0., -0., -0.],
       [ 0.,  0.,  0.,  0., -0., -0., -0., -0., -0.]])
jbednar commented 9 years ago

I don't think this issue is to do with reaching the edge, but with falling between the cracks between locations in the pixel grid. E.g. try changing the 55 to 54, and you should see a gap at a different location, not the edge.

The underlying cause is just that the line thickness you specified is smaller than the distance between grid cell centers, in some directions in the Cartesian grid (though not in the vertical or horizontal directions), and thus in some positions on the grid, the line covers neither the grid cell to the left nor the grid cell to the right, and thus neither is turned on. See PR https://github.com/ioam/imagen/pull/23 for more explanation.

If you want to avoid gaps but keep to the strict definition that grid cells are turned on if and only if the center of the grid cell is within the specified line thickness (which is true by default), you can either increase your line thickness, increase your density, or increase the smoothing (antialiasing), as you wish.

Otherwise, you can set enforce_minimal_thickness=True to ensure that there are never any gaps, but it's not on by default, both for backwards compatibility and because it deviates from the strict definition of how the line function is evaluated on a grid.

jlstevens commented 9 years ago

Ok. That explanation makes sense but I did find it rather odd that one one frame had this issue out of the animation I was looking at (a rotating line). All the other frames reached the edge for the orientations I used.

Good to know about the enforce_minimal_thickness parameter though.

jbednar commented 9 years ago

Just luck and geometry. You should get no line at all in the worst case, e.g. a vertical line falling entirely between the centers::

imagen.Line(thickness=0.1, xdensity=9, ydensity=9, smoothing=0, orientation=np.pi/2,x=0.06)()