I'm using Python to generate images using dashed lines for stippling. The period of the dashing is constant, what changes is dash/space ratio. This produces something like this:
However in that image the dashing has a uniform origin and this creates unsightly vertical gutters. So I tried to randomize the origin to remove the gutters. This sort of works but there is an obvious pattern:
Wondering where this comes from I made a very simple test case with stacked dashed straight lines:
random.uniform(-10.,+10.)
(*) (after an initial random.seed()
And with added randomness:
So there is still pattern. What I don't understand is that to get a visible gutter you need to have 6 or 7 consecutive values falling in the same range (says, half the total range), which should be a 1/64 probability but seems to happen a lot more often in the 200 lines generated.
Am I misunderstanding something? Is it just our human brain which is seeing patterns where there is none? Could there be a better way to generate something more "visually random" (python 2.7, and preferably without installing anything)?
(*) partial pixels are valid in that context
Annex: the code I use (this is a Gimp script):
#!/usr/bin/env python # -*- coding: iso-8859-15 -*-Python script for Gimp (requires Gimp 2.10)
Run on a 400x400 image to see something without having to wait too much
Menu entry is in “Test” submenu of image menubar
import random,traceback
from gimpfu import *def constant(minShift,maxShift):
return 0def triangle(minShift,maxShift):
return random.triangular(minShift,maxShift)def uniform(minShift,maxShift):
return random.uniform(minShift,maxShift)def gauss(minShift,maxShift):
return random.gauss((minShift+maxShift)/2,(maxShift-minShift)/2)variants=[(‘Constant’,constant),(‘Triangle’,triangle),(‘Uniform’,uniform),(‘Gauss’,gauss)]
def generate(image,name,generator):
random.seed()
layer=gimp.Layer(image, name, image.width, image.height, RGB_IMAGE,100, LAYER_MODE_NORMAL)
image.add_layer(layer,0)
layer.fill(FILL_WHITE)
path=pdb.gimp_vectors_new(image,name)# Generate path, horizontal lines are 2px apart, # Start on left has a random offset, end is on the right edge right edge for i in range(1,image.height, 2): shift=generator(-10.,10.) points=[shift,i]*3+[image.width,i]*3 pdb.gimp_vectors_stroke_new_from_points(path,0, len(points),points,False) pdb.gimp_image_add_vectors(image, path, 0) # Stroke the path pdb.gimp_context_set_foreground(gimpcolor.RGB(0, 0, 0, 255)) pdb.gimp_context_set_stroke_method(STROKE_LINE) pdb.gimp_context_set_line_cap_style(0) pdb.gimp_context_set_line_join_style(0) pdb.gimp_context_set_line_miter_limit(0.) pdb.gimp_context_set_line_width(2) pdb.gimp_context_set_line_dash_pattern(2,[5,5]) pdb.gimp_drawable_edit_stroke_item(layer,path)
def randomTest(image):
image.undo_group_start()
gimp.context_push()try: for name,generator in variants: generate(image,name,generator) except Exception as e: print e.args[0] pdb.gimp_message(e.args[0]) traceback.print_exc() gimp.context_pop() image.undo_group_end() return;
Registration
desc=“Python random test”
register(
“randomize-test”,desc,‘’,‘’,‘’,‘’,desc,“*”,
[(PF_IMAGE, “image”, “Input image”, None),],[],
randomTest,menu=“<Image>/Test”,
)main()
#python