NB. Script sfn.ijs for creating an animation of growth for:
NB. A Simple Local Cellular Model for Snow Crystal Growth
NB. Cliff Reiter
NB. Creates a sample animation of the model growth
NB. Requires J (www.jsoftware.com) and the Image3 Addon for J
NB. load required scripts
load '~addons/image3/prevare.ijs'
load '~addons/image3/view_m.ijs'
NB. adverb for creating padding around given configurations
Pad=: 1 : 0
([:-(+2&|)@$@]++:@[){.!.m.((+2&|)@$@]+[){.!.m.]
)
NB. replicate pixels
rep=:[##"1
NB. show array as shifted to a hexagonal lattice
hx_sh=:(e.&0 1@(4:|i.@#)|."0 1])@:(2&rep)
NB. periodic extension functions (overriden)
perext2=:({:,],{.)"1@:({:,],{.)
perext2e=:({:,],{.)"1@:(],2&{.)
NB. left and right neighbor lists
lnbr=:(4 0 1 5 7 6 3)&{@,
rnbr=:(4 1 2 5 8 7 3)&{@,
NB. adverb for applying a local function to hexagonal neighborhoods
Hxauto=: 1 : 0
[: ,/ [: 0 2&|: ((2 1 ,:3 3)&(u.@:lnbr ;._3)@:perext2) ,:(2 1,:3 3)&(u.@:rnbr ;._3)@:perext2e
)
NB. find edge locations
ledge=: (-.@{. * +/ > 0:)@:(1&<:)
NB. find receptive locations (ice or edge)
l_i_or_e=: (+/ > 0:)@:(1&<:)
NB. function to give average values
avg=: +/ % #
hxa_edge=: ledge Hxauto
hxa_i_or_e=: l_i_or_e Hxauto
NB. create averging method
dfu_avg=:1 : 0
((1j6#1)+m.*1 6#_6 1)&(+/ . *)
)
hxa_avg =: (%12) dfu_avg Hxauto
NB. applies one step of
dla=: 3 : 0
0 dla y.
:
e=. hxa_i_or_e y.
z=. hxa_avg y. * -. e
z+e*y.+x.
)
NB. main function for iterating growth model
mk_dla=:1 : 0
200 2000 m. mk_dla y.
:
b_sf=:({.x.) ({.m.) Pad 1 1$1
s_sf=.#b_sf
'ocir icir'=:(2,2#s_sf){.!.(1)cir <:s_sf
bc_fct=: ({.m.)"_
roomq=: 1: *./ . > ,@:(icir&*)
fns=.''
k=.0
n=._2+#m.
while. (roomq b_sf )*. k<{:x. do.
if. 0=10|k do. NB. every tenth frame
fn=.y.,'_',(5 nfmt k),'.png'
(sfP1;sf_vw2 b_sf) write_image fn
end.
b_sf=: ((1+n <.k){m.) dla b_sf
b_sf=:(ocir*bc_fct k)+b_sf*-.ocir
if. 0 = 100|k do.
wd 'reset;'
sf_view b_sf
end.
k=.k+1
end.
(k-1),x.
)
NB. makes inner/outer circles for boundary tests/conditions
cir=:3 : 0 NB. assumes y. is odd
sh=.(1=4|y.){_0.5 0,:0 0.5
hn=.<.-:y.
sq=. ((1 o. 1r3p1)*i:-hn) ([(+/&*:)"0"0 1$@[ $sh"_ +/ ])i: hn
'o i'=.<./"(1) 0 2{sq
(sq>:o),:sq>:i
)
NB. formatting decimals function
to_o=: {&('o',a.)@:(('.',a.)&i.)
NB. file name function
sfnm=: 3 : 0"1
'sf' sfnm y.
:
x.,'_d',(to_o 6j4 ": y.)
)
NB. makes the file sequence
mk_hxs=:3 : 0"1
200 100000 y. mk_dla pathd,'na' sfnm y.
:
x. y. mk_dla pathd,'na' sfnm y.
)
NB. pallete
sfP1=:(<.0.75*3#"0 i.128),Hue 5r6-2r3*(i.%<:)128
NB. scaling for coloring
sf_c=:3 : 0
<.(y.-1)%(1e_4>.<:>./,y.)%127.999
)
NB. viewing functions
sf_vw=:3 : 0
i=.y.>:1
hx_sh ((-.i)*<.128*y.)+i*128+sf_c y.
)
sf_vw2=:3 : 0
i=.y.>:1
z=.hx_sh ((-.i)*<.128*y.)+i*128+sf_c y.
h=.<. 0.5 + (w=.# z)*1 o. 1r3p1
z {~ <.(w %&<: h ) *i. h
)
sf_view=:3 : 0
800 sf_view y.
:
z=.sf_vw y.
r=.1>.<.0.5+-:x.%#y.
view_image sfP1;r rep z
)
NB. the J path to temporary file space
NB. make such a path explicit if necessary
]path=: >(i.&(<'temp')@{. { {:) |:SYSTEMFOLDERS_j_
NB. create temp directory
NB. delete the files in the directory before
NB. running with other parameters
1!:5< pathd=:path,dir_sep,'sfn',dir_sep
NB. make the frames
100 2000 mk_hxs 0.45 0.0001
NB. get the images names (animation frames) in the temp directory
fns=:pngs_in pathd
NB. puts those frames into an animation
NB. with 8 frames per second
8 fseq_to_png_mov fns;nm=:pathd,'sfn.mov'
NB. Attempts to run the animation by
NB. assuming the default J browser has
NB. the Quicktime pluggin installed. Open
NB. sfn.mov in the temp directory with
NB. Quicktime directly if necessary
open_html nm