%%
%% This is file `randomwalk.sty',
%% generated with the docstrip utility.
%%
%% The original source files were:
%%
%% randomwalk.dtx  (with options: `package')
%% 
%% Do not distribute a modified version of this file.
%% 
%% Communicate any suggestions for changing this package
%% to Bruno Le Floch (first@su.rname.fr, replaced by the
%% relevant parts of my name).
%% 
%% File: randomwalk.dtx Copyright (C) 2011 Bruno Le Floch
%%
%% It may be distributed and/or modified under the conditions of the
%% LaTeX Project Public License (LPPL), either version 1.3c of this
%% license or (at your option) any later version.  The latest version
%% of this license is in the file
%%
%%    http://www.latex-project.org/lppl.txt
%%
%% -----------------------------------------------------------------------
\RequirePackage{l3names}
\GetIdInfo$Id: randomwalk.dtx 1 2011-01-09 10:15:31Z blefloch $
       {Customizable Random Walks using TikZ}%
\ProvidesExplPackage
  {\filename}{\filedate}{\fileversion}{\filedescription}
\RequirePackage{expl3}
\RequirePackage{xparse}
\RequirePackage{tikz}
\int_const:Nn \c_rw_lcg_first_int {0}
\int_const:Nn \c_rw_lcg_last_int  {536870911}
\int_const:Nn \c_rw_lcg_range_int {
  \c_rw_lcg_last_int - \c_rw_lcg_first_int
}
\RequirePackage [
  first= \c_rw_lcg_first_int,
  last = \c_rw_lcg_last_int,
  counter = lcg@rand ]
  { lcg }
\rand % This \rand avoids some very odd bug.
\fp_const:Nn \c_rw_one_degree_fp {+1.74532925e-2}
\DeclareDocumentCommand \RandomWalk { m } {
  \rw_set_defaults:
  \keys_set:nn { randomwalk } { #1 }
  \rw_walk:
}
\cs_new:Nn \rw_Atype: {}
\cs_new:Nn \rw_Ltype: {}
\tl_new:Nn \l_rw_Aargs_tl {}
\tl_new:Nn \l_rw_Largs_tl {}
\bool_new:N \l_rw_revert_random_bool

\cs_new:Nn \rw_set_defaults:
{
  \fp_set:Nn \l_rw_step_length_fp {10}
  \int_set:Nn \l_rw_step_number_int {10}
  \cs_set:Nn \rw_Atype: {interval:nn}
  \tl_set:Nn \l_rw_Aargs_tl { {-\c_pi_fp} {\c_pi_fp} }
  \cs_set:Nn \rw_Ltype: {fixed:n}
  \tl_set:Nn \l_rw_Largs_tl {\l_rw_step_length_fp}
  \bool_set_false:N \l_rw_revert_random_bool
}
\keys_define:nn { randomwalk } {
  number .value_required:,
  length .value_required:,
  angles .value_required:,
  number .code:n = {\int_set:Nn \l_rw_step_number_int {#1}},
  length .code:n = {
    \clist_clear:N \l_rw_lengths_clist
    \clist_put_right:Nn \l_rw_lengths_clist {#1}
    \tl_set:Nn \l_rw_Largs_tl {\l_rw_lengths_clist}
    \rw_clist_fp_from_dim:N \l_rw_lengths_clist
    \rw_clist_count:NN \l_rw_tmpa_int \l_rw_lengths_clist
    \int_compare:nNnTF {\l_rw_tmpa_int}={1}
    {
      \cs_gset:Nn \rw_Ltype: {fixed:n}
    }
    {
      \cs_gset:Nn \rw_Ltype: {list:N}
    }
  },
  angles .code:n  = {
    \clist_clear:N \l_rw_angles_clist
    \clist_put_right:Nn \l_rw_angles_clist {#1}
    \cs_gset:Nn \rw_Atype: {list:N}
    \tl_set:Nn \l_rw_Aargs_tl {\l_rw_angles_clist}
  },
  degree .code:n = {\rw_radians_from_degrees:N \l_rw_angles_clist},
  degrees .code:n = {\rw_radians_from_degrees:N \l_rw_angles_clist},
  angles-relative .code:n = {\cs_gset:Nx \rw_Atype: {rel_\rw_Atype:}},
  revert-random .bool_set:N = \l_rw_revert_random_bool,
}
\cs_new:Nn \rw_walk:
{
  \fp_set:Nn \l_rw_old_x_fp {0}
  \fp_set:Nn \l_rw_old_y_fp {0}
  \fp_set:Nn \l_rw_new_x_fp {0}
  \fp_set:Nn \l_rw_new_y_fp {0}
  \begin{tikzpicture}
    \prg_stepwise_inline:nnnn {1}{1}{\l_rw_step_number_int}
    {
      \rw_step_draw:
    }
    \bool_if:NF \l_rw_revert_random_bool {
      \global \cr@nd \cr@nd
    }
  \end{tikzpicture}
}
\cs_new:Nn \rw_step_draw:
{
  \rw_step_random_generic:VV \l_rw_Largs_tl \l_rw_Aargs_tl
  \fp_add:Nn \l_rw_new_x_fp {\l_rw_step_x_fp}
  \fp_add:Nn \l_rw_new_y_fp {\l_rw_step_y_fp}
  \draw (\fp_to_dim:N \l_rw_old_x_fp, \fp_to_dim:N \l_rw_old_y_fp)
  -- (\fp_to_dim:N \l_rw_new_x_fp, \fp_to_dim:N \l_rw_new_y_fp);
  \fp_set:Nn \l_rw_old_x_fp {\l_rw_new_x_fp}
  \fp_set:Nn \l_rw_old_y_fp {\l_rw_new_y_fp}
}
\cs_new:Nn \rw_step_random_generic:nn
{
  \cs:w rw_L \rw_Ltype: \cs_end: #1
  \cs:w rw_A \rw_Atype: \cs_end: #2
  \rw_step_build:
}
\cs_generate_variant:Nn \rw_step_random_generic:nn {VV}
\cs_new:Nn \rw_Lfixed:n {
  \fp_set:Nn \l_rw_radius_fp {#1} }
\cs_new:Nn \rw_Llist:N {
  \rw_set_to_random_clist_element:NN \l_rw_radius_fp #1 }
\cs_new:Nn \rw_Linterval:nn {
  \rw_set_to_random_fp:Nnn \l_rw_radius_fp {#1} {#2} }
\cs_new:Nn \rw_Ainterval:nn {
  \rw_set_to_random_fp:Nnn \l_rw_angle_fp {#1} {#2} }
\cs_new:Nn \rw_Alist:N {
  \rw_set_to_random_clist_element:NN \l_rw_angle_fp #1 }
\cs_new:Nn \rw_Arel_interval:nn {
  \rw_add_to_random_fp:Nnn \l_rw_angle_fp {#1} {#2} }
\cs_new:Nn \rw_Arel_list:N {
  \rw_add_to_random_clist_element:NN \l_rw_angle_fp #1 }
\cs_new:Nn \rw_step_build:
{
  \rw_cartesian_from_polar:NNNN  \l_rw_step_x_fp \l_rw_step_y_fp
                                 \l_rw_radius_fp \l_rw_angle_fp
}
\cs_new_protected:Nn \rw_cartesian_from_polar:NNNN
{
  \fp_cos:Nn #1 {\fp_use:N #4}
  \fp_sin:Nn #2 {\fp_use:N #4}
  \fp_mul:Nn #1 {\fp_use:N #3}
  \fp_mul:Nn #2 {\fp_use:N #3}
}
\cs_new_protected:Nn \rw_gcartesian_from_polar:NNNN
{
  \fp_gcos:Nn #1 {\fp_use:N #4}
  \fp_gsin:Nn #2 {\fp_use:N #4}
  \fp_gmul:Nn #1 {\fp_use:N #3}
  \fp_gmul:Nn #2 {\fp_use:N #3}
}
\cs_new:Nn \rw_set_to_random_int:Nnn
{
  \rand
  \int_set:Nn #1
  {
    \int_mod:nn {\c@lcg@rand} { (#3) - (#2) }
  }
}
\cs_new:Nn \rw_set_to_random_fp:Nnn
{
  \fp_set:Nn \l_rw_tmpa_fp {#3}
  \fp_sub:Nn \l_rw_tmpa_fp {#2}
  \rand
  \fp_set:Nn \l_rw_tmpb_fp {\int_use:N \c@lcg@rand}
  \fp_div:Nn \l_rw_tmpb_fp {\int_use:N \c_rw_lcg_range_int}
  \fp_mul:Nn \l_rw_tmpa_fp {\l_rw_tmpb_fp}
  \fp_add:Nn \l_rw_tmpa_fp {#2}
  \fp_set:Nn #1 { \l_rw_tmpa_fp }
}
\cs_new:Nn \rw_add_to_random_fp:Nnn
{
  \fp_set:Nn \l_rw_tmpa_fp {#3}
  \fp_sub:Nn \l_rw_tmpa_fp {#2}
  \rand
  \fp_set:Nn \l_rw_tmpb_fp {\int_use:N \c@lcg@rand}
  \fp_div:Nn \l_rw_tmpb_fp {\int_use:N \c_rw_lcg_range_int}
  \fp_mul:Nn \l_rw_tmpa_fp {\l_rw_tmpb_fp}
  \fp_add:Nn \l_rw_tmpa_fp {#2}
  \fp_add:Nn #1 { \l_rw_tmpa_fp } %here: mod?
}
\cs_new:Nn \rw_clist_count:NN
{
  \int_set:Nn \l_rw_tmpa_int {0}
  \clist_set_eq:NN \l_rw_tmpa_clist #2
  \bool_until_do:nn
  {
    \clist_if_empty_p:N \l_rw_tmpa_clist
  }{
    \clist_pop:NN \l_rw_tmpa_clist \l_rw_tmpa_toks
    \int_add:Nn \l_rw_tmpa_int {1}
  }
  \int_set_eq:NN #1 \l_rw_tmpa_int
}
\cs_new:Nn \rw_clist_nth:NNn {
  \int_set:Nn \l_rw_tmpa_int {#3}
  \clist_set_eq:NN \l_rw_tmpa_clist #2
  \bool_until_do:nn
  {
    \int_compare_p:nNn {\l_rw_tmpa_int}<{0}
  }{
    \clist_pop:NN \l_rw_tmpa_clist \l_rw_tmpc_fp
    \int_add:Nn \l_rw_tmpa_int {-1}
  }
  \fp_set:Nn #1 {\l_rw_tmpc_fp}
}
\cs_new:Nn \rw_set_to_random_clist_element:NN
{
  \rw_clist_count:NN \l_rw_tmpa_int #2
  \rw_set_to_random_int:Nnn \l_rw_tmpb_int {0} {\l_rw_tmpa_int}
  \rw_clist_nth:NNn #1 #2 {\l_rw_tmpb_int}
}
\cs_new:Nn \rw_add_to_random_clist_element:NN
{
  \rw_clist_count:NN \l_rw_tmpa_int #2
  \rw_set_to_random_int:Nnn \l_rw_tmpb_int {0} {\l_rw_tmpa_int}
  \rw_clist_nth:NNn \l_rw_tmpb_fp #2 {\l_rw_tmpb_int}
  \fp_add:Nn #1 {\l_rw_tmpb_fp}
}
\cs_new:Nn \rw_radians_from_degrees:N
{
  \clist_clear:N \l_rw_tmpa_clist
  \bool_until_do:nn
  {
    \clist_if_empty_p:N #1
  }{
    \clist_pop:NN #1 \l_rw_tmpa_toks
    \fp_set:Nn \l_rw_tmpa_fp {\l_rw_tmpa_toks}
    \fp_mul:Nn \l_rw_tmpa_fp {\c_rw_one_degree_fp}
    \clist_push:NV \l_rw_tmpa_clist \l_rw_tmpa_fp
  }
  \clist_put_right:NV #1 \l_rw_tmpa_clist
}

\cs_new:Nn \rw_clist_fp_from_dim:N
{
  \clist_clear:N \l_rw_tmpa_clist
  \bool_until_do:nn
  {
    \clist_if_empty_p:N #1
  }{
    \clist_pop:NN #1 \l_rw_tmpa_toks
    \fp_set_from_dim:Nn \l_rw_tmpa_fp {\l_rw_tmpa_toks}
    \clist_push:NV \l_rw_tmpa_clist \l_rw_tmpa_fp
  }
  \clist_put_right:NV #1 \l_rw_tmpa_clist
}
\fp_new:N \l_rw_old_x_fp
\fp_new:N \l_rw_old_y_fp
\fp_new:N \l_rw_step_x_fp
\fp_new:N \l_rw_step_y_fp
\fp_new:N \l_rw_new_x_fp
\fp_new:N \l_rw_new_y_fp
\fp_new:N \l_rw_angle_fp
\int_new:N \l_rw_step_number_int
\clist_new:N \l_rw_angles_clist
\clist_new:N \l_rw_lengths_clist

\fp_new:N \l_rw_tmpa_fp
\fp_new:N \l_rw_tmpb_fp
\fp_new:N \l_rw_tmpc_fp
\clist_new:N \l_rw_tmpa_clist
\clist_new:N \l_rw_tmpb_clist
\int_new:N \l_rw_tmpa_int
\int_new:N \l_rw_tmpb_int
\int_new:N \l_rw_tmpc_int
%% 
%%
%% End of file `randomwalk.sty'.
