%% %% 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 (see the latex-randomwalk repository %% on GitHub). %% %% File: randomwalk.dtx Copyright (C) 2011-2013 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 {expl3} [2012/08/14] \ProvidesExplPackage {randomwalk.sty} {2013/01/08} {0.2c} {Customizable random walks using TikZ} \RequirePackage {xparse} [2012/08/14] \RequirePackage {tikz} \int_const:Nn \c__randomwalk_lcg_last_int { \c_max_int - \c_one } \AtBeginDocument { \RequirePackage [ first= \c_zero , last = \c__randomwalk_lcg_last_int , counter = lcg@rand ] { lcg } \rand % This \rand avoids some very odd bug. } \int_new:N \l__randomwalk_step_number_int \bool_new:N \l__randomwalk_relative_angles_bool \bool_new:N \l__randomwalk_revert_random_bool \cs_new_protected_nopar:Npn \__randomwalk_rand_angle: { } \cs_new_protected_nopar:Npn \__randomwalk_rand_length: { } \fp_new:N \l__randomwalk_angle_fp \fp_new:N \l__randomwalk_length_fp \fp_new:N \l__randomwalk_old_x_fp \fp_new:N \l__randomwalk_old_y_fp \fp_new:N \l__randomwalk_new_x_fp \fp_new:N \l__randomwalk_new_y_fp \seq_new:N \l__randomwalk_angles_seq \seq_new:N \l__randomwalk_lengths_seq \DeclareDocumentCommand \RandomWalk { m } { \__randomwalk_set_defaults: \keys_set:nn { randomwalk } { #1 } \__randomwalk_walk: } \cs_new:Npn \__randomwalk_set_defaults: { \int_set:Nn \l__randomwalk_step_number_int {10} \cs_gset_protected_nopar:Npn \__randomwalk_rand_angle: { \__randomwalk_fp_set_rand:Nnn \l__randomwalk_angle_fp { - pi } { pi } } \cs_gset_protected_nopar:Npn \__randomwalk_rand_length: { \fp_set:Nn \l__randomwalk_length_fp {10} } \bool_set_false:N \l__randomwalk_revert_random_bool \bool_set_false:N \l__randomwalk_relative_angles_bool } \keys_define:nn { randomwalk } { number .value_required: , length .value_required: , angles .value_required: , number .int_set:N = \l__randomwalk_step_number_int , length .code:n = { \seq_set_split:Nnn \l__randomwalk_lengths_seq { , } {#1} \seq_set_map:NNn \l__randomwalk_lengths_seq \l__randomwalk_lengths_seq { \dim_to_fp:n {##1} } \int_compare:nNnTF { \seq_count:N \l__randomwalk_lengths_seq } = {1} { \cs_gset_protected_nopar:Npn \__randomwalk_rand_length: { \fp_set:Nn \l__randomwalk_length_fp {#1} } } { \cs_gset_protected_nopar:Npn \__randomwalk_rand_length: { \__randomwalk_fp_set_rand_seq_item:NN \l__randomwalk_length_fp \l__randomwalk_lengths_seq } } } , angles .code:n = { \seq_set_split:Nnn \l__randomwalk_angles_seq { , } {#1} \cs_gset_protected_nopar:Npn \__randomwalk_rand_angle: { \bool_if:NTF \l__randomwalk_relative_angles_bool { \__randomwalk_fp_add_rand_seq_item:NN } { \__randomwalk_fp_set_rand_seq_item:NN } \l__randomwalk_angle_fp \l__randomwalk_angles_seq } } , degree .code:n = { \__randomwalk_radians_from_degrees:N \l__randomwalk_angles_seq } , degrees .code:n = { \__randomwalk_radians_from_degrees:N \l__randomwalk_angles_seq } , angles-relative .code:n = { \bool_set_true:N \l__randomwalk_relative_angles_bool } , revert-random .bool_set:N = \l__randomwalk_revert_random_bool , } \cs_new:Npn \__randomwalk_radians_from_degrees:N #1 { \seq_set_map:NNn #1 #1 { \fp_eval:n { ##1 deg } } } \cs_new:Npn \__randomwalk_walk: { \begin{tikzpicture} \fp_zero:N \l__randomwalk_old_x_fp \fp_zero:N \l__randomwalk_old_y_fp \fp_zero:N \l__randomwalk_new_x_fp \fp_zero:N \l__randomwalk_new_y_fp \prg_replicate:nn { \l__randomwalk_step_number_int } { \__randomwalk_step_draw: } \bool_if:NF \l__randomwalk_revert_random_bool { \int_gset_eq:NN \cr@nd \cr@nd } \end{tikzpicture} } \cs_new:Npn \__randomwalk_step_draw: { \__randomwalk_rand_length: \__randomwalk_rand_angle: \fp_set_eq:NN \l__randomwalk_old_x_fp \l__randomwalk_new_x_fp \fp_set_eq:NN \l__randomwalk_old_y_fp \l__randomwalk_new_y_fp \fp_add:Nn \l__randomwalk_new_x_fp { \l__randomwalk_length_fp * cos \l__randomwalk_angle_fp } \fp_add:Nn \l__randomwalk_new_y_fp { \l__randomwalk_length_fp * sin \l__randomwalk_angle_fp } \draw ( \fp_to_dim:N \l__randomwalk_old_x_fp, \fp_to_dim:N \l__randomwalk_old_y_fp ) -- ( \fp_to_dim:N \l__randomwalk_new_x_fp, \fp_to_dim:N \l__randomwalk_new_y_fp ); } \cs_new:Npn \__randomwalk_int_set_rand:Nnn #1#2#3 { \rand \int_set:Nn #1 { #2 + \int_mod:nn {\c@lcg@rand} { #3 + 1 - (#2) } } } \cs_new_nopar:Npn \__randomwalk_fp_set_rand:Nnn { \__randomwalk_fp_set_rand_aux:NNnn \fp_set:Nn } \cs_new_nopar:Npn \__randomwalk_fp_add_rand:Nnn { \__randomwalk_fp_set_rand_aux:NNnn \fp_add:Nn } \cs_new:Npn \__randomwalk_fp_set_rand_aux:NNnn #1#2#3#4 { \rand #1 #2 { #3 + (#4 - (#3)) * \c@lcg@rand / \c__randomwalk_lcg_last_int } } \cs_new_protected_nopar:Npn \__randomwalk_fp_set_rand_seq_item:NN { \__randomwalk_fp_set_rand_item_aux:NNNNN \fp_set:Nn \seq_item:Nn \seq_count:N } \cs_new_protected_nopar:Npn \__randomwalk_fp_add_rand_seq_item:NN { \__randomwalk_fp_set_rand_item_aux:NNNNN \fp_add:Nn \seq_item:Nn \seq_count:N } \cs_new_protected:Npn \__randomwalk_fp_set_rand_item_aux:NNNNN #1#2#3#4#5 { \rand #1 #4 { #2 #5 { 1 + \int_mod:nn { \c@lcg@rand } { #3 #5 } } } } %% %% %% End of file `randomwalk.sty'.