Improved Multi-threaded Diffusion Limited Aggregation
$ 500,500 rep_new_dla 3,10,0,0,5
rep_create_alternating_coordinates_map:
1,1,1,2
eval[0] ${-math_lib}"!((x%2==0)!=(y%2==0))*((x%2==0)||(y%2==0))?dar_insert(#-1,[x,y]);
end(resize(#-1,1,dar_size(#-1),1,s(#-1),0););
"
k.
rep_new_dla:
skip ${1=2},${2=10},${3=1},${4=0},${5=0},${6=1}
#$1==_point_proximity#
#$2==_escape#
#$3==aggregation_mode#
#$4==_target={ 0=dark | 1=light }#
#$5==_border#
#$6==_keep_erase_mask={ 0=maskless | 1=mask }#
__bg={$4?0:1}
m "dla_target_2s : n 0,1 s. c * midpoint={avg(iM,im)} f. i>$midpoint?1"
m "dla_target_3s : n 0,1 s c add / 3 midpoint={avg(iM,im)} f. i>$midpoint?1"
m "dla_target_4s_plus : n 0,1 ts={s-1} s c add[^-1] /.. $ts * midpoint={avg(iM,im)} f. i>$midpoint?1"
m "dla_target : if s==1 n 0,1 elif s==2 dla_target_2s elif s==3 dla_target_3s elif s>3 dla_target_4s_plus fi"
m "dla_check_variance : tv=0 repeat s sh $> tv+={iv#-1} rm. if $tv break fi done u {$tv?1:0}"
m "dla_clear_image : {w#0},{h#0},{d#0},1,$__bg rv[-1,0] rm."
if abs($1)>1 m " dla_create_coordinate_map : +rep_noise_poissondisk_to_coordinates {abs($1)} round."
else m "dla_create_coordinate_map : +rep_create_alternating_coordinates_map"
fi
if $4 m "dla_expand : if $5!=0 +dilate_circ[0] {abs($5)} fi"
else m "dla_expand : if $5!=0 +erode_circ[0] {abs($5)} fi"
fi
n_threads={$_cpus}
mt={$n_threads-1}
l.
$n_threads,1,1,2
+s. x
store[^0] dla_ref
endl
length_const_line=""
dar_lines=""
length_const_line.=begin(
length_const_line.="const ww=w#0;"
length_const_line.="const hh=h#0;"
length_const_line.="const " length_const_line.=lim_atmp=$2;
length_const_line.="const " length_const_line.=dlmode={($4%2)>0?1:0} length_const_line.=;
length_const_line.="const " length_const_line.=use_border="$check_count";
length_const_line.=use_border?(
repeat $n_threads
insert_ref_pos={2+$n_threads+$>}
length_const_line.=check_and_insert_point_$>()=(i(#0,I(#$insert_ref_pos,0,refpos))!=i(#-1,I(#$insert_ref_pos,0,refpos)));
done
length_const_line.=):(
repeat $n_threads
insert_ref_pos={2+$n_threads+$>}
if $4 length_const_line.=check_and_insert_point_$>()=(i(#0,I(#$insert_ref_pos,0,refpos))<1?1);
else length_const_line.=check_and_insert_point_$>()=(i(#0,I(#$insert_ref_pos,0,refpos))>0?1);
fi
done
length_const_line.=);
repeat $n_threads
insert_dar_pos={$>+2}
insert_ref_pos={2+$n_threads+$>}
length_const_line.="const v"
length_const_line.=$>=
length_const_line.=h#$insert_ref_pos
length_const_line.=;
dar_lines.=x==
dar_lines.=$>
dar_lines.=?(
dar_lines.=repeat(v$>,refpos,
dar_lines.=if(check_and_insert_point_$>(),dar_insert(#$insert_dar_pos,I(#$insert_ref_pos,0,refpos)););
dar_lines.=);
dar_lines.=do(n=0;
dar_lines.=do(
dar_lines.=temp_vec=I(#$insert_dar_pos,0,n);
dar_lines.=xp=temp_vec[0];
dar_lines.=yp=temp_vec[1];
dar_lines.=if(
if $4%2
if $3==0 dar_lines.=(i(#0,xp-1,yp-1,0,0,0,2)||i(#0,xp-1,yp+1,0,0,0,2))||(i(#0,xp+1,yp-1,0,0,0,2)||i(#0,xp+1,yp+1,0,0,0,2))
elif $3==1 dar_lines.=(i(#0,xp-1,yp,0,0,0,2)||i(#0,xp+1,yp,0,0,0,2))||(i(#0,xp,yp-1,0,0,0,2)||i(#0,xp,yp+1,0,0,0,2))
elif $3==2 dar_lines.=((i(#0,xp-1,yp-1,0,0,0,2)||i(#0,xp-1,yp+1,0,0,0,2))||(i(#0,xp+1,yp-1,0,0,0,2)||i(#0,xp+1,yp+1,0,0,0,2)))||((i(#0,xp-1,yp,0,0,0,2)||i(#0,xp+1,yp,0,0,0,2))||(i(#0,xp,yp-1,0,0,0,2)||i(#0,xp,yp+1,0,0,0,2)))
elif $3==3 dar_lines.=altern?(i(#0,xp-1,yp-1,0,0,0,2)||i(#0,xp-1,yp+1,0,0,0,2))||(i(#0,xp+1,yp-1,0,0,0,2)||i(#0,xp+1,yp+1,0,0,0,2)):(i(#0,xp-1,yp,0,0,0,2)||i(#0,xp+1,yp,0,0,0,2))||(i(#0,xp,yp-1,0,0,0,2)||i(#0,xp,yp+1,0,0,0,2))
fi
else
if $3==0 dar_lines.=(i(#0,xp-1,yp-1,0,0,0,2)<1||i(#0,xp-1,yp+1,0,0,0,2)<1)||(i(#0,xp+1,yp-1,0,0,0,2)<1||i(#0,xp+1,yp+1,0,0,0,2)<1)
elif $3==1 dar_lines.=(i(#0,xp-1,yp,0,0,0,2)<1||i(#0,xp+1,yp,0,0,0,2)<1)||(i(#0,xp,yp-1,0,0,0,2)<1||i(#0,xp,yp+1,0,0,0,2)<1)
elif $3==2 dar_lines.=((i(#0,xp-1,yp-1,0,0,0,2)<1||i(#0,xp-1,yp+1,0,0,0,2)<1)||(i(#0,xp+1,yp-1,0,0,0,2)<1||i(#0,xp+1,yp+1,0,0,0,2)<1))||((i(#0,xp-1,yp,0,0,0,2)<1||i(#0,xp+1,yp,0,0,0,2)<1)||(i(#0,xp,yp-1,0,0,0,2)<1||i(#0,xp,yp+1,0,0,0,2)<1))
elif $3==3 dar_lines.=altern?(i(#0,xp-1,yp-1,0,0,0,2)<1||i(#0,xp-1,yp+1,0,0,0,2)<1)||(i(#0,xp+1,yp-1,0,0,0,2)<1||i(#0,xp+1,yp+1,0,0,0,2)<1):(i(#0,xp-1,yp,0,0,0,2)<1||i(#0,xp+1,yp,0,0,0,2)<1)||(i(#0,xp,yp-1,0,0,0,2)<1||i(#0,xp,yp+1,0,0,0,2)<1)
fi
fi
dar_lines.=,
dar_lines.=i(#0,xp%ww,yp%hh)=dlmode;
dar_lines.=dar_remove(#$insert_dar_pos,n);
dar_lines.=n--;
dar_lines.=attempts=0;
dar_lines.=);
dar_lines.=n++;
dar_lines.=,n<dar_size(#$insert_dar_pos));
dar_lines.=repeat(dar_size(#$insert_dar_pos),p,
dar_lines.=temp_vec=I(#$insert_dar_pos,0,p);
dar_lines.=px=temp_vec[0];
dar_lines.=py=temp_vec[1];
dar_lines.=pv=round(u(0,7));
dar_lines.=npx=newpos_x[pv];
dar_lines.=npy=newpos_y[pv];
dar_lines.=I(#$insert_dar_pos,0,p)=[px+npx,py+npy];
dar_lines.=);
dar_lines.=,dar_size(#$insert_dar_pos)&&(attempts<lim_atmp));
dar_lines.=)
if ($>!=$mt)
dar_lines.=:
else
dar_lines.=;
fi
done
length_const_line.=newpos_x=[-1,-1,-1,0,0,1,1,1];
length_const_line.=newpos_y=[-1,0,1,-1,1,-1,0,1];
length_const_line.=);
length_const_line.=attempts=0;
length_const_line.=altern=round(u(1));
echo $length_const_line
echo $dar_lines
repeat $! l[$>]
dla_create_coordinate_map
dla_check_variance[0]
use_dla_map=${}
echo $use_dla_map
l[0] $dla_ref endl
s. y,$n_threads
ti={$!}
check_count=0
if $use_dla_map
dla_target[0]
dla_expand
check_count={$!-$ti}
else
dla_clear_image
set[0] {1-$__bg},50%,50%,{d#0==1?0:50%}
fi
eval[1] :${-math_lib}$length_const_line$dar_lines
endl done