Here is my attempt:
#@cli noise_maxdist : _nb_points[%]>=0
#@cli : Add random noise points to selected image such that added points are set with the maximal possible distance.
#@cli : $$ 300,300 noise_maxdist 1% dilate_circ 5
noise_maxdist : check "$1>=0"
e[^-1] "Add noise points to image$?, with maximal possible distance."
v - repeat $! l[$>]
N={round(${"is_percent $1"}?whd*$1:$1)}
if $N
100%,100%,100% +f. inf
if {d==1} # 2d version
eval "
# Init with random point.
i(#1,round(u([0,0],[w,h]-1))) = 1;
x = w/2; y = h/2; r = max(w,h);
const N1 = "$N"-1;
for (n = 0, n<N1, ++n,
x0 = max(0,x - r); y0 = max(0,y - r);
x1 = min(w - 1,x + r); y1 = min(h - 1,y + r);
ext('+z[^0] ',vtos([x0,y0,x1,y1]),' distance.. 1 min[-2,-1] j[2] .,',vtos([x0,y0]),' rm.');
# Find local maximum of distance function (faster than doing it globally, and improve randomization).
xc = round(u(w-1)); yc = round(u(h-1)); r2 = r*2;
x0 = max(0,xc - r2); y0 = max(0,yc - r2);
x1 = min(w - 1,xc + r2); y1 = min(h - 1,yc + r2);
ext('+z[2] ',vtos([x0,y0,x1,y1]));
s = stats(#-1); x = x0 + s[8]; y = y0 + s[9];
r = i(#2,x,y); ext('rm.');
# Put new point on found location.
i(#1,x,y) = 1;
)"
else # 3d version
eval "
# Init with random point.
i(#1,round(u([0,0,0],[w,h,d]-1))) = 1;
x = w/2; y = h/2; z = d/2; r = max(w,h,d);
const N1 = "$N"-1;
for (n = 0, n<N1, ++n,
x0 = max(0,x - r); y0 = max(0,y - r); z0 = max(0,z - r);
x1 = min(w - 1,x + r); y1 = min(h - 1,y + r); z1 = min(d - 1,z + r);
ext('+z[^0] ',vtos([x0,y0,z0,x1,y1,z1]),' distance.. 1 min[-2,-1] j[2] .,',vtos([x0,y0,z0]),' rm.');
# Find local maximum of distance function (faster than doing it globally, and improve randomization).
xc = round(u(w-1)); yc = round(u(h-1)); zc = round(u(d-1)); r2 = 2*r;
x0 = max(0,xc - r2); y0 = max(0,yc - r2); z0 = max(0,zc - r2);
x1 = min(w - 1,xc + r2); y1 = min(h - 1,yc + r2); z1 = min(d - 1,zc + r2);
ext('+z[2] ',vtos([x0,y0,z0,x1,y1,z1]));
s = stats(#-1); x = x0 + s[8]; y = y0 + s[9]; z = z0 + s[10];
r = i(#2,x,y,z); ext('rm.');
# Put new point on found location.
i(#1,x,y,z) = 1;
)"
fi
f[0] "init(val = vectors(iM==im?1:iM)); i#1?val:I" k[0]
fi
endl done v +
works in 2D and 3D (but slow in 3D ).
Example of use:
$ gmic sp lena,128 noise_maxdist 3%
But I think this is still a bit slow (and I’ve no ideas to speed it up right now).