From a6cd75438fbcaade92377c09f1656838f98d34bd Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sat, 6 Feb 2021 22:29:38 +0000 Subject: spath3 (6feb21) git-svn-id: svn://tug.org/texlive/trunk@57639 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/tex/latex/spath3/spath3.sty | 2150 ++++++++++++++------ .../latex/spath3/tikzlibrarycalligraphy.code.tex | 387 +++- .../tex/latex/spath3/tikzlibraryknots.code.tex | 244 ++- .../tex/latex/spath3/tikzlibraryspath3.code.tex | 986 ++++++++- 4 files changed, 2872 insertions(+), 895 deletions(-) (limited to 'Master/texmf-dist/tex/latex/spath3') diff --git a/Master/texmf-dist/tex/latex/spath3/spath3.sty b/Master/texmf-dist/tex/latex/spath3/spath3.sty index 155441947b0..868e648f570 100644 --- a/Master/texmf-dist/tex/latex/spath3/spath3.sty +++ b/Master/texmf-dist/tex/latex/spath3/spath3.sty @@ -15,7 +15,7 @@ \NeedsTeXFormat{LaTeX2e} \RequirePackage{expl3} \RequirePackage{pgf} -\ProvidesExplPackage {spath3} {2021/01/19} {2.0} {Functions for +\ProvidesExplPackage {spath3} {2021/02/05} {2.2} {Functions for manipulating PGF soft paths} \RequirePackage{xparse} \cs_new_protected:Nn \__spath_tl_put_right_braced:Nn @@ -40,29 +40,40 @@ manipulating PGF soft paths} \tl_gput_left:Nn #1 { { #2 } } } \cs_generate_variant:Nn \__spath_tl_gput_left_braced:Nn { NV, cV, cv, Nx, cx } +\tl_new:N \g__spath_output_tl +\int_new:N \g__spath_output_int +\seq_new:N \g__spath_output_seq +\bool_new:N \g__spath_output_bool \tl_new:N \l__spath_tmpa_tl \tl_new:N \l__spath_tmpb_tl \tl_new:N \l__spath_tmpc_tl \tl_new:N \l__spath_tmpd_tl \tl_new:N \l__spath_tmpe_tl +\tl_new:N \l__spath_tmpf_tl +\tl_new:N \l__spath_tmpg_tl +\tl_new:N \l__spath_tmph_tl +\tl_new:N \l__spath_tmpi_tl \seq_new:N \l__spath_tmpa_seq \seq_new:N \l__spath_tmpb_seq - -\tl_new:N \g__spath_output_tl -\int_new:N \g__spath_output_int -\seq_new:N \g__spath_output_seq +\seq_new:N \l__spath_tmpc_seq \dim_new:N \l__spath_tmpa_dim \dim_new:N \l__spath_tmpb_dim -\dim_new:N \l__spath_move_x_dim -\dim_new:N \l__spath_move_y_dim + \fp_new:N \l__spath_tmpa_fp \fp_new:N \l__spath_tmpb_fp +\fp_new:N \l__spath_tmpc_fp + \int_new:N \l__spath_tmpa_int +\int_new:N \l__spath_tmpb_int -\bool_new:N \g__spath_output_bool +\bool_new:N \l__spath_tmpa_bool +\dim_new:N \l__spath_move_x_dim +\dim_new:N \l__spath_move_y_dim \bool_new:N \l__spath_closed_bool +\tl_new:N \l__spath_intersecta_tl +\tl_new:N \l__spath_intersectb_tl \tl_const:Nn \c_spath_moveto_tl {\pgfsyssoftpath@movetotoken} \tl_const:Nn \c_spath_lineto_tl {\pgfsyssoftpath@linetotoken} \tl_const:Nn \c_spath_curveto_tl {\pgfsyssoftpath@curvetotoken} @@ -71,143 +82,136 @@ manipulating PGF soft paths} \tl_const:Nn \c_spath_closepath_tl {\pgfsyssoftpath@closepathtoken} \int_new:N \g__spath_anon_int \int_gzero:N \g__spath_anon_int -\tl_new:N \l__spath_itera_tl -\tl_new:N \l__spath_iterb_tl -\tl_new:N \l__spath_iterc_tl -\tl_new:N \l__spath_iterd_tl -\tl_new:N \l__spath_iterp_tl -\dim_new:N \l__spath_itera_dim -\dim_new:N \l__spath_iterb_dim -\seq_new:N \l__spath_iter_seq -\msg_new:nnn { spath3 } { unknown path construction } { The~ path~ construction~ element~ #1~ is~ not~ currently~ supported.} +\msg_new:nnn { spath3 } { unknown path construction } +{ The~ path~ construction~ element~ #1~ is~ not~ currently~ supported.} \cs_new_protected_nopar:Npn \__spath_segments_to_seq:n #1 { \group_begin: - \tl_set:Nn \l__spath_itera_tl {#1} - \tl_clear:N \l__spath_iterb_tl - \seq_clear:N \l__spath_iter_seq - \dim_zero:N \l__spath_itera_dim - \dim_zero:N \l__spath_iterb_dim + \tl_set:Nn \l__spath_tmpa_tl {#1} + \tl_clear:N \l__spath_tmpb_tl + \seq_clear:N \l__spath_tmpa_seq + \dim_zero:N \l__spath_tmpa_dim + \dim_zero:N \l__spath_tmpb_dim \bool_until_do:nn { - \tl_if_empty_p:N \l__spath_itera_tl + \tl_if_empty_p:N \l__spath_tmpa_tl } { - \tl_set:Nx \l__spath_iterc_tl {\tl_head:N \l__spath_itera_tl} - \tl_set:Nx \l__spath_itera_tl {\tl_tail:N \l__spath_itera_tl} - \tl_case:NnF \l__spath_iterc_tl + \tl_set:Nx \l__spath_tmpc_tl {\tl_head:N \l__spath_tmpa_tl} + \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} + \tl_case:NnF \l__spath_tmpc_tl { \c_spath_moveto_tl { - \tl_set_eq:NN \l__spath_iterb_tl \c_spath_moveto_tl - \tl_put_right:Nx \l__spath_iterb_tl {{\tl_head:N \l__spath_itera_tl}} - \dim_set:Nn \l__spath_itera_dim {\tl_head:N \l__spath_itera_tl} - \tl_set:Nx \l__spath_itera_tl {\tl_tail:N \l__spath_itera_tl} + \tl_set_eq:NN \l__spath_tmpb_tl \c_spath_moveto_tl + \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}} + \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl} + \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \tl_put_right:Nx \l__spath_iterb_tl {{\tl_head:N \l__spath_itera_tl}} - \dim_set:Nn \l__spath_iterb_dim {\tl_head:N \l__spath_itera_tl} - \tl_set:Nx \l__spath_itera_tl {\tl_tail:N \l__spath_itera_tl} + \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}} + \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl} + \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_iterd_tl {\tl_head:N \l__spath_itera_tl} - \tl_if_eq:NNF \l__spath_iterd_tl \c_spath_moveto_tl + \tl_set:Nx \l__spath_tmpd_tl {\tl_head:N \l__spath_tmpa_tl} + \tl_if_eq:NNF \l__spath_tmpd_tl \c_spath_moveto_tl { - \tl_clear:N \l__spath_iterb_tl + \tl_clear:N \l__spath_tmpb_tl } } \c_spath_lineto_tl { - \tl_set_eq:NN \l__spath_iterb_tl \c_spath_moveto_tl - \tl_put_right:Nx \l__spath_iterb_tl + \tl_set_eq:NN \l__spath_tmpb_tl \c_spath_moveto_tl + \tl_put_right:Nx \l__spath_tmpb_tl { - {\dim_use:N \l__spath_itera_dim} - {\dim_use:N \l__spath_iterb_dim} + {\dim_use:N \l__spath_tmpa_dim} + {\dim_use:N \l__spath_tmpb_dim} } - \tl_put_right:NV \l__spath_iterb_tl \c_spath_lineto_tl + \tl_put_right:NV \l__spath_tmpb_tl \c_spath_lineto_tl - \tl_put_right:Nx \l__spath_iterb_tl {{\tl_head:N \l__spath_itera_tl}} - \dim_set:Nn \l__spath_itera_dim {\tl_head:N \l__spath_itera_tl} - \tl_set:Nx \l__spath_itera_tl {\tl_tail:N \l__spath_itera_tl} + \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}} + \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl} + \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \tl_put_right:Nx \l__spath_iterb_tl {{\tl_head:N \l__spath_itera_tl}} - \dim_set:Nn \l__spath_iterb_dim {\tl_head:N \l__spath_itera_tl} - \tl_set:Nx \l__spath_itera_tl {\tl_tail:N \l__spath_itera_tl} + \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}} + \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl} + \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} } \c_spath_curvetoa_tl { - \tl_set_eq:NN \l__spath_iterb_tl \c_spath_moveto_tl - \tl_put_right:Nx \l__spath_iterb_tl + \tl_set_eq:NN \l__spath_tmpb_tl \c_spath_moveto_tl + \tl_put_right:Nx \l__spath_tmpb_tl { - {\dim_use:N \l__spath_itera_dim} - {\dim_use:N \l__spath_iterb_dim} + {\dim_use:N \l__spath_tmpa_dim} + {\dim_use:N \l__spath_tmpb_dim} } - \tl_put_right:NV \l__spath_iterb_tl \c_spath_curvetoa_tl + \tl_put_right:NV \l__spath_tmpb_tl \c_spath_curvetoa_tl \prg_replicate:nn {2} { - \tl_put_right:Nx \l__spath_iterb_tl {{\tl_head:N \l__spath_itera_tl}} - \tl_set:Nx \l__spath_itera_tl {\tl_tail:N \l__spath_itera_tl} - \tl_put_right:Nx \l__spath_iterb_tl {{\tl_head:N \l__spath_itera_tl}} - \tl_set:Nx \l__spath_itera_tl {\tl_tail:N \l__spath_itera_tl} - \tl_put_right:Nx \l__spath_iterb_tl {\tl_head:N \l__spath_itera_tl} - \tl_set:Nx \l__spath_itera_tl {\tl_tail:N \l__spath_itera_tl} + \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}} + \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} + \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}} + \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} + \tl_put_right:Nx \l__spath_tmpb_tl {\tl_head:N \l__spath_tmpa_tl} + \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} } - \tl_put_right:Nx \l__spath_iterb_tl {{\tl_head:N \l__spath_itera_tl}} - \dim_set:Nn \l__spath_itera_dim {\tl_head:N \l__spath_itera_tl} - \tl_set:Nx \l__spath_itera_tl {\tl_tail:N \l__spath_itera_tl} + \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}} + \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl} + \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \tl_put_right:Nx \l__spath_iterb_tl {{\tl_head:N \l__spath_itera_tl}} - \dim_set:Nn \l__spath_iterb_dim {\tl_head:N \l__spath_itera_tl} - \tl_set:Nx \l__spath_itera_tl {\tl_tail:N \l__spath_itera_tl} + \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}} + \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl} + \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} } \c_spath_closepath_tl { - \tl_set_eq:NN \l__spath_iterb_tl \c_spath_moveto_tl - \tl_put_right:Nx \l__spath_iterb_tl + \tl_set_eq:NN \l__spath_tmpb_tl \c_spath_moveto_tl + \tl_put_right:Nx \l__spath_tmpb_tl { - {\dim_use:N \l__spath_itera_dim} - {\dim_use:N \l__spath_iterb_dim} + {\dim_use:N \l__spath_tmpa_dim} + {\dim_use:N \l__spath_tmpb_dim} } - \tl_put_right:NV \l__spath_iterb_tl \c_spath_lineto_tl + \tl_put_right:NV \l__spath_tmpb_tl \c_spath_lineto_tl - \tl_put_right:Nx \l__spath_iterb_tl {{\tl_head:N \l__spath_itera_tl}} - \dim_set:Nn \l__spath_itera_dim {\tl_head:N \l__spath_itera_tl} - \tl_set:Nx \l__spath_itera_tl {\tl_tail:N \l__spath_itera_tl} + \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}} + \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl} + \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \tl_put_right:Nx \l__spath_iterb_tl {{\tl_head:N \l__spath_itera_tl}} - \dim_set:Nn \l__spath_iterb_dim {\tl_head:N \l__spath_itera_tl} - \tl_set:Nx \l__spath_itera_tl {\tl_tail:N \l__spath_itera_tl} + \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}} + \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl} + \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} } } { - \tl_set_eq:NN \l__spath_iterb_tl \l__spath_iterc_tl - \tl_put_right:Nx \l__spath_iterb_tl {{\tl_head:N \l__spath_itera_tl}} - \dim_set:Nn \l__spath_itera_dim {\tl_head:N \l__spath_itera_tl} - \tl_set:Nx \l__spath_itera_tl {\tl_tail:N \l__spath_itera_tl} + \tl_set_eq:NN \l__spath_tmpb_tl \l__spath_tmpc_tl + \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}} + \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl} + \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \tl_put_right:Nx \l__spath_iterb_tl {{\tl_head:N \l__spath_itera_tl}} - \dim_set:Nn \l__spath_iterb_dim {\tl_head:N \l__spath_itera_tl} - \tl_set:Nx \l__spath_itera_tl {\tl_tail:N \l__spath_itera_tl} + \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}} + \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl} + \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} } - \tl_if_empty:NF \l__spath_iterb_tl + \tl_if_empty:NF \l__spath_tmpb_tl { - \seq_put_right:NV \l__spath_iter_seq \l__spath_iterb_tl + \seq_put_right:NV \l__spath_tmpa_seq \l__spath_tmpb_tl } - \tl_clear:N \l__spath_iterb_tl + \tl_clear:N \l__spath_tmpb_tl } \seq_gclear:N \g__spath_output_seq - \seq_gset_eq:NN \g__spath_output_seq \l__spath_iter_seq + \seq_gset_eq:NN \g__spath_output_seq \l__spath_tmpa_seq \group_end: } \cs_new_protected_nopar:Npn \spath_segments_to_seq:Nn #1#2 @@ -229,33 +233,33 @@ manipulating PGF soft paths} \cs_new_protected_nopar:Npn \__spath_components_to_seq:n #1 { \group_begin: - \tl_set:Nn \l__spath_itera_tl {#1} - \seq_clear:N \l__spath_iter_seq - \tl_set:Nx \l__spath_itera_tl {\tl_tail:N \l__spath_itera_tl} - \tl_put_right:NV \l__spath_itera_tl \c_spath_moveto_tl - \tl_set_eq:NN \l__spath_iterb_tl \c_spath_moveto_tl + \tl_set:Nn \l__spath_tmpa_tl {#1} + \seq_clear:N \l__spath_tmpa_seq + \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} + \tl_put_right:NV \l__spath_tmpa_tl \c_spath_moveto_tl + \tl_set_eq:NN \l__spath_tmpb_tl \c_spath_moveto_tl \bool_do_until:nn { - \tl_if_empty_p:N \l__spath_itera_tl + \tl_if_empty_p:N \l__spath_tmpa_tl } { - \tl_set:Nx \l__spath_iterc_tl {\tl_head:N \l__spath_itera_tl} - \tl_if_eq:NNT \l__spath_iterc_tl \c_spath_moveto_tl + \tl_set:Nx \l__spath_tmpc_tl {\tl_head:N \l__spath_tmpa_tl} + \tl_if_eq:NNT \l__spath_tmpc_tl \c_spath_moveto_tl { - \seq_put_right:NV \l__spath_iter_seq \l__spath_iterb_tl - \tl_clear:N \l__spath_iterb_tl + \seq_put_right:NV \l__spath_tmpa_seq \l__spath_tmpb_tl + \tl_clear:N \l__spath_tmpb_tl } - \tl_if_single:NTF \l__spath_iterc_tl + \tl_if_single:NTF \l__spath_tmpc_tl { - \tl_put_right:NV \l__spath_iterb_tl \l__spath_iterc_tl + \tl_put_right:NV \l__spath_tmpb_tl \l__spath_tmpc_tl } { - \tl_put_right:Nx \l__spath_iterb_tl {{\l__spath_iterc_tl}} + \tl_put_right:Nx \l__spath_tmpb_tl {{\l__spath_tmpc_tl}} } - \tl_set:Nx \l__spath_itera_tl {\tl_tail:N \l__spath_itera_tl} + \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} } \seq_gclear:N \g__spath_output_seq - \seq_gset_eq:NN \g__spath_output_seq \l__spath_iter_seq + \seq_gset_eq:NN \g__spath_output_seq \l__spath_tmpa_seq \group_end: } \cs_new_protected_nopar:Npn \spath_components_to_seq:Nn #1#2 @@ -300,8 +304,8 @@ manipulating PGF soft paths} \group_begin: \int_set:Nn \l__spath_tmpa_int {0} \tl_map_inline:nn {#1} { - \tl_set:Nn \l__spath_tmpc_tl {##1} - \tl_case:NnT \l__spath_tmpc_tl + \tl_set:Nn \l__spath_tmpa_tl {##1} + \tl_case:NnT \l__spath_tmpa_tl { \c_spath_lineto_tl {} \c_spath_curveto_tl {} @@ -353,24 +357,24 @@ manipulating PGF soft paths} \int_set_eq:NN #1 \g__spath_output_int \int_gzero:N \g__spath_output_int } -\cs_generate_variant:Nn \spath_numberofcomponents:Nn {NV, cn, cV} +\cs_generate_variant:Nn \spath_numberofcomponents:Nn {NV, cn, cV, Nv} \cs_new_protected_nopar:Npn \spath_gnumberofcomponents:Nn #1#2 { \__spath_numberofcomponents:n {#2} \int_gset_eq:NN #1 \g__spath_output_int \int_gzero:N \g__spath_output_int } -\cs_generate_variant:Nn \spath_gnumberofcomponents:Nn {NV, cn, cV} +\cs_generate_variant:Nn \spath_gnumberofcomponents:Nn {NV, cn, cV, Nv} \cs_new_protected_nopar:Npn \__spath_initialpoint:n #1 { \group_begin: - \tl_clear:N \l__spath_tmpb_tl - \tl_set:Nx \l__spath_tmpb_tl + \tl_clear:N \l__spath_tmpa_tl + \tl_set:Nx \l__spath_tmpa_tl { { \tl_item:nn {#1} {2} } { \tl_item:nn {#1} {3} } } - \tl_gset_eq:NN \g__spath_output_tl \l__spath_tmpb_tl + \tl_gset_eq:NN \g__spath_output_tl \l__spath_tmpa_tl \group_end: } \cs_new_protected_nopar:Npn \spath_initialpoint:Nn #1#2 @@ -415,6 +419,50 @@ manipulating PGF soft paths} \tl_gclear:N \g__spath_output_tl } \cs_generate_variant:Nn \spath_gfinalpoint:Nn {NV, cn, cV, Nv} +\cs_new_protected_nopar:Npn \__spath_finalmovepoint:n #1 +{ + \group_begin: + \tl_set:Nn \l__spath_tmpc_tl { {0pt} {0pt} } + \tl_set:Nn \l__spath_tmpa_tl {#1} + \bool_do_until:nn + { + \tl_if_empty_p:N \l__spath_tmpa_tl + } + { + \tl_set:Nx \l__spath_tmpb_tl {\tl_head:N \l__spath_tmpa_tl} + \tl_case:Nn \l__spath_tmpb_tl + { + \c_spath_moveto_tl + { + \tl_set:Nx \l__spath_tmpc_tl + { + { \tl_item:Nn \l__spath_tmpa_tl {2} } + { \tl_item:Nn \l__spath_tmpa_tl {3} } + } + } + } + \prg_replicate:nn {3} + { + \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} + } + } + \tl_gset_eq:NN \g__spath_output_tl \l__spath_tmpc_tl + \group_end: +} +\cs_new_protected_nopar:Npn \spath_finalmovepoint:Nn #1#2 +{ + \__spath_finalmovepoint:n {#2} + \tl_set_eq:NN #1 \g__spath_output_tl + \tl_gclear:N \g__spath_output_tl +} +\cs_generate_variant:Nn \spath_finalmovepoint:Nn {NV, cn, cV} +\cs_new_protected_nopar:Npn \spath_gfinalmovepoint:Nn #1#2 +{ + \__spath_finalmovepoint:n {#2} + \tl_gset_eq:NN #1 \g__spath_output_tl + \tl_gclear:N \g__spath_output_tl +} +\cs_generate_variant:Nn \spath_gfinalmovepoint:Nn {NV, cn, cV} \cs_new_protected_nopar:Npn \__spath_reverse:n #1 { \group_begin: @@ -495,7 +543,10 @@ manipulating PGF soft paths} \bool_set_true:N \l__spath_closed_bool } { - \msg_warning:nnx { spath3 } { unknown path construction } {\l__spath_tmpc_tl } + \msg_warning:nnx + { spath3 } + { unknown path construction } + {\l__spath_tmpc_tl } } \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} @@ -629,9 +680,11 @@ manipulating PGF soft paths} } { \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \dim_set:Nn \l__spath_tmpa_dim {\dim_min:nn {\tl_head:N \l__spath_tmpa_tl} {\l__spath_tmpa_dim}} + \dim_set:Nn \l__spath_tmpa_dim + {\dim_min:nn {\tl_head:N \l__spath_tmpa_tl} {\l__spath_tmpa_dim}} \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \dim_set:Nn \l__spath_tmpb_dim {\dim_min:nn {\tl_head:N \l__spath_tmpa_tl} {\l__spath_tmpb_dim}} + \dim_set:Nn \l__spath_tmpb_dim + {\dim_min:nn {\tl_head:N \l__spath_tmpa_tl} {\l__spath_tmpb_dim}} \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} } \tl_clear:N \l__spath_tmpb_tl @@ -671,9 +724,11 @@ manipulating PGF soft paths} } { \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \dim_set:Nn \l__spath_tmpa_dim {\dim_max:nn {\tl_head:N \l__spath_tmpa_tl} {\l__spath_tmpa_dim}} + \dim_set:Nn \l__spath_tmpa_dim + {\dim_max:nn {\tl_head:N \l__spath_tmpa_tl} {\l__spath_tmpa_dim}} \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \dim_set:Nn \l__spath_tmpb_dim {\dim_max:nn {\tl_head:N \l__spath_tmpa_tl} {\l__spath_tmpb_dim}} + \dim_set:Nn \l__spath_tmpb_dim + {\dim_max:nn {\tl_head:N \l__spath_tmpa_tl} {\l__spath_tmpb_dim}} \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} } \tl_clear:N \l__spath_tmpb_tl @@ -752,6 +807,7 @@ manipulating PGF soft paths} \tl_gset_eq:NN \g__spath_output_tl \l__spath_tmpb_tl \group_end: } +\cs_generate_variant:Nn \__spath_translate:nnn {nVV} \cs_new_protected_nopar:Npn \spath_translate:Nnnn #1#2#3#4 { \__spath_translate:nnn {#2}{#3}{#4} @@ -786,6 +842,61 @@ manipulating PGF soft paths} \spath_gtranslate:Nnn #1 #2 } \cs_generate_variant:Nn \spath_gtranslate:Nn {NV} +\cs_new_protected_nopar:Npn \__spath_translate_to:nnn #1#2#3 +{ + \group_begin: + \spath_initialpoint:Nn \l__spath_tmpa_tl {#1} + + \dim_set:Nn \l__spath_tmpa_dim + { + #2 + - + \tl_item:Nn \l__spath_tmpa_tl {1} + } + \dim_set:Nn \l__spath_tmpb_dim + { + #3 + - + \tl_item:Nn \l__spath_tmpa_tl {2} + } + + \__spath_translate:nVV {#1} \l__spath_tmpa_dim \l__spath_tmpb_dim + \group_end: +} +\cs_new_protected_nopar:Npn \spath_translate_to:Nnnn #1#2#3#4 +{ + \__spath_translate_to:nnn {#2}{#3}{#4} + \tl_set_eq:NN #1 \g__spath_output_tl + \tl_gclear:N \g__spath_output_tl +} +\cs_generate_variant:Nn \spath_translate_to:Nnnn {NVxx, NVVV, NVnn} +\cs_new_protected_nopar:Npn \spath_translate_to:Nnn #1#2#3 +{ + \spath_translate_to:NVnn #1#1{#2}{#3} +} +\cs_generate_variant:Nn \spath_translate_to:Nnn {NVV, cnn, cVV} +\cs_new_protected_nopar:Npn \spath_gtranslate_to:Nnnn #1#2#3#4 +{ + \__spath_translate_to:nnn {#2}{#3}{#4} + \tl_gset_eq:NN #1 \g__spath_output_tl + \tl_gclear:N \g__spath_output_tl +} +\cs_generate_variant:Nn \spath_gtranslate_to:Nnnn {NVxx, NVVV, NVnn} +\cs_new_protected_nopar:Npn \spath_gtranslate_to:Nnn #1#2#3 +{ + \spath_gtranslate_to:NVnn #1#1{#2}{#3} +} +\cs_generate_variant:Nn \spath_gtranslate_to:Nnn {NVV, cnn, cVV} +\cs_new_protected_nopar:Npn \spath_translate_to:Nn #1#2 +{ + \spath_translate_to:Nnn #1 #2 +} +\cs_generate_variant:Nn \spath_translate_to:Nn {NV} +\cs_new_protected_nopar:Npn \spath_gtranslate_to:Nn #1#2 +{ + \spath_gtranslate_to:Nnn #1 #2 +} +\cs_generate_variant:Nn \spath_gtranslate_to:Nn {NV} \cs_new_protected_nopar:Npn \__spath_scale:nnn #1#2#3 { \group_begin: @@ -865,8 +976,10 @@ manipulating PGF soft paths} \tl_set:Nx \l__spath_tmpd_tl {\tl_head:N \l__spath_tmpa_tl} \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \fp_set:Nn \l__spath_tmpa_fp {\l__spath_tmpc_tl * #2 + \l__spath_tmpd_tl * #4 + #6} - \fp_set:Nn \l__spath_tmpb_fp {\l__spath_tmpc_tl * #3 + \l__spath_tmpd_tl * #5 + #7} + \fp_set:Nn \l__spath_tmpa_fp + {\l__spath_tmpc_tl * #2 + \l__spath_tmpd_tl * #4 + #6} + \fp_set:Nn \l__spath_tmpb_fp + {\l__spath_tmpc_tl * #3 + \l__spath_tmpd_tl * #5 + #7} \tl_put_right:Nx \l__spath_tmpb_tl { {\fp_to_dim:N \l__spath_tmpa_fp} @@ -883,7 +996,8 @@ manipulating PGF soft paths} \tl_set_eq:NN #1 \g__spath_output_tl \tl_gclear:N \g__spath_output_tl } -\cs_generate_variant:Nn \spath_transform:Nnnnnnnn {NVnnnnnn, Nnxxxxxx, cnnnnnnn} +\cs_generate_variant:Nn \spath_transform:Nnnnnnnn +{NVnnnnnn, Nnxxxxxx, cnnnnnnn} \cs_new_protected_nopar:Npn \spath_transform:Nnnnnnn #1#2#3#4#5#6#7 { \spath_transform:NVnnnnnn #1#1{#2}{#3}{#4}{#5}{#6}{#7} @@ -922,39 +1036,276 @@ manipulating PGF soft paths} \spath_gtransform:NVnnnnnn #1#1#2 } \cs_generate_variant:Nn \spath_gtransform:Nn {cn, cV, NV} -\cs_new_protected_nopar:Npn \__spath_weld:nn #1#2 +\cs_new_protected_nopar:Npn \__spath_span:nnn #1#2#3 { \group_begin: - \tl_set:Nn \l__spath_tmpa_tl {#1} - \tl_set:Nn \l__spath_tmpb_tl {#2} - - \spath_finalpoint:NV \l__spath_tmpc_tl \l__spath_tmpa_tl - \spath_initialpoint:NV \l__spath_tmpd_tl \l__spath_tmpb_tl + \spath_initialpoint:Nn \l__spath_tmpa_tl {#1} + \spath_finalpoint:Nn \l__spath_tmpb_tl {#1} - \dim_set:Nn \l__spath_tmpa_dim + \fp_set:Nn \l__spath_tmpa_fp { - \tl_item:Nn \l__spath_tmpc_tl {1} - - - \tl_item:Nn \l__spath_tmpd_tl {1} + (\tl_item:Nn \l__spath_tmpb_tl {1}) - + (\tl_item:Nn \l__spath_tmpa_tl {1}) } - \dim_set:Nn \l__spath_tmpb_dim + \fp_set:Nn \l__spath_tmpb_fp { - \tl_item:Nn \l__spath_tmpc_tl {2} - - - \tl_item:Nn \l__spath_tmpd_tl {2} + (\tl_item:Nn \l__spath_tmpb_tl {2}) - + (\tl_item:Nn \l__spath_tmpa_tl {2}) + } + \fp_set:Nn \l__spath_tmpc_fp + { + (\l__spath_tmpa_fp) * (\l__spath_tmpa_fp) + + + (\l__spath_tmpb_fp * \l__spath_tmpb_fp) } - \spath_translate:NVV \l__spath_tmpb_tl \l__spath_tmpa_dim \l__spath_tmpb_dim - - \prg_replicate:nn {3} + \fp_compare:nTF { - \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl} + \l__spath_tmpc_fp < 0.001 } + { + \spath_translate_to:Nnnn \l__spath_tmpd_tl {#1} #2 + } + { + \fp_set:Nn \l__spath_tmpa_fp + { + ( + ((\tl_item:nn {#3} {1}) + - + (\tl_item:nn {#2} {1})) + * + ((\tl_item:Nn \l__spath_tmpb_tl {1}) + - + (\tl_item:Nn \l__spath_tmpa_tl {1})) + + + ((\tl_item:nn {#3} {2}) + - + (\tl_item:nn {#2} {2})) + * + ((\tl_item:Nn \l__spath_tmpb_tl {2}) + - + (\tl_item:Nn \l__spath_tmpa_tl {2})) + ) + / + \l__spath_tmpc_fp + } + \fp_set:Nn \l__spath_tmpb_fp + { + ( + ((\tl_item:nn {#3} {2}) + - + (\tl_item:nn {#2} {2})) + * + ((\tl_item:Nn \l__spath_tmpb_tl {1}) + - + (\tl_item:Nn \l__spath_tmpa_tl {1})) + - + ((\tl_item:nn {#3} {1}) + - + (\tl_item:nn {#2} {1})) + * + ((\tl_item:Nn \l__spath_tmpb_tl {2}) + - + (\tl_item:Nn \l__spath_tmpa_tl {2})) + ) + / + \l__spath_tmpc_fp + } - \tl_put_right:NV \l__spath_tmpa_tl \l__spath_tmpb_tl + \tl_set:Nx \l__spath_tmpc_tl + { + { + \fp_to_decimal:N \l__spath_tmpa_fp + } + { + \fp_to_decimal:N \l__spath_tmpb_fp + } + { + \fp_eval:n { - \l__spath_tmpb_fp } + } + { + \fp_to_decimal:N \l__spath_tmpa_fp + } + { + \fp_to_dim:n + { + \tl_item:nn {#2} {1} + - + \l__spath_tmpa_fp * (\tl_item:Nn \l__spath_tmpa_tl {1}) + + + \l__spath_tmpb_fp * (\tl_item:Nn \l__spath_tmpa_tl {2}) + } + } + { + \fp_to_dim:n + { + \tl_item:nn {#2} {2} + - + \l__spath_tmpb_fp * (\tl_item:Nn \l__spath_tmpa_tl {1}) + - + \l__spath_tmpa_fp * (\tl_item:Nn \l__spath_tmpa_tl {2}) + } + } + } + \spath_transform:NnV \l__spath_tmpd_tl {#1} \l__spath_tmpc_tl + } + \tl_gset_eq:NN \g__spath_output_tl \l__spath_tmpd_tl + \group_end: +} +\cs_new_protected_nopar:Npn \spath_span:Nnnn #1#2#3#4 +{ + \__spath_span:nnn {#2}{#3}{#4} + \tl_set_eq:NN #1 \g__spath_output_tl + \tl_gclear:N \g__spath_output_tl +} +\cs_generate_variant:Nn \spath_span:Nnnn {NVnn, NVVV, NnVV} +\cs_new_protected_nopar:Npn \spath_span:Nnn #1#2#3 +{ + \spath_span:NVnn #1#1{#2}{#3} +} +\cs_generate_variant:Nn \spath_span:Nnn {NVV, cnn, cvv, cVV} +\cs_new_protected_nopar:Npn \spath_gspan:Nnnn #1#2#3#4 +{ + \__spath_span:nnn {#2}{#3}{#4} + \tl_gset_eq:NN #1 \g__spath_output_tl + \tl_gclear:N \g__spath_output_tl +} +\cs_generate_variant:Nn \spath_gspan:Nnnn {NVnn, NVVV} +\cs_new_protected_nopar:Npn \spath_gspan:Nnn #1#2#3 +{ + \spath_gspan:NVnn #1#1{#2}{#3} +} +\cs_generate_variant:Nn \spath_gspan:Nnn {NVV, cnn, cvv, cVV} +\cs_new_protected_nopar:Npn \__spath_normalise:n #1 +{ + \__spath_span:nnn {#1}{{0pt}{0pt}}{{1pt}{0pt}} +} +\cs_new_protected_nopar:Npn \spath_normalise:Nn #1#2 +{ + \__spath_normalise:n {#2} + \tl_set_eq:NN #1 \g__spath_output_tl + \tl_gclear:N \g__spath_output_tl +} +\cs_generate_variant:Nn \spath_normalise:Nn {cn,NV, cV, cv} +\cs_new_protected_nopar:Npn \spath_normalise:N #1 +{ + \spath_normalise:NV #1#1 +} +\cs_generate_variant:Nn \spath_normalise:N {c} +\cs_new_protected_nopar:Npn \spath_gnormalise:Nn #1#2 +{ + \__spath_normalise:n {#2} + \tl_gset_eq:NN #1 \g__spath_output_tl + \tl_gclear:N \g__spath_output_tl +} +\cs_generate_variant:Nn \spath_gnormalise:Nn {cn,NV, cV, cv} +\cs_new_protected_nopar:Npn \spath_gnormalise:N #1 +{ + \spath_gnormalise:NV #1#1 +} +\cs_generate_variant:Nn \spath_gnormalise:N {c} +\cs_new_protected_nopar:Npn \__spath_splice_between:nnn #1#2#3 +{ + \group_begin: + \spath_finalpoint:NV \l__spath_tmpd_tl {#1} + \spath_initialpoint:NV \l__spath_tmpe_tl {#3} + \spath_span:NnVV \l__spath_tmpb_tl {#2} \l__spath_tmpd_tl \l__spath_tmpe_tl + \spath_append_no_move:NnV \l__spath_tmpa_tl {#1} \l__spath_tmpb_tl + \spath_append_no_move:Nn \l__spath_tmpa_tl {#3} \tl_gset_eq:NN \g__spath_output_tl \l__spath_tmpa_tl \group_end: } +\cs_new_protected_nopar:Npn \spath_splice_between:Nnnn #1#2#3#4 +{ + \__spath_splice_between:nnn {#2}{#3}{#4} + \tl_set_eq:NN #1 \g__spath_output_tl + \tl_gclear:N \g__spath_output_tl +} +\cs_generate_variant:Nn \spath_splice_between:Nnnn {NVnn, NVVV} +\cs_new_protected_nopar:Npn \spath_splice_between:Nnn #1#2#3 +{ + \spath_splice_between:NVnn #1#1{#2}{#3} +} +\cs_generate_variant:Nn \spath_splice_between:Nnn {NVV, cnn, cvv, Nvn} +\cs_new_protected_nopar:Npn \spath_gsplice_between:Nnnn #1#2#3#4 +{ + \__spath_splice_between:nnn {#2}{#3}{#4} + \tl_gset_eq:NN #1 \g__spath_output_tl + \tl_gclear:N \g__spath_output_tl +} +\cs_generate_variant:Nn \spath_gsplice_between:Nnnn {NVnn, NVVV} +\cs_new_protected_nopar:Npn \spath_gsplice_between:Nnn #1#2#3 +{ + \spath_gsplice_between:NVnn #1#1{#2}{#3} +} +\cs_generate_variant:Nn \spath_gsplice_between:Nnn {NVV, cnn, cvv} +\cs_new_protected_nopar:Npn \__spath_close_with:nn #1#2 +{ + \group_begin: + \spath_finalmovepoint:Nn \l__spath_tmpa_tl {#1} + \spath_finalpoint:Nn \l__spath_tmpb_tl {#1} + \dim_compare:nTF + { + \dim_abs:n + { + \tl_item:Nn \l__spath_tmpa_tl {1} + - + \tl_item:Nn \l__spath_tmpb_tl {1} + } + + + \dim_abs:n + { + \tl_item:Nn \l__spath_tmpa_tl {2} + - + \tl_item:Nn \l__spath_tmpb_tl {2} + } + < 0.01pt + } + { + \__spath_close:n {#1} + } + { + \spath_span:NnVV \l__spath_tmpc_tl {#2} \l__spath_tmpb_tl \l__spath_tmpa_tl + \spath_append_no_move:NnV \l__spath_tmpd_tl {#1} \l__spath_tmpc_tl + \__spath_close:V \l__spath_tmpd_tl + } + \group_end: +} +\cs_new_protected_nopar:Npn \spath_close_with:Nnn #1#2#3 +{ + \__spath_close_with:nn {#2}{#3} + \tl_set_eq:NN #1 \g__spath_output_tl + \tl_gclear:N \g__spath_output_tl +} +\cs_generate_variant:Nn \spath_close_with:Nnn {cnn, cVV, cvv, NVn} +\cs_new_protected_nopar:Npn \spath_close_with:Nn #1#2 +{ + \spath_close_with:NVn #1#1{#2} +} +\cs_generate_variant:Nn \spath_close_with:Nn {cn, cV, cv, NV} +\cs_new_protected_nopar:Npn \spath_gclose_with:Nnn #1#2#3 +{ + \__spath_close_with:nn {#2}{#3} + \tl_gset_eq:NN #1 \g__spath_output_tl + \tl_gclear:N \g__spath_output_tl +} +\cs_generate_variant:Nn \spath_gclose_with:Nnn {cnn, cVV, cvv, NVn} +\cs_new_protected_nopar:Npn \spath_gclose_with:Nn #1#2 +{ + \spath_gclose_with:NVn #1#1{#2} +} +\cs_generate_variant:Nn \spath_gclose_with:Nn {cn, cV, cv, NV} +\cs_new_protected_nopar:Npn \__spath_weld:nn #1#2 +{ + \group_begin: + \tl_set:Nn \l__spath_tmpa_tl {#1} + \tl_set:Nn \l__spath_tmpb_tl {#2} + \spath_finalpoint:Nn \l__spath_tmpc_tl {#1} + \spath_translate_to:NV \l__spath_tmpb_tl \l__spath_tmpc_tl + + \__spath_append_no_move:VV \l__spath_tmpa_tl \l__spath_tmpb_tl + \group_end: +} \cs_new_protected_nopar:Npn \spath_weld:Nnn #1#2#3 { \__spath_weld:nn {#2}{#3} @@ -992,18 +1343,19 @@ manipulating PGF soft paths} \tl_gset_eq:NN \g__spath_output_tl \l__spath_tmpa_tl \group_end: } +\cs_generate_variant:Nn \__spath_append_no_move:nn {VV} \cs_new_protected_nopar:Npn \spath_append_no_move:Nnn #1#2#3 { \__spath_append_no_move:nn {#2}{#3} \tl_set_eq:NN #1 \g__spath_output_tl \tl_gclear:N \g__spath_output_tl } -\cs_generate_variant:Nn \spath_append_no_move:Nnn {NVV, NVn} +\cs_generate_variant:Nn \spath_append_no_move:Nnn {NVV, NVn, NnV} \cs_new_protected_nopar:Npn \spath_append_no_move:Nn #1#2 { \spath_append_no_move:NVn #1#1{#2} } -\cs_generate_variant:Nn \spath_append_no_move:Nn {NV, cv} +\cs_generate_variant:Nn \spath_append_no_move:Nn {NV, cv, Nv} \cs_new_protected_nopar:Npn \spath_gappend_no_move:Nnn #1#2#3 { \__spath_append_no_move:nn {#2}{#3} @@ -1015,7 +1367,7 @@ manipulating PGF soft paths} { \spath_gappend_no_move:NVn #1#1{#2} } -\cs_generate_variant:Nn \spath_gappend_no_move:Nn {NV, cv} +\cs_generate_variant:Nn \spath_gappend_no_move:Nn {NV, cv, Nv} \cs_new_protected_nopar:Npn \spath_append:Nnn #1#2#3 { \tl_set:Nn #1 {#2} @@ -1026,7 +1378,7 @@ manipulating PGF soft paths} { \spath_append:NVn #1#1{#2} } -\cs_generate_variant:Nn \spath_append:Nn {NV, Nv} +\cs_generate_variant:Nn \spath_append:Nn {NV, Nv, cv} \cs_new_protected_nopar:Npn \spath_gappend:Nnn #1#2#3 { \tl_gset:Nn #1 {#2} @@ -1037,7 +1389,7 @@ manipulating PGF soft paths} { \spath_gappend:NVn #1#1{#2} } -\cs_generate_variant:Nn \spath_gappend:Nn {NV, Nv} +\cs_generate_variant:Nn \spath_gappend:Nn {NV, Nv, cv} \cs_new_protected_nopar:Npn \spath_prepend_no_move:Nnn #1#2#3 { \spath_append_no_move:Nnn #1{#3}{#2} @@ -1114,12 +1466,13 @@ manipulating PGF soft paths} { \group_begin: \tl_set:Nn \l__spath_tmpa_tl {#1} - \spath_initialpoint:NV \l__spath_tmpb_tl \l__spath_tmpa_tl + \spath_finalmovepoint:NV \l__spath_tmpb_tl \l__spath_tmpa_tl \tl_put_right:NV \l__spath_tmpa_tl \c_spath_closepath_tl \tl_put_right:NV \l__spath_tmpa_tl \l__spath_tmpb_tl \tl_gset_eq:NN \g__spath_output_tl \l__spath_tmpa_tl \group_end: } +\cs_generate_variant:Nn \__spath_close:n {V} \cs_new_protected_nopar:Npn \spath_close:Nn #1#2 { \__spath_close:n {#2} @@ -1291,7 +1644,10 @@ manipulating PGF soft paths} \tl_set:Nn \l__spath_tmpa_tl {#1} \tl_set:Nn \l__spath_tmpb_tl {#2} \bool_gset_true:N \g__spath_tmpa_bool - \int_compare:nNnTF {\tl_count:N \l__spath_tmpa_tl} = {\tl_count:N \l__spath_tmpb_tl} + \int_compare:nNnTF + {\tl_count:N \l__spath_tmpa_tl} + = + {\tl_count:N \l__spath_tmpb_tl} { \int_step_inline:nnnn {1} {3} {\tl_count:N \l__spath_tmpa_tl} { @@ -1303,16 +1659,30 @@ manipulating PGF soft paths} } \dim_set:Nn \l__spath_tmpa_dim {\tl_item:Nn \l__spath_tmpa_tl {##1+1}} \dim_set:Nn \l__spath_tmpb_dim {\tl_item:Nn \l__spath_tmpb_tl {##1+1}} - \dim_compare:nF { \dim_abs:n { \l__spath_tmpa_dim - \l__spath_tmpb_dim} < 0.001pt } + \dim_compare:nF + { + \dim_abs:n + { + \l__spath_tmpa_dim - \l__spath_tmpb_dim + } + < 0.001pt + } { \bool_gset_false:N \g__spath_tmpa_bool } \dim_set:Nn \l__spath_tmpa_dim {\tl_item:Nn \l__spath_tmpa_tl {##1+2}} \dim_set:Nn \l__spath_tmpb_dim {\tl_item:Nn \l__spath_tmpb_tl {##1+2}} - \dim_compare:nF { \dim_abs:n { \l__spath_tmpa_dim - \l__spath_tmpb_dim} < 0.001pt } + \dim_compare:nF { - \bool_gset_false:N \g__spath_tmpa_bool - } + \dim_abs:n + { + \l__spath_tmpa_dim - \l__spath_tmpb_dim + } + < 0.001pt + } + { + \bool_gset_false:N \g__spath_tmpa_bool + } } } { @@ -1354,11 +1724,15 @@ manipulating PGF soft paths} { {\fp_to_dim:n { - (1 - #2)^2 * \tl_item:nn {#1} {2} + 2 * (1 - #2) * (#2) * \tl_item:nn {#1} {5} + (#2)^2 * \tl_item:nn {#1} {8} + (1 - #2)^2 * \tl_item:nn {#1} {2} + + 2 * (1 - #2) * (#2) * \tl_item:nn {#1} {5} + + (#2)^2 * \tl_item:nn {#1} {8} }} {\fp_to_dim:n { - (1 - #2)^2 * \tl_item:nn {#1} {3} + 2 * (1 - #2) * (#2) * \tl_item:nn {#1} {6} + (#2)^2 * \tl_item:nn {#1} {9} + (1 - #2)^2 * \tl_item:nn {#1} {3} + + 2 * (1 - #2) * (#2) * \tl_item:nn {#1} {6} + + (#2)^2 * \tl_item:nn {#1} {9} }} } @@ -1367,11 +1741,17 @@ manipulating PGF soft paths} { {\fp_to_dim:n { - (1 - #2)^3 * \tl_item:nn {#1} {2} + 3 * (1 - #2)^2 * (#2) * \tl_item:nn {#1} {5} + 3 * (1 - #2) * (#2)^2 * \tl_item:nn {#1} {8} + (#2)^3 * \tl_item:nn {#1} {11} + (1 - #2)^3 * \tl_item:nn {#1} {2} + + 3 * (1 - #2)^2 * (#2) * \tl_item:nn {#1} {5} + + 3 * (1 - #2) * (#2)^2 * \tl_item:nn {#1} {8} + + (#2)^3 * \tl_item:nn {#1} {11} }} {\fp_to_dim:n { - (1 - #2)^3 * \tl_item:nn {#1} {3} + 3 * (1 - #2)^2 * (#2) * \tl_item:nn {#1} {6} + 3 * (1 - #2) * (#2)^2 * \tl_item:nn {#1} {9} + (#2)^3 * \tl_item:nn {#1} {12} + (1 - #2)^3 * \tl_item:nn {#1} {3} + + 3 * (1 - #2)^2 * (#2) * \tl_item:nn {#1} {6} + + 3 * (1 - #2) * (#2)^2 * \tl_item:nn {#1} {9} + + (#2)^3 * \tl_item:nn {#1} {12} }} } @@ -1384,11 +1764,17 @@ manipulating PGF soft paths} { {\fp_to_dim:n { - (1 - #2)^3 * \tl_item:nn {#1} {2} + 3 * (1 - #2)^2 * (#2) * \tl_item:nn {#1} {5} + 3 * (1 - #2) * (#2)^2 * \tl_item:nn {#1} {8} + (#2)^3 * \tl_item:nn {#1} {11} + (1 - #2)^3 * \tl_item:nn {#1} {2} + + 3 * (1 - #2)^2 * (#2) * \tl_item:nn {#1} {5} + + 3 * (1 - #2) * (#2)^2 * \tl_item:nn {#1} {8} + + (#2)^3 * \tl_item:nn {#1} {11} }} {\fp_to_dim:n { - (1 - #2)^3 * \tl_item:nn {#1} {3} + 3 * (1 - #2)^2 * (#2) * \tl_item:nn {#1} {6} + 3 * (1 - #2) * (#2)^2 * \tl_item:nn {#1} {9} + (#2)^3 * \tl_item:nn {#1} {12} + (1 - #2)^3 * \tl_item:nn {#1} {3} + + 3 * (1 - #2)^2 * (#2) * \tl_item:nn {#1} {6} + + 3 * (1 - #2) * (#2)^2 * \tl_item:nn {#1} {9} + + (#2)^3 * \tl_item:nn {#1} {12} }} } @@ -1397,11 +1783,15 @@ manipulating PGF soft paths} { {\fp_to_dim:n { - (1 - #2)^2 * \tl_item:nn {#1} {5} + 2 * (1 - #2) * (#2) * \tl_item:nn {#1} {8} + (#2)^2 * \tl_item:nn {#1} {11} + (1 - #2)^2 * \tl_item:nn {#1} {5} + + 2 * (1 - #2) * (#2) * \tl_item:nn {#1} {8} + + (#2)^2 * \tl_item:nn {#1} {11} }} {\fp_to_dim:n { - (1 - #2)^2 * \tl_item:nn {#1} {6} + 2 * (1 - #2) * (#2) * \tl_item:nn {#1} {9} + (#2)^2 * \tl_item:nn {#1} {12} + (1 - #2)^2 * \tl_item:nn {#1} {6} + + 2 * (1 - #2) * (#2) * \tl_item:nn {#1} {9} + + (#2)^2 * \tl_item:nn {#1} {12} }} } \tl_put_right:NV \l__spath_tmpa_tl \c_spath_curvetob_tl @@ -1425,6 +1815,7 @@ manipulating PGF soft paths} \__spath_tl_gput_right_braced:NV \g__spath_output_tl \l__spath_tmpa_tl \group_end: } +\cs_generate_variant:Nn \__spath_split_curve:nn {nv, nV} \cs_new_protected_nopar:Npn \spath_split_curve:NNnn #1#2#3#4 { \__spath_split_curve:nn {#3}{#4} @@ -1441,6 +1832,201 @@ manipulating PGF soft paths} \tl_gclear:N \g__spath_output_tl } \cs_generate_variant:Nn \spath_gsplit_curve:NNnn {NNnV, NNVn, NNVV} +\cs_new_protected_nopar:Npn \__spath_maybe_split_curve:n #1 +{ + \group_begin: + \fp_set:Nn \l__spath_tmpa_fp + { + ( + \tl_item:nn {#1} {3} + - 3 * \tl_item:nn {#1} {6} + + 3 * \tl_item:nn {#1} {9} + - \tl_item:nn {#1} {12} + ) + * + (3 * \tl_item:nn {#1} {8} - 3 * \tl_item:nn {#1} {11}) + - + ( + \tl_item:nn {#1} {2} + - 3 * \tl_item:nn {#1} {5} + + 3 * \tl_item:nn {#1} {8} + - \tl_item:nn {#1} {11} + ) + * + (3 * \tl_item:nn {#1} {9} - 3 * \tl_item:nn {#1} {12}) + } + \fp_set:Nn \l__spath_tmpb_fp + { + ( + \tl_item:nn {#1} {2} + - 3 * \tl_item:nn {#1} {5} + + 3 * \tl_item:nn {#1} {8} + - \tl_item:nn {#1} {11} + ) + * + ( + 3 * \tl_item:nn {#1} {6} + - 6 * \tl_item:nn {#1} {9} + + 3 * \tl_item:nn {#1} {12} + ) + - + ( + \tl_item:nn {#1} {3} + - 3 * \tl_item:nn {#1} {6} + + 3 * \tl_item:nn {#1} {9} + - \tl_item:nn {#1} {12} + ) + * + ( + 3 * \tl_item:nn {#1} {5} + - 6 * \tl_item:nn {#1} {8} + + 3 * \tl_item:nn {#1} {11} + ) + } + \fp_compare:nTF + { + \l__spath_tmpb_fp != 0 + } + { + \fp_set:Nn \l__spath_tmpa_fp {.5 * \l__spath_tmpa_fp / \l__spath_tmpb_fp} + \fp_compare:nTF + { + 0 < \l__spath_tmpa_fp && \l__spath_tmpa_fp < 1 + } + { + \__spath_split_curve:nV {#1} \l__spath_tmpa_fp + } + { + \tl_gset:Nn \g__spath_output_tl { {#1} {} } + } + } + { + \tl_gset:Nn \g__spath_output_tl { {#1} {} } + } + \group_end: +} +\cs_new_protected_nopar:Npn \spath_maybe_split_curve:NNn #1#2#3 +{ + \__spath_maybe_split_curve:n {#3} + \tl_set:Nx #1 {\tl_item:Nn \g__spath_output_tl {1}} + \tl_set:Nx #2 {\tl_item:Nn \g__spath_output_tl {2}} + \tl_gclear:N \g__spath_output_tl +} +\cs_generate_variant:Nn \spath_maybe_split_curve:NNn {NNn, NNV } +\cs_new_protected_nopar:Npn \spath_maybe_gsplit_curve:NNn #1#2#3 +{ + \__spath_maybe_split_curve:n {#3} + \tl_gset:Nx #1 {\tl_item:Nn \g__spath_output_tl {1}} + \tl_gset:Nx #2 {\tl_item:Nn \g__spath_output_tl {2}} + \tl_gclear:N \g__spath_output_tl +} +\cs_generate_variant:Nn \spath_maybe_gsplit_curve:NNn {NNn, NNV} +\cs_new_protected_nopar:Npn \__spath_split_curves:n #1 +{ + \group_begin: + \tl_set:Nn \l__spath_tmpa_tl {#1} + \tl_clear:N \l__spath_tmpb_tl + \tl_clear:N \l__spath_tmpc_tl + \bool_do_until:nn + { + \tl_if_empty_p:N \l__spath_tmpa_tl + } + { + \tl_set:Nx \l__spath_tmpc_tl {\tl_head:N \l__spath_tmpa_tl} + \tl_case:NnF \l__spath_tmpc_tl + { + \c_spath_curvetoa_tl + { + \tl_clear:N \l__spath_tmpd_tl + \tl_set_eq:NN \l__spath_tmpd_tl \c_spath_moveto_tl + \tl_put_right:Nx \l__spath_tmpd_tl + { + { \dim_use:N \l__spath_tmpa_dim } + { \dim_use:N \l__spath_tmpb_dim } + } + \dim_set:Nn \l__spath_tmpa_dim + { + \tl_item:Nn \l__spath_tmpa_tl {8} + } + \dim_set:Nn \l__spath_tmpb_dim + { + \tl_item:Nn \l__spath_tmpa_tl {9} + } + \prg_replicate:nn {3} + { + \tl_put_right:Nx \l__spath_tmpd_tl + { + \tl_item:Nn \l__spath_tmpa_tl {1} + {\tl_item:Nn \l__spath_tmpa_tl {2}} + {\tl_item:Nn \l__spath_tmpa_tl {3}} + } + \prg_replicate:nn {3} + { + \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} + } + } + + \spath_maybe_split_curve:NNV + \l__spath_tmpd_tl + \l__spath_tmpe_tl + \l__spath_tmpd_tl + \prg_replicate:nn {3} + { + \tl_set:Nx \l__spath_tmpd_tl {\tl_tail:N \l__spath_tmpd_tl} + \tl_set:Nx \l__spath_tmpe_tl {\tl_tail:N \l__spath_tmpe_tl} + } + \tl_put_right:NV \l__spath_tmpb_tl \l__spath_tmpd_tl + \tl_put_right:NV \l__spath_tmpb_tl \l__spath_tmpe_tl + } + } + { + \dim_set:Nn \l__spath_tmpa_dim + { + \tl_item:Nn \l__spath_tmpa_tl {2} + } + \dim_set:Nn \l__spath_tmpb_dim + { + \tl_item:Nn \l__spath_tmpa_tl {3} + } + \tl_put_right:Nx \l__spath_tmpb_tl + { + \tl_item:Nn \l__spath_tmpa_tl {1} + {\tl_item:Nn \l__spath_tmpa_tl {2}} + {\tl_item:Nn \l__spath_tmpa_tl {3}} + } + \prg_replicate:nn {3} + { + \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} + } + } + } + \tl_gset_eq:NN \g__spath_output_tl \l__spath_tmpb_tl + \group_end: +} +\cs_new_protected_nopar:Npn \spath_split_curves:Nn #1#2 +{ + \__spath_split_curves:n {#2} + \tl_set_eq:NN #1 \g__spath_output_tl + \tl_gclear:N \g__spath_output_tl +} +\cs_generate_variant:Nn \spath_split_curves:Nn {NV, cV, cn, cv } +\cs_new_protected_nopar:Npn \spath_split_curves:N #1 +{ + \spath_split_curves:NV #1#1 +} +\cs_generate_variant:Nn \spath_split_curves:N {c} +\cs_new_protected_nopar:Npn \spath_gsplit_curves:Nn #1#2 +{ + \__spath_split_curves:n {#2} + \tl_gset_eq:NN #1 \g__spath_output_tl + \tl_gclear:N \g__spath_output_tl +} +\cs_generate_variant:Nn \spath_gsplit_curves:Nn {NV, cV, cn, cv } +\cs_new_protected_nopar:Npn \spath_gsplit_curves:N #1 +{ + \spath_gsplit_curves:NV #1#1 +} +\cs_generate_variant:Nn \spath_gsplit_curves:N {c} \cs_new_protected_nopar:Npn \__spath_split_line:nn #1#2 { \group_begin: @@ -1502,179 +2088,168 @@ manipulating PGF soft paths} \tl_gclear:N \g__spath_output_tl } \cs_generate_variant:Nn \spath_gsplit_line:NNnn {NNnV, NNVn, NNVV} -\int_new:N \l__spath_split_int -\int_new:N \l__spath_splitat_int -\fp_new:N \l__spath_split_fp -\bool_new:N \l__spath_split_bool -\tl_new:N \l__spath_split_path_tl -\tl_new:N \l__spath_split_patha_tl -\tl_new:N \l__spath_split_pathb_tl -\tl_new:N \l__spath_split_intoa_tl -\tl_new:N \l__spath_split_intob_tl -\dim_new:N \l__spath_splitx_dim -\dim_new:N \l__spath_splity_dim \cs_new_protected_nopar:Npn \__spath_split_at:nn #1#2 { \group_begin: - \int_set:Nn \l__spath_splitat_int {\fp_to_int:n {floor(#2) + 1}} - \fp_set:Nn \l__spath_split_fp {#2 - floor(#2)} + \int_set:Nn \l__spath_tmpa_int {\fp_to_int:n {floor(#2) + 1}} + \fp_set:Nn \l__spath_tmpa_fp {#2 - floor(#2)} % Is split point near one end or other of a component? \fp_compare:nT { - \l__spath_split_fp < 0.01 + \l__spath_tmpa_fp < 0.01 } { % Near the start, so we'll place it at the start - \fp_set:Nn \l__spath_split_fp {0} + \fp_set:Nn \l__spath_tmpa_fp {0} } \fp_compare:nT { - \l__spath_split_fp > 0.99 + \l__spath_tmpa_fp > 0.99 } { % Near the end, so we'll place it at the end - \fp_set:Nn \l__spath_split_fp {0} - \int_incr:N \l__spath_splitat_int + \fp_set:Nn \l__spath_tmpa_fp {0} + \int_incr:N \l__spath_tmpa_int } - \int_zero:N \l__spath_split_int - \bool_set_true:N \l__spath_split_bool + \int_zero:N \l__spath_tmpb_int + \bool_set_true:N \l__spath_tmpa_bool - \tl_set:Nn \l__spath_split_path_tl {#1} - \tl_clear:N \l__spath_split_patha_tl + \tl_set:Nn \l__spath_tmpe_tl {#1} + \tl_clear:N \l__spath_tmpc_tl - \dim_zero:N \l__spath_splitx_dim - \dim_zero:N \l__spath_splity_dim + \dim_zero:N \l__spath_tmpa_dim + \dim_zero:N \l__spath_tmpb_dim \bool_until_do:nn { - \tl_if_empty_p:N \l__spath_split_path_tl + \tl_if_empty_p:N \l__spath_tmpe_tl || - \int_compare_p:n { \l__spath_splitat_int == \l__spath_split_int } + \int_compare_p:n { \l__spath_tmpa_int == \l__spath_tmpb_int } } { - \tl_set:Nx \l__spath_tmpc_tl {\tl_head:N \l__spath_split_path_tl} - \tl_set:Nx \l__spath_split_path_tl {\tl_tail:N \l__spath_split_path_tl } - \tl_case:Nn \l__spath_tmpc_tl + \tl_set:Nx \l__spath_tmpf_tl {\tl_head:N \l__spath_tmpe_tl} + \tl_set:Nx \l__spath_tmpe_tl {\tl_tail:N \l__spath_tmpe_tl } + \tl_case:Nn \l__spath_tmpf_tl { \c_spath_lineto_tl { - \int_incr:N \l__spath_split_int + \int_incr:N \l__spath_tmpb_int } \c_spath_curvetoa_tl { - \int_incr:N \l__spath_split_int + \int_incr:N \l__spath_tmpb_int } } - \int_compare:nT { \l__spath_split_int < \l__spath_splitat_int } + \int_compare:nT { \l__spath_tmpb_int < \l__spath_tmpa_int } { - \tl_put_right:NV \l__spath_split_patha_tl \l__spath_tmpc_tl + \tl_put_right:NV \l__spath_tmpc_tl \l__spath_tmpf_tl - \tl_put_right:Nx \l__spath_split_patha_tl - {{ \tl_head:N \l__spath_split_path_tl }} - \dim_set:Nn \l__spath_splitx_dim {\tl_head:N \l__spath_split_path_tl} - \tl_set:Nx \l__spath_split_path_tl {\tl_tail:N \l__spath_split_path_tl } + \tl_put_right:Nx \l__spath_tmpc_tl + {{ \tl_head:N \l__spath_tmpe_tl }} + \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpe_tl} + \tl_set:Nx \l__spath_tmpe_tl {\tl_tail:N \l__spath_tmpe_tl } - \tl_put_right:Nx \l__spath_split_patha_tl - {{ \tl_head:N \l__spath_split_path_tl }} - \dim_set:Nn \l__spath_splity_dim {\tl_head:N \l__spath_split_path_tl} - \tl_set:Nx \l__spath_split_path_tl {\tl_tail:N \l__spath_split_path_tl } + \tl_put_right:Nx \l__spath_tmpc_tl + {{ \tl_head:N \l__spath_tmpe_tl }} + \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpe_tl} + \tl_set:Nx \l__spath_tmpe_tl {\tl_tail:N \l__spath_tmpe_tl } } } - \tl_clear:N \l__spath_split_pathb_tl - \tl_put_right:NV \l__spath_split_pathb_tl \c_spath_moveto_tl - \tl_put_right:Nx \l__spath_split_pathb_tl + \tl_clear:N \l__spath_tmpd_tl + \tl_put_right:NV \l__spath_tmpd_tl \c_spath_moveto_tl + \tl_put_right:Nx \l__spath_tmpd_tl { - {\dim_use:N \l__spath_splitx_dim} - {\dim_use:N \l__spath_splity_dim} + {\dim_use:N \l__spath_tmpa_dim} + {\dim_use:N \l__spath_tmpb_dim} } \fp_compare:nTF { - \l__spath_split_fp == 0 + \l__spath_tmpa_fp == 0 } { - \tl_set_eq:NN \l__spath_split_intob_tl \l__spath_split_pathb_tl - \tl_if_empty:NF \l__spath_split_path_tl + \tl_set_eq:NN \l__spath_tmpb_tl \l__spath_tmpd_tl + \tl_if_empty:NF \l__spath_tmpe_tl { - \tl_put_right:NV \l__spath_split_intob_tl \l__spath_tmpc_tl - \tl_put_right:NV \l__spath_split_intob_tl \l__spath_split_path_tl + \tl_put_right:NV \l__spath_tmpb_tl \l__spath_tmpf_tl + \tl_put_right:NV \l__spath_tmpb_tl \l__spath_tmpe_tl } } { - \tl_case:Nn \l__spath_tmpc_tl + \tl_case:Nn \l__spath_tmpf_tl { \c_spath_lineto_tl { - \tl_put_right:NV \l__spath_split_pathb_tl \l__spath_tmpc_tl - \tl_put_right:Nx \l__spath_split_pathb_tl - {{ \tl_head:N \l__spath_split_path_tl }} - \tl_set:Nx \l__spath_split_path_tl {\tl_tail:N \l__spath_split_path_tl } + \tl_put_right:NV \l__spath_tmpd_tl \l__spath_tmpf_tl + \tl_put_right:Nx \l__spath_tmpd_tl + {{ \tl_head:N \l__spath_tmpe_tl }} + \tl_set:Nx \l__spath_tmpe_tl {\tl_tail:N \l__spath_tmpe_tl } - \tl_put_right:Nx \l__spath_split_pathb_tl - {{ \tl_head:N \l__spath_split_path_tl }} - \tl_set:Nx \l__spath_split_path_tl {\tl_tail:N \l__spath_split_path_tl } + \tl_put_right:Nx \l__spath_tmpd_tl + {{ \tl_head:N \l__spath_tmpe_tl }} + \tl_set:Nx \l__spath_tmpe_tl {\tl_tail:N \l__spath_tmpe_tl } \spath_split_line:NNVV - \l__spath_split_intoa_tl - \l__spath_split_intob_tl - \l__spath_split_pathb_tl - \l__spath_split_fp + \l__spath_tmpa_tl + \l__spath_tmpb_tl + \l__spath_tmpd_tl + \l__spath_tmpa_fp \prg_replicate:nn {3} { - \tl_set:Nx \l__spath_split_intoa_tl {\tl_tail:N \l__spath_split_intoa_tl} + \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} } - \tl_put_right:NV \l__spath_split_patha_tl \l__spath_split_intoa_tl - \tl_put_right:NV \l__spath_split_intob_tl \l__spath_split_path_tl + \tl_put_right:NV \l__spath_tmpc_tl \l__spath_tmpa_tl + \tl_put_right:NV \l__spath_tmpb_tl \l__spath_tmpe_tl } \c_spath_curvetoa_tl { - \tl_put_right:NV \l__spath_split_pathb_tl \l__spath_tmpc_tl - \tl_put_right:Nx \l__spath_split_pathb_tl - {{ \tl_head:N \l__spath_split_path_tl }} - \tl_set:Nx \l__spath_split_path_tl {\tl_tail:N \l__spath_split_path_tl } + \tl_put_right:NV \l__spath_tmpd_tl \l__spath_tmpf_tl + \tl_put_right:Nx \l__spath_tmpd_tl + {{ \tl_head:N \l__spath_tmpe_tl }} + \tl_set:Nx \l__spath_tmpe_tl {\tl_tail:N \l__spath_tmpe_tl } - \tl_put_right:Nx \l__spath_split_pathb_tl - {{ \tl_head:N \l__spath_split_path_tl }} - \tl_set:Nx \l__spath_split_path_tl {\tl_tail:N \l__spath_split_path_tl } + \tl_put_right:Nx \l__spath_tmpd_tl + {{ \tl_head:N \l__spath_tmpe_tl }} + \tl_set:Nx \l__spath_tmpe_tl {\tl_tail:N \l__spath_tmpe_tl } \prg_replicate:nn {2} { - \tl_put_right:Nx \l__spath_split_pathb_tl - { \tl_head:N \l__spath_split_path_tl } - \tl_set:Nx \l__spath_split_path_tl {\tl_tail:N \l__spath_split_path_tl } + \tl_put_right:Nx \l__spath_tmpd_tl + { \tl_head:N \l__spath_tmpe_tl } + \tl_set:Nx \l__spath_tmpe_tl {\tl_tail:N \l__spath_tmpe_tl } - \tl_put_right:Nx \l__spath_split_pathb_tl - {{ \tl_head:N \l__spath_split_path_tl }} - \tl_set:Nx \l__spath_split_path_tl {\tl_tail:N \l__spath_split_path_tl } + \tl_put_right:Nx \l__spath_tmpd_tl + {{ \tl_head:N \l__spath_tmpe_tl }} + \tl_set:Nx \l__spath_tmpe_tl {\tl_tail:N \l__spath_tmpe_tl } - \tl_put_right:Nx \l__spath_split_pathb_tl - {{ \tl_head:N \l__spath_split_path_tl }} - \tl_set:Nx \l__spath_split_path_tl {\tl_tail:N \l__spath_split_path_tl } + \tl_put_right:Nx \l__spath_tmpd_tl + {{ \tl_head:N \l__spath_tmpe_tl }} + \tl_set:Nx \l__spath_tmpe_tl {\tl_tail:N \l__spath_tmpe_tl } } \spath_split_curve:NNVV - \l__spath_split_intoa_tl - \l__spath_split_intob_tl - \l__spath_split_pathb_tl \l__spath_split_fp + \l__spath_tmpa_tl + \l__spath_tmpb_tl + \l__spath_tmpd_tl \l__spath_tmpa_fp \prg_replicate:nn {3} { - \tl_set:Nx \l__spath_split_intoa_tl {\tl_tail:N \l__spath_split_intoa_tl} + \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} } - \tl_put_right:NV \l__spath_split_patha_tl \l__spath_split_intoa_tl - \tl_put_right:NV \l__spath_split_intob_tl \l__spath_split_path_tl + \tl_put_right:NV \l__spath_tmpc_tl \l__spath_tmpa_tl + \tl_put_right:NV \l__spath_tmpb_tl \l__spath_tmpe_tl } } } \tl_gclear:N \g__spath_output_tl - \__spath_tl_gput_right_braced:NV \g__spath_output_tl \l__spath_split_patha_tl - \__spath_tl_gput_right_braced:NV \g__spath_output_tl \l__spath_split_intob_tl + \__spath_tl_gput_right_braced:NV \g__spath_output_tl \l__spath_tmpc_tl + \__spath_tl_gput_right_braced:NV \g__spath_output_tl \l__spath_tmpb_tl \group_end: } \cs_new_protected_nopar:Npn \spath_split_at:NNnn #1#2#3#4 @@ -1696,7 +2271,11 @@ manipulating PGF soft paths} \cs_new_protected_nopar:Npn \spath_split_at:Nnn #1#2#3 { \__spath_split_at:nn {#2}{#3} - \tl_set:Nx #1 {\tl_item:Nn \g__spath_output_tl {1} \tl_item:Nn \g__spath_output_tl {2}} + \tl_set:Nx #1 + { + \tl_item:Nn \g__spath_output_tl {1} + \tl_item:Nn \g__spath_output_tl {2} + } \tl_gclear:N \g__spath_output_tl } \cs_generate_variant:Nn \spath_split_at:Nnn {NVn, NVV} @@ -1707,7 +2286,11 @@ manipulating PGF soft paths} \cs_new_protected_nopar:Npn \spath_gsplit_at:Nnn #1#2#3 { \__spath_split_at:nn {#2}{#3} - \tl_gset:Nx #1 {\tl_item:Nn \g__spath_output_tl {1} \tl_item:Nn \g__spath_output_tl {2}} + \tl_gset:Nx #1 + { + \tl_item:Nn \g__spath_output_tl {1} + \tl_item:Nn \g__spath_output_tl {2} + } \tl_gclear:N \g__spath_output_tl } \cs_generate_variant:Nn \spath_gsplit_at:Nnn {NVn, NVV} @@ -1715,15 +2298,6 @@ manipulating PGF soft paths} { \spath_gsplit_at:NVn #1#1{#2} } -\tl_new:N \l__spath_shorten_fa_tl -\tl_new:N \l__spath_shorten_path_tl -\tl_new:N \l__spath_shorten_last_tl -\tl_new:N \l__spath_shorten_lasta_tl -\tl_new:N \l__spath_shorten_lastb_tl -\int_new:N \l__spath_shorten_int -\fp_new:N \l__spath_shorten_x_fp -\fp_new:N \l__spath_shorten_y_fp -\fp_new:N \l__spath_shorten_len_fp \cs_new_protected_nopar:Npn \__spath_shorten_at_end:nn #1#2 { \int_compare:nTF @@ -1732,121 +2306,121 @@ manipulating PGF soft paths} } { \group_begin: - \tl_set:Nn \l__spath_shorten_path_tl {#1} - \tl_reverse:N \l__spath_shorten_path_tl + \tl_set:Nn \l__spath_tmpa_tl {#1} + \tl_reverse:N \l__spath_tmpa_tl - \tl_set:Nx \l__spath_shorten_fa_tl {\tl_item:Nn \l__spath_shorten_path_tl {3}} + \tl_set:Nx \l__spath_tmpb_tl {\tl_item:Nn \l__spath_tmpa_tl {3}} - \tl_clear:N \l__spath_shorten_last_tl - \tl_if_eq:NNTF \l__spath_shorten_fa_tl \c_spath_curveto_tl + \tl_clear:N \l__spath_tmpe_tl + \tl_if_eq:NNTF \l__spath_tmpb_tl \c_spath_curveto_tl { - \int_set:Nn \l__spath_shorten_int {3} + \int_set:Nn \l__spath_tmpa_int {3} } { - \int_set:Nn \l__spath_shorten_int {1} + \int_set:Nn \l__spath_tmpa_int {1} } - \prg_replicate:nn { \l__spath_shorten_int } + \prg_replicate:nn { \l__spath_tmpa_int } { - \tl_put_right:Nx \l__spath_shorten_last_tl + \tl_put_right:Nx \l__spath_tmpe_tl { - {\tl_head:N \l__spath_shorten_path_tl} + {\tl_head:N \l__spath_tmpa_tl} } - \tl_set:Nx \l__spath_shorten_path_tl {\tl_tail:N \l__spath_shorten_path_tl} - \tl_put_right:Nx \l__spath_shorten_last_tl + \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} + \tl_put_right:Nx \l__spath_tmpe_tl { - {\tl_head:N \l__spath_shorten_path_tl} + {\tl_head:N \l__spath_tmpa_tl} } - \tl_set:Nx \l__spath_shorten_path_tl {\tl_tail:N \l__spath_shorten_path_tl} - \tl_put_right:Nx \l__spath_shorten_last_tl + \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} + \tl_put_right:Nx \l__spath_tmpe_tl { - \tl_head:N \l__spath_shorten_path_tl + \tl_head:N \l__spath_tmpa_tl } - \tl_set:Nx \l__spath_shorten_path_tl {\tl_tail:N \l__spath_shorten_path_tl} + \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} } - \tl_put_right:Nx \l__spath_shorten_last_tl + \tl_put_right:Nx \l__spath_tmpe_tl { - {\tl_item:Nn \l__spath_shorten_path_tl {1}} - {\tl_item:Nn \l__spath_shorten_path_tl {2}} + {\tl_item:Nn \l__spath_tmpa_tl {1}} + {\tl_item:Nn \l__spath_tmpa_tl {2}} } - \tl_put_right:NV \l__spath_shorten_last_tl \c_spath_moveto_tl + \tl_put_right:NV \l__spath_tmpe_tl \c_spath_moveto_tl - \tl_reverse:N \l__spath_shorten_path_tl + \tl_reverse:N \l__spath_tmpa_tl - \fp_set:Nn \l__spath_shorten_x_fp + \fp_set:Nn \l__spath_tmpa_fp { - \dim_to_fp:n {\tl_item:Nn \l__spath_shorten_last_tl {4}} + \dim_to_fp:n {\tl_item:Nn \l__spath_tmpe_tl {4}} - - \dim_to_fp:n {\tl_item:Nn \l__spath_shorten_last_tl {1}} + \dim_to_fp:n {\tl_item:Nn \l__spath_tmpe_tl {1}} } - \fp_set:Nn \l__spath_shorten_y_fp + \fp_set:Nn \l__spath_tmpb_fp { - \dim_to_fp:n {\tl_item:Nn \l__spath_shorten_last_tl {5}} + \dim_to_fp:n {\tl_item:Nn \l__spath_tmpe_tl {5}} - - \dim_to_fp:n {\tl_item:Nn \l__spath_shorten_last_tl {2}} + \dim_to_fp:n {\tl_item:Nn \l__spath_tmpe_tl {2}} } - \fp_set:Nn \l__spath_shorten_len_fp + \fp_set:Nn \l__spath_tmpc_fp { - sqrt( \l__spath_shorten_x_fp * \l__spath_shorten_x_fp + \l__spath_shorten_y_fp * \l__spath_shorten_y_fp ) + sqrt( + \l__spath_tmpa_fp * \l__spath_tmpa_fp + + + \l__spath_tmpb_fp * \l__spath_tmpb_fp + ) * \l__spath_tmpa_int } \fp_compare:nTF { - \l__spath_shorten_len_fp > #2 + \l__spath_tmpc_fp > #2 } { - \fp_set:Nn \l__spath_shorten_len_fp + \fp_set:Nn \l__spath_tmpc_fp { - (\l__spath_shorten_len_fp - #2)/ \l__spath_shorten_len_fp + (\l__spath_tmpc_fp - #2)/ \l__spath_tmpc_fp } - \tl_reverse:N \l__spath_shorten_last_tl + \tl_reverse:N \l__spath_tmpe_tl - \tl_if_eq:NNTF \l__spath_shorten_fa_tl \c_spath_curveto_tl + \tl_if_eq:NNTF \l__spath_tmpb_tl \c_spath_curveto_tl { - \fp_set:Nn \l__spath_shorten_len_fp - { - 1 - (1 -\l__spath_shorten_len_fp)/3 - } \spath_split_curve:NNVV - \l__spath_shorten_lasta_tl - \l__spath_shorten_lastb_tl - \l__spath_shorten_last_tl - \l__spath_shorten_len_fp + \l__spath_tmpc_tl + \l__spath_tmpd_tl + \l__spath_tmpe_tl + \l__spath_tmpc_fp } { \spath_split_line:NNVV - \l__spath_shorten_lasta_tl - \l__spath_shorten_lastb_tl - \l__spath_shorten_last_tl - \l__spath_shorten_len_fp + \l__spath_tmpc_tl + \l__spath_tmpd_tl + \l__spath_tmpe_tl + \l__spath_tmpc_fp } \prg_replicate:nn {3} { - \tl_set:Nx \l__spath_shorten_lasta_tl {\tl_tail:N \l__spath_shorten_lasta_tl} + \tl_set:Nx \l__spath_tmpc_tl {\tl_tail:N \l__spath_tmpc_tl} } - \tl_put_right:NV \l__spath_shorten_path_tl \l__spath_shorten_lasta_tl + \tl_put_right:NV \l__spath_tmpa_tl \l__spath_tmpc_tl } { \int_compare:nT { - \tl_count:N \l__spath_shorten_path_tl > 3 + \tl_count:N \l__spath_tmpa_tl > 3 } { - \dim_set:Nn \l__spath_tmpa_dim {\fp_to_dim:n {#2 - \l__spath_shorten_len_fp } } - \spath_shorten_at_end:NV \l__spath_shorten_path_tl \l__spath_tmpa_dim + \dim_set:Nn \l__spath_tmpa_dim {\fp_to_dim:n {#2 - \l__spath_tmpc_fp } } + \spath_shorten_at_end:NV \l__spath_tmpa_tl \l__spath_tmpa_dim } } - \tl_gset_eq:NN \g__spath_output_tl \l__spath_shorten_path_tl + \tl_gset_eq:NN \g__spath_output_tl \l__spath_tmpa_tl \group_end: } { @@ -1885,110 +2459,120 @@ manipulating PGF soft paths} } { \group_begin: - \tl_set:Nn \l__spath_shorten_path_tl {#1} + \tl_set:Nn \l__spath_tmpa_tl {#1} - \tl_set:Nx \l__spath_shorten_fa_tl {\tl_item:Nn \l__spath_shorten_path_tl {4}} + \tl_set:Nx \l__spath_tmpb_tl {\tl_item:Nn \l__spath_tmpa_tl {4}} - \tl_clear:N \l__spath_shorten_last_tl + \tl_clear:N \l__spath_tmpe_tl - \tl_if_eq:NNTF \l__spath_shorten_fa_tl \c_spath_curvetoa_tl + \tl_if_eq:NNTF \l__spath_tmpb_tl \c_spath_curvetoa_tl { - \int_set:Nn \l__spath_shorten_int {3} + \int_set:Nn \l__spath_tmpa_int {3} } { - \int_set:Nn \l__spath_shorten_int {1} + \int_set:Nn \l__spath_tmpa_int {1} } - \tl_set_eq:NN \l__spath_shorten_last_tl \c_spath_moveto_tl - \tl_set:Nx \l__spath_shorten_path_tl {\tl_tail:N \l__spath_shorten_path_tl } + \tl_set_eq:NN \l__spath_tmpe_tl \c_spath_moveto_tl + \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl } - \prg_replicate:nn { \l__spath_shorten_int } + \prg_replicate:nn { \l__spath_tmpa_int } { - \__spath_tl_put_right_braced:Nx \l__spath_shorten_last_tl {\tl_item:Nn \l__spath_shorten_path_tl {1}} - \__spath_tl_put_right_braced:Nx \l__spath_shorten_last_tl {\tl_item:Nn \l__spath_shorten_path_tl {2}} - \tl_put_right:Nx \l__spath_shorten_last_tl {\tl_item:Nn \l__spath_shorten_path_tl {3}} + \__spath_tl_put_right_braced:Nx + \l__spath_tmpe_tl + {\tl_item:Nn \l__spath_tmpa_tl {1}} + \__spath_tl_put_right_braced:Nx + \l__spath_tmpe_tl + {\tl_item:Nn \l__spath_tmpa_tl {2}} + \tl_put_right:Nx \l__spath_tmpe_tl {\tl_item:Nn \l__spath_tmpa_tl {3}} \prg_replicate:nn {3} { - \tl_set:Nx \l__spath_shorten_path_tl {\tl_tail:N \l__spath_shorten_path_tl } + \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl } } } - \__spath_tl_put_right_braced:Nx \l__spath_shorten_last_tl {\tl_item:Nn \l__spath_shorten_path_tl {1}} - \__spath_tl_put_right_braced:Nx \l__spath_shorten_last_tl {\tl_item:Nn \l__spath_shorten_path_tl {2}} + \__spath_tl_put_right_braced:Nx + \l__spath_tmpe_tl + {\tl_item:Nn \l__spath_tmpa_tl {1}} + \__spath_tl_put_right_braced:Nx + \l__spath_tmpe_tl + {\tl_item:Nn \l__spath_tmpa_tl {2}} - \fp_set:Nn \l__spath_shorten_x_fp + \fp_set:Nn \l__spath_tmpa_fp { - \dim_to_fp:n {\tl_item:Nn \l__spath_shorten_last_tl {5}} + \dim_to_fp:n {\tl_item:Nn \l__spath_tmpe_tl {5}} - - \dim_to_fp:n {\tl_item:Nn \l__spath_shorten_last_tl {2}} + \dim_to_fp:n {\tl_item:Nn \l__spath_tmpe_tl {2}} } - \fp_set:Nn \l__spath_shorten_y_fp + \fp_set:Nn \l__spath_tmpb_fp { - \dim_to_fp:n {\tl_item:Nn \l__spath_shorten_last_tl {6}} + \dim_to_fp:n {\tl_item:Nn \l__spath_tmpe_tl {6}} - - \dim_to_fp:n {\tl_item:Nn \l__spath_shorten_last_tl {3}} + \dim_to_fp:n {\tl_item:Nn \l__spath_tmpe_tl {3}} } - \fp_set:Nn \l__spath_shorten_len_fp + \fp_set:Nn \l__spath_tmpc_fp { - sqrt( \l__spath_shorten_x_fp * \l__spath_shorten_x_fp + \l__spath_shorten_y_fp * \l__spath_shorten_y_fp ) + sqrt( + \l__spath_tmpa_fp * \l__spath_tmpa_fp + + + \l__spath_tmpb_fp * \l__spath_tmpb_fp + ) + * + \l__spath_tmpa_int } \fp_compare:nTF { - \l__spath_shorten_len_fp > #2 + \l__spath_tmpc_fp > #2 } { - \fp_set:Nn \l__spath_shorten_len_fp + \fp_set:Nn \l__spath_tmpc_fp { - #2/ \l__spath_shorten_len_fp + #2/ \l__spath_tmpc_fp } - \tl_if_eq:NNTF \l__spath_shorten_fa_tl \c_spath_curvetoa_tl + \tl_if_eq:NNTF \l__spath_tmpb_tl \c_spath_curvetoa_tl { - \fp_set:Nn \l__spath_shorten_len_fp - { - \l__spath_shorten_len_fp/3 - } \spath_split_curve:NNVV - \l__spath_shorten_lasta_tl - \l__spath_shorten_lastb_tl - \l__spath_shorten_last_tl - \l__spath_shorten_len_fp + \l__spath_tmpc_tl + \l__spath_tmpd_tl + \l__spath_tmpe_tl + \l__spath_tmpc_fp } { \spath_split_line:NNVV - \l__spath_shorten_lasta_tl - \l__spath_shorten_lastb_tl - \l__spath_shorten_last_tl - \l__spath_shorten_len_fp + \l__spath_tmpc_tl + \l__spath_tmpd_tl + \l__spath_tmpe_tl + \l__spath_tmpc_fp } \prg_replicate:nn {2} { - \tl_set:Nx \l__spath_shorten_path_tl {\tl_tail:N \l__spath_shorten_path_tl} + \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} } - \tl_put_left:NV \l__spath_shorten_path_tl \l__spath_shorten_lastb_tl + \tl_put_left:NV \l__spath_tmpa_tl \l__spath_tmpd_tl } { - \tl_put_left:NV \l__spath_shorten_path_tl \c_spath_moveto_tl + \tl_put_left:NV \l__spath_tmpa_tl \c_spath_moveto_tl \int_compare:nT { - \tl_count:N \l__spath_shorten_path_tl > 3 + \tl_count:N \l__spath_tmpa_tl > 3 } { - \dim_set:Nn \l__spath_tmpa_dim {\fp_to_dim:n {#2 - \l__spath_shorten_len_fp } } - \spath_shorten_at_start:NV \l__spath_shorten_path_tl \l__spath_tmpa_dim + \dim_set:Nn \l__spath_tmpa_dim {\fp_to_dim:n {#2 - \l__spath_tmpc_fp } } + \spath_shorten_at_start:NV \l__spath_tmpa_tl \l__spath_tmpa_dim } } - \tl_gset_eq:NN \g__spath_output_tl \l__spath_shorten_path_tl + \tl_gset_eq:NN \g__spath_output_tl \l__spath_tmpa_tl \group_end: } { @@ -2044,7 +2628,9 @@ manipulating PGF soft paths} } { - \tl_set:Nx \l__spath_tmpa_tl {\seq_item:Nn \l__spath_tmpa_seq { \l__spath_tmpa_int} } + \tl_set:Nx + \l__spath_tmpa_tl + {\seq_item:Nn \l__spath_tmpa_seq { \l__spath_tmpa_int} } \int_compare:nTF { @@ -2122,11 +2708,21 @@ manipulating PGF soft paths} { {\fp_to_dim:n { - (1 - \l__spath_tmpa_fp)^3 * \tl_item:Nn \l__spath_tmpa_tl {2} + 3 * (1 - \l__spath_tmpa_fp)^2 * (\l__spath_tmpa_fp) * \tl_item:Nn \l__spath_tmpa_tl {5} + 3 * (1 - \l__spath_tmpa_fp) * (\l__spath_tmpa_fp)^2 * \tl_item:Nn \l__spath_tmpa_tl {8} + (\l__spath_tmpa_fp)^3 * \tl_item:Nn \l__spath_tmpa_tl {11} + (1 - \l__spath_tmpa_fp)^3 * \tl_item:Nn \l__spath_tmpa_tl {2} + + 3 * (1 - \l__spath_tmpa_fp)^2 * (\l__spath_tmpa_fp) + * \tl_item:Nn \l__spath_tmpa_tl {5} + + 3 * (1 - \l__spath_tmpa_fp) * (\l__spath_tmpa_fp)^2 + * \tl_item:Nn \l__spath_tmpa_tl {8} + + (\l__spath_tmpa_fp)^3 * \tl_item:Nn \l__spath_tmpa_tl {11} }} {\fp_to_dim:n { - (1 - \l__spath_tmpa_fp)^3 * \tl_item:Nn \l__spath_tmpa_tl {3} + 3 * (1 - \l__spath_tmpa_fp)^2 * (\l__spath_tmpa_fp) * \tl_item:Nn \l__spath_tmpa_tl {6} + 3 * (1 - \l__spath_tmpa_fp) * (\l__spath_tmpa_fp)^2 * \tl_item:Nn \l__spath_tmpa_tl {9} + (\l__spath_tmpa_fp)^3 * \tl_item:Nn \l__spath_tmpa_tl {12} + (1 - \l__spath_tmpa_fp)^3 * \tl_item:Nn \l__spath_tmpa_tl {3} + + 3 * (1 - \l__spath_tmpa_fp)^2 * (\l__spath_tmpa_fp) + * \tl_item:Nn \l__spath_tmpa_tl {6} + + 3 * (1 - \l__spath_tmpa_fp) * (\l__spath_tmpa_fp)^2 + * \tl_item:Nn \l__spath_tmpa_tl {9} + + (\l__spath_tmpa_fp)^3 * \tl_item:Nn \l__spath_tmpa_tl {12} }} } } @@ -2177,7 +2773,9 @@ manipulating PGF soft paths} } { - \tl_set:Nx \l__spath_tmpa_tl {\seq_item:Nn \l__spath_tmpa_seq { \l__spath_tmpa_int} } + \tl_set:Nx + \l__spath_tmpa_tl + {\seq_item:Nn \l__spath_tmpa_seq { \l__spath_tmpa_int} } \int_compare:nTF { @@ -2255,16 +2853,24 @@ manipulating PGF soft paths} { {\fp_to_dim:n { - 3*(1 - \l__spath_tmpa_fp)^2 * (\tl_item:Nn \l__spath_tmpa_tl {5} - \tl_item:Nn \l__spath_tmpa_tl {2}) - + 6 * (1 - \l__spath_tmpa_fp) * (\l__spath_tmpa_fp) * (\tl_item:Nn \l__spath_tmpa_tl {8} - \tl_item:Nn \l__spath_tmpa_tl {5}) - + 3*(\l__spath_tmpa_fp)^2 * (\tl_item:Nn \l__spath_tmpa_tl {11} - \tl_item:Nn \l__spath_tmpa_tl {8}) + 3*(1 - \l__spath_tmpa_fp)^2 * (\tl_item:Nn \l__spath_tmpa_tl {5} + - \tl_item:Nn \l__spath_tmpa_tl {2}) + + 6 * (1 - \l__spath_tmpa_fp) * (\l__spath_tmpa_fp) * + (\tl_item:Nn \l__spath_tmpa_tl {8} + - \tl_item:Nn \l__spath_tmpa_tl {5}) + + 3*(\l__spath_tmpa_fp)^2 * (\tl_item:Nn \l__spath_tmpa_tl {11} + - \tl_item:Nn \l__spath_tmpa_tl {8}) } } {\fp_to_dim:n { - 3*(1 - \l__spath_tmpa_fp)^2 * (\tl_item:Nn \l__spath_tmpa_tl {6} - \tl_item:Nn \l__spath_tmpa_tl {3}) - + 6 * (1 - \l__spath_tmpa_fp) * (\l__spath_tmpa_fp) * (\tl_item:Nn \l__spath_tmpa_tl {9} - \tl_item:Nn \l__spath_tmpa_tl {6}) - + 3*(\l__spath_tmpa_fp)^2 * (\tl_item:Nn \l__spath_tmpa_tl {12} - \tl_item:Nn \l__spath_tmpa_tl {9}) + 3*(1 - \l__spath_tmpa_fp)^2 * (\tl_item:Nn \l__spath_tmpa_tl {6} + - \tl_item:Nn \l__spath_tmpa_tl {3}) + + 6 * (1 - \l__spath_tmpa_fp) * (\l__spath_tmpa_fp) * + (\tl_item:Nn \l__spath_tmpa_tl {9} + - \tl_item:Nn \l__spath_tmpa_tl {6}) + + 3*(\l__spath_tmpa_fp)^2 * (\tl_item:Nn \l__spath_tmpa_tl {12} + - \tl_item:Nn \l__spath_tmpa_tl {9}) }} } } @@ -2296,15 +2902,24 @@ manipulating PGF soft paths} \tl_clear:N \l__spath_tmpa_tl \__spath_tangent_at:nn {#1}{#2} \tl_set_eq:NN \l__spath_tmpb_tl \g__spath_output_tl - \fp_set:Nn \l__spath_tmpa_fp { sqrt( (\tl_item:Nn \l__spath_tmpb_tl {1})^2 + (\tl_item:Nn \l__spath_tmpb_tl {2})^2 ) } + \fp_set:Nn \l__spath_tmpa_fp + { + sqrt( + (\tl_item:Nn \l__spath_tmpb_tl {1})^2 + + + (\tl_item:Nn \l__spath_tmpb_tl {2})^2 + ) + } \fp_compare:nTF {\l__spath_tmpa_fp = 0} { \fp_set:Nn \l__spath_tmpa_fp {1} \fp_set:Nn \l__spath_tmpb_fp {0} } { - \fp_set:Nn \l__spath_tmpb_fp { (\tl_item:Nn \l__spath_tmpb_tl {2}) / \l__spath_tmpa_fp } - \fp_set:Nn \l__spath_tmpa_fp { (\tl_item:Nn \l__spath_tmpb_tl {1}) / \l__spath_tmpa_fp } + \fp_set:Nn \l__spath_tmpb_fp + { (\tl_item:Nn \l__spath_tmpb_tl {2}) / \l__spath_tmpa_fp } + \fp_set:Nn \l__spath_tmpa_fp + { (\tl_item:Nn \l__spath_tmpb_tl {1}) / \l__spath_tmpa_fp } } \tl_set:Nx \l__spath_tmpa_tl { @@ -2332,22 +2947,6 @@ manipulating PGF soft paths} \tl_gclear:N \g__spath_output_tl } \cs_generate_variant:Nn \spath_gtransformation_at:Nnn {NVn, NVV, NnV} -\tl_new:N \l__spath_split_path_a_tl -\tl_new:N \l__spath_split_path_b_tl -\tl_new:N \l__spath_split_path_a_start_tl -\tl_new:N \l__spath_split_path_b_start_tl -\tl_new:N \l__spath_split_path_a_end_tl -\tl_new:N \l__spath_split_path_b_end_tl -\tl_new:N \l__spath_split_path_a_final_tl -\tl_new:N \l__spath_split_path_b_final_tl - -\tl_new:N \l__spath_split_prev_first_tl -\tl_new:N \l__spath_split_prev_second_tl - -\seq_new:N \l__spath_split_first_seq -\seq_new:N \l__spath_split_second_seq - -\int_new:N \l__spath_split_segment_int \cs_new_protected_nopar:Npn \spath_intersect:NN #1#2 { \pgfintersectionofpaths% @@ -2357,152 +2956,199 @@ manipulating PGF soft paths} \pgfsetpath #2 } } -\tl_new:N \l__spath_intersecta_tl -\tl_new:N \l__spath_intersectb_tl \cs_new_protected_nopar:Npn \spath_intersect:nn #1#2 { \tl_set:Nn \l__spath_intersecta_tl {#1} \tl_set:Nn \l__spath_intersectb_tl {#2} \spath_intersect:NN \l__spath_intersecta_tl \l__spath_intersectb_tl } -\cs_new_protected_nopar:Npn \__spath_split_at_intersections:nn #1#2 +\cs_new_protected_nopar:Npn \__spath_split_component_at_intersections:nn #1#2 { \group_begin: + \tl_clear:N \l__spath_tmpe_tl + \seq_clear:N \l__spath_tmpb_seq - % Clear some token lists and sequences - \tl_clear:N \l__spath_split_path_a_final_tl - \tl_clear:N \l__spath_split_path_b_final_tl - \seq_clear:N \l__spath_split_first_seq - \seq_clear:N \l__spath_split_second_seq - - \pgfintersectionsortbyfirstpath % Find the intersections of these segments - \tl_set:Nn \l__spath_split_path_a_tl {#1} - \tl_set:Nn \l__spath_split_path_b_tl {#2} - % Remove empty components + \tl_set:Nn \l__spath_tmpb_tl {#1} + \tl_set:Nn \l__spath_tmpc_tl {#2} - \spath_intersect:NN \l__spath_split_path_a_tl \l__spath_split_path_b_tl + \spath_reallength:Nn \l__spath_tmpa_int {#1} - % If we get intersections - \int_compare:nT {\pgfintersectionsolutions > 0} + % Remember if the component is closed + \spath_finalaction:NV \l__spath_tmpa_tl \l__spath_tmpb_tl + + \bool_set:Nn \l__spath_closed_bool { - % Find the times of the intersections on each path - \int_step_inline:nnnn {1} {1} {\pgfintersectionsolutions} - { - \pgfintersectiongetsolutiontimes{##1}{\l__spath_split_first_tl}{\l__spath_split_second_tl} - \seq_put_left:NV \l__spath_split_first_seq \l__spath_split_first_tl - } + \tl_if_eq_p:NN \l__spath_tmpa_tl \c_spath_closepath_tl } - \spath_intersect:NN \l__spath_split_path_b_tl \l__spath_split_path_a_tl + % Open it + \spath_open:N \l__spath_tmpb_tl + + % Sort intersections along the component + \pgfintersectionsortbyfirstpath + \spath_intersect:NN \l__spath_tmpb_tl \l__spath_tmpc_tl % If we get intersections \int_compare:nT {\pgfintersectionsolutions > 0} { - % Find the times of the intersections on each path + % Find the times of the intersections on the component \int_step_inline:nnnn {1} {1} {\pgfintersectionsolutions} { - \pgfintersectiongetsolutiontimes{##1}{\l__spath_split_first_tl}{\l__spath_split_second_tl} - \seq_put_left:NV \l__spath_split_second_seq \l__spath_split_first_tl + \pgfintersectiongetsolutiontimes{##1}{\l__spath_tmph_tl}{\l__spath_tmpi_tl} + \seq_put_left:NV \l__spath_tmpb_seq \l__spath_tmph_tl } - } - - \tl_set:Nn \l__spath_split_prev_first_tl {-1} - - \seq_map_inline:Nn \l__spath_split_first_seq - { - \tl_set:Nn \l__spath_split_first_tl {##1} - \tl_set_eq:NN \l__spath_tmpa_tl \l__spath_split_first_tl - \int_compare:nT + \seq_get_left:NN \l__spath_tmpb_seq \l__spath_tmpa_tl + \fp_compare:nT { - \fp_to_int:n {floor( \l__spath_split_first_tl) } - = - \fp_to_int:n {floor( \l__spath_split_prev_first_tl) } + \l__spath_tmpa_tl > \l__spath_tmpa_int - .01 } { - \tl_set:Nx \l__spath_split_first_tl - { - \fp_eval:n { - floor( \l__spath_split_first_tl ) - + - ( \l__spath_split_first_tl - floor( \l__spath_split_first_tl) ) - / - ( \l__spath_split_prev_first_tl - floor( \l__spath_split_prev_first_tl) ) - } - } + \bool_set_false:N \l__spath_closed_bool } - \tl_set_eq:NN \l__spath_split_prev_first_tl \l__spath_tmpa_tl - - \spath_split_at:NNVV \l__spath_split_path_a_start_tl \l__spath_split_path_a_end_tl \l__spath_split_path_a_tl \l__spath_split_first_tl - - \tl_put_left:NV \l__spath_split_path_a_final_tl \l__spath_split_path_a_end_tl - \tl_set_eq:NN \l__spath_split_path_a_tl \l__spath_split_path_a_start_tl - - } - - \tl_set:Nn \l__spath_split_prev_second_tl {-1} - - \seq_map_inline:Nn \l__spath_split_second_seq - { - \tl_set:Nn \l__spath_split_second_tl {##1} - - \tl_set_eq:NN \l__spath_tmpa_tl \l__spath_split_second_tl - \int_compare:nT + \seq_get_right:NN \l__spath_tmpb_seq \l__spath_tmpa_tl + \fp_compare:nT { - \fp_to_int:n {floor( \l__spath_split_second_tl) } - = - \fp_to_int:n {floor( \l__spath_split_prev_second_tl) } + \l__spath_tmpa_tl < .01 + } + { + \bool_set_false:N \l__spath_closed_bool } + + \tl_set:Nn \l__spath_tmpg_tl {-1} + + \seq_map_inline:Nn \l__spath_tmpb_seq { - \tl_set:Nx \l__spath_split_second_tl + \tl_set:Nn \l__spath_tmph_tl {##1} + + \tl_set_eq:NN \l__spath_tmpa_tl \l__spath_tmph_tl + \int_compare:nT { - \fp_eval:n { - floor( \l__spath_split_second_tl ) - + - ( \l__spath_split_second_tl - floor( \l__spath_split_second_tl) ) - / - ( \l__spath_split_prev_second_tl - floor( \l__spath_split_prev_second_tl) ) + \fp_to_int:n {floor( \l__spath_tmph_tl) } + = + \fp_to_int:n {floor( \l__spath_tmpg_tl) } + } + { + \tl_set:Nx \l__spath_tmph_tl + { + \fp_eval:n { + floor( \l__spath_tmph_tl ) + + + ( \l__spath_tmph_tl - floor( \l__spath_tmph_tl) ) + / + ( \l__spath_tmpg_tl - floor( \l__spath_tmpg_tl) ) + } } } + \tl_set_eq:NN \l__spath_tmpg_tl \l__spath_tmpa_tl + + \spath_split_at:NNVV + \l__spath_tmpd_tl + \l__spath_tmpf_tl + \l__spath_tmpb_tl + \l__spath_tmph_tl + + \tl_put_left:NV \l__spath_tmpe_tl \l__spath_tmpf_tl + \tl_set_eq:NN \l__spath_tmpb_tl \l__spath_tmpd_tl + } - \tl_set_eq:NN \l__spath_split_prev_second_tl \l__spath_tmpa_tl - \spath_split_at:NNVV \l__spath_split_path_b_start_tl \l__spath_split_path_b_end_tl \l__spath_split_path_b_tl\l__spath_split_second_tl + \tl_put_left:NV \l__spath_tmpe_tl \l__spath_tmpb_tl - \tl_put_left:NV \l__spath_split_path_b_final_tl \l__spath_split_path_b_end_tl - \tl_set_eq:NN \l__spath_split_path_b_tl \l__spath_split_path_b_start_tl + \spath_remove_empty_components:N \l__spath_tmpe_tl + \tl_set_eq:NN \l__spath_tmpb_tl \l__spath_tmpe_tl } - \tl_put_left:NV \l__spath_split_path_a_final_tl \l__spath_split_path_a_tl - \tl_put_left:NV \l__spath_split_path_b_final_tl \l__spath_split_path_b_tl - - \tl_if_empty:NT \l__spath_split_path_a_final_tl + \bool_if:NT \l__spath_closed_bool { - \tl_set_eq:NN \l__spath_split_path_a_final_tl \l__spath_split_path_a_tl + \spath_join_component:Nn \l__spath_tmpb_tl {1} } - \tl_if_empty:NT \l__spath_split_path_b_final_tl + + \tl_gclear:N \g__spath_output_tl + \tl_gset_eq:NN \g__spath_output_tl \l__spath_tmpb_tl + + \group_end: +} +\cs_new_protected_nopar:Npn \spath_split_component_at_intersections:Nnn #1#2#3 +{ + \__spath_split_component_at_intersections:nn {#2}{#3} + \tl_set_eq:NN #1 \g__spath_output_tl + \tl_gclear:N \g__spath_output_tl +} +\cs_generate_variant:Nn \spath_split_component_at_intersections:Nnn {NVn, NVV} +\cs_new_protected_nopar:Npn \spath_split_component_at_intersections:Nn #1#2 +{ + \spath_split_component_at_intersections:NVn #1#1{#2} +} +\cs_generate_variant:Nn \spath_split_component_at_intersections:Nn {cn, cv} +\cs_new_protected_nopar:Npn \spath_gsplit_component_at_intersections:Nnn #1#2#3 +{ + \__spath_split_component_at_intersections:nn {#2}{#3} + \tl_gset_eq:NN #1 \g__spath_output_tl + \tl_gclear:N \g__spath_output_tl +} +\cs_generate_variant:Nn \spath_gsplit_component_at_intersections:Nnn {NVn, NVV} +\cs_new_protected_nopar:Npn \spath_gsplit_component_at_intersections:Nn #1#2 +{ + \spath_gsplit_component_at_intersections:NVn #1#1{#2} +} +\cs_generate_variant:Nn \spath_gsplit_component_at_intersections:Nn {cn, cv} +\cs_new_protected_nopar:Npn \__spath_split_path_at_intersections:nn #1#2 +{ + \group_begin: + + \seq_clear:N \l__spath_tmpa_seq + \seq_clear:N \l__spath_tmpb_seq + + \spath_components_to_seq:Nn \l__spath_tmpa_seq {#1} + \seq_map_inline:Nn \l__spath_tmpa_seq { - \tl_set_eq:NN \l__spath_split_path_b_final_tl \l__spath_split_path_b_tl + \spath_split_component_at_intersections:Nnn \l__spath_tmpa_tl {##1} {#2} + \seq_put_right:NV \l__spath_tmpb_seq \l__spath_tmpa_tl } - \spath_remove_empty_components:N \l__spath_split_path_a_final_tl - \spath_remove_empty_components:N \l__spath_split_path_b_final_tl - \tl_gclear:N \g__spath_output_tl - \__spath_tl_gput_right_braced:NV \g__spath_output_tl \l__spath_split_path_a_final_tl - \__spath_tl_gput_right_braced:NV \g__spath_output_tl \l__spath_split_path_b_final_tl + \tl_gset:Nx \g__spath_output_tl {\seq_use:Nn \l__spath_tmpb_seq {} } \group_end: } +\cs_new_protected_nopar:Npn \spath_split_path_at_intersections:Nnn #1#2#3 +{ + \__spath_split_path_at_intersections:nn {#2}{#3} + \tl_set_eq:NN #1 \g__spath_output_tl + \tl_gclear:N \g__spath_output_tl +} +\cs_generate_variant:Nn \spath_split_path_at_intersections:Nnn +{NVn, NVV, cVn, cVV, cvn, cvv} +\cs_new_protected_nopar:Npn \spath_split_path_at_intersections:Nn #1#2 +{ + \spath_split_path_at_intersections:NVn #1#1{#2} +} +\cs_generate_variant:Nn \spath_split_path_at_intersections:Nn {cv, NV} +\cs_new_protected_nopar:Npn \spath_gsplit_path_at_intersections:Nnn #1#2#3 +{ + \__spath_split_path_at_intersections:nn {#2}{#3} + \tl_gset_eq:NN #1 \g__spath_output_tl + \tl_gclear:N \g__spath_output_tl +} +\cs_generate_variant:Nn \spath_gsplit_path_at_intersections:Nnn +{NVn, NVV, cVn, cVV, cvn, cvv} +\cs_new_protected_nopar:Npn \spath_gsplit_path_at_intersections:Nn #1#2 +{ + \spath_gsplit_path_at_intersections:NVn #1#1{#2} +} +\cs_generate_variant:Nn \spath_gsplit_path_at_intersections:Nn {cv, NV} \cs_new_protected_nopar:Npn \spath_split_at_intersections:NNnn #1#2#3#4 { - \__spath_split_at_intersections:nn {#3}{#4} - \tl_set:Nx #1 {\tl_item:Nn \g__spath_output_tl {1}} - \tl_set:Nx #2 {\tl_item:Nn \g__spath_output_tl {2}} + \__spath_split_path_at_intersections:nn {#3}{#4} + \tl_set_eq:NN #1 \g__spath_output_tl + \__spath_split_path_at_intersections:nn {#4}{#3} + \tl_set_eq:NN #2 \g__spath_output_tl \tl_gclear:N \g__spath_output_tl } -\cs_generate_variant:Nn \spath_split_at_intersections:NNnn {NNVV, ccVV, ccvv} +\cs_generate_variant:Nn \spath_split_at_intersections:NNnn +{NNVn, NNVV, ccVn, ccVV, ccvn, ccvv} \cs_new_protected_nopar:Npn \spath_split_at_intersections:NN #1#2 { \spath_split_at_intersections:NNVV #1#2#1#2 @@ -2510,213 +3156,283 @@ manipulating PGF soft paths} \cs_generate_variant:Nn \spath_split_at_intersections:NN {cc} \cs_new_protected_nopar:Npn \spath_gsplit_at_intersections:NNnn #1#2#3#4 { - \__spath_split_at_intersections:nn {#3}{#4} - \tl_gset:Nx #1 {\tl_item:Nn \g__spath_output_tl {1}} - \tl_gset:Nx #2 {\tl_item:Nn \g__spath_output_tl {2}} + \__spath_split_path_at_intersections:nn {#3}{#4} + \tl_gset_eq:NN #1 \g__spath_output_tl + \__spath_split_path_at_intersections:nn {#4}{#3} + \tl_gset_eq:NN #2 \g__spath_output_tl \tl_gclear:N \g__spath_output_tl } -\cs_generate_variant:Nn \spath_gsplit_at_intersections:NNnn {NNVV, ccVV, ccvv} +\cs_generate_variant:Nn \spath_gsplit_at_intersections:NNnn +{NNVn, NNVV, ccVn, ccVV, ccvn, ccvv} \cs_new_protected_nopar:Npn \spath_gsplit_at_intersections:NN #1#2 { \spath_gsplit_at_intersections:NNVV #1#2#1#2 } \cs_generate_variant:Nn \spath_gsplit_at_intersections:NN {cc} -\cs_new_protected_nopar:Npn \__spath_split_at_self_intersections:n #1 +\cs_new_protected_nopar:Npn \__spath_split_component_at_self_intersections:n #1 { \group_begin: + \tl_set:Nn \l__spath_tmpe_tl {#1} + + % Remember if the component is closed + \spath_finalaction:NV \l__spath_tmpa_tl \l__spath_tmpe_tl + + \bool_set:Nn \l__spath_closed_bool + { + \tl_if_eq_p:NN \l__spath_tmpa_tl \c_spath_closepath_tl + } % Copy the path - \tl_set:Nn \l__spath_split_path_b_tl {#1} + \tl_set:Nn \l__spath_tmpe_tl {#1} % Open the path - \spath_open:N \l__spath_split_path_b_tl - % Remove empty components - \spath_remove_empty_components:N \l__spath_split_path_b_tl + \spath_open:N \l__spath_tmpe_tl + % Ensure beziers don't self-intersect + \spath_split_curves:N \l__spath_tmpe_tl + % Make a copy for later - \tl_set_eq:NN \l__spath_split_path_b_final_tl \l__spath_split_path_b_tl + \tl_set_eq:NN \l__spath_tmpg_tl \l__spath_tmpe_tl % Clear some token lists and sequences - \tl_clear:N \l__spath_split_path_a_tl - \seq_clear:N \l__spath_split_first_seq - \int_zero:N \l__spath_split_segment_int + \tl_clear:N \l__spath_tmpd_tl + \seq_clear:N \l__spath_tmpb_seq + \int_zero:N \l__spath_tmpa_int \pgfintersectionsortbyfirstpath - \bool_do_until:nn - { - \int_compare_p:n - { - \tl_count:N \l__spath_split_path_b_tl < 4 - } - } - { - \tl_clear:N \l__spath_split_path_a_tl - \tl_put_right:Nx \l__spath_split_path_a_tl - { - \tl_item:Nn \l__spath_split_path_b_tl {1} - {\tl_item:Nn \l__spath_split_path_b_tl {2}} - {\tl_item:Nn \l__spath_split_path_b_tl {3}} - } - - \tl_set:Nx \l__spath_tmpa_tl { \tl_item:Nn \l__spath_split_path_b_tl {4} } - - \tl_set:Nx \l__spath_split_path_b_tl {\tl_tail:N \l__spath_split_path_b_tl} - - \int_zero:N \l__spath_tmpa_int + % Split the path into a sequence of segments + \spath_segments_to_seq:NV \l__spath_tmpa_seq \l__spath_tmpe_tl - \tl_case:Nn \l__spath_tmpa_tl + \seq_map_indexed_inline:Nn \l__spath_tmpa_seq + { + \seq_map_indexed_inline:Nn \l__spath_tmpa_seq { - \c_spath_moveto_tl - { - \tl_clear:N \l__spath_split_path_a_tl - \tl_set:Nx \l__spath_split_path_b_tl {\tl_tail:N \l__spath_split_path_b_tl} - \tl_set:Nx \l__spath_split_path_b_tl {\tl_tail:N \l__spath_split_path_b_tl} - \tl_set:Nx \l__spath_split_path_b_tl {\tl_tail:N \l__spath_split_path_b_tl} - } - \c_spath_lineto_tl + % Don't intersect a segment with itself + \int_compare:nF { - \int_set:Nn \l__spath_tmpa_int {1} + ##1 == ####1 } - \c_spath_curvetoa_tl { - \int_set:Nn \l__spath_tmpa_int {3} - } - } - - \prg_replicate:nn { \l__spath_tmpa_int } - { - \tl_set:Nx \l__spath_split_path_b_tl {\tl_tail:N \l__spath_split_path_b_tl} - \tl_set:Nx \l__spath_split_path_b_tl {\tl_tail:N \l__spath_split_path_b_tl} - - \tl_put_right:Nx \l__spath_split_path_a_tl - { - \tl_item:Nn \l__spath_split_path_b_tl {1} - {\tl_item:Nn \l__spath_split_path_b_tl {2}} - {\tl_item:Nn \l__spath_split_path_b_tl {3}} - } + \spath_intersect:nn {##2} {####2} - \tl_set:Nx \l__spath_split_path_b_tl {\tl_tail:N \l__spath_split_path_b_tl} - } - - \tl_put_left:NV \l__spath_split_path_b_tl \c_spath_moveto_tl - - \tl_if_empty:NF \l__spath_split_path_a_tl - { - % Intersect the current segment with the rest of the path - \spath_intersect:NN \l__spath_split_path_a_tl \l__spath_split_path_b_tl - - % If we get intersections - \int_compare:nT {\pgfintersectionsolutions > 0} - { - % Find the times of the intersections on each path - \int_step_inline:nnnn {1} {1} {\pgfintersectionsolutions} + \int_compare:nT {\pgfintersectionsolutions > 0} { - \pgfintersectiongetsolutiontimes{##1}{\l__spath_split_first_tl}{\l__spath_split_second_tl} - \fp_compare:nT + % Find the times of the intersections on each path + \int_step_inline:nnnn {1} {1} {\pgfintersectionsolutions} { - \l__spath_split_first_tl < .99 - } - { - \tl_set:Nx \l__spath_tmpa_tl {\fp_to_decimal:n {\l__spath_split_first_tl + \l__spath_split_segment_int}} - \seq_put_right:NV \l__spath_split_first_seq \l__spath_tmpa_tl - } - } - } - - \spath_intersect:NN \l__spath_split_path_b_tl \l__spath_split_path_a_tl + \pgfintersectiongetsolutiontimes + {########1}{\l__spath_tmpb_tl}{\l__spath_tmpc_tl} - % If we get intersections - \int_compare:nT {\pgfintersectionsolutions > 0} - { - % Find the times of the intersections on each path - \int_step_inline:nnnn {1} {1} {\pgfintersectionsolutions} - { - \pgfintersectiongetsolutiontimes{##1}{\l__spath_split_first_tl}{\l__spath_split_second_tl} - \fp_compare:nT - { - \l__spath_split_first_tl > .01 - } - { - \tl_set:Nx \l__spath_tmpa_tl {\fp_to_decimal:n {\l__spath_split_first_tl + \l__spath_split_segment_int + 1}} - \seq_put_right:NV \l__spath_split_first_seq \l__spath_tmpa_tl + \bool_if:nT + { + !( + \fp_compare_p:n { \l__spath_tmpb_tl > .99 } + && + \int_compare_p:n {##1 + 1 == ####1} + ) + && + !( + \fp_compare_p:n { \l__spath_tmpb_tl < .01 } + && + \int_compare_p:n {##1 - 1 == ####1} + ) + && + !( + \l__spath_closed_bool + && + \fp_compare_p:n { \l__spath_tmpb_tl < .01 } + && + \int_compare_p:n {##1 == 1} + && + \int_compare_p:n {\seq_count:N \l__spath_tmpa_seq == ####1} + ) + && + !( + \l__spath_closed_bool + && + \fp_compare_p:n { \l__spath_tmpb_tl > .99 } + && + \int_compare_p:n {####1 == 1} + && + \int_compare_p:n {\seq_count:N \l__spath_tmpa_seq == ##1} + ) + } + { + \tl_set:Nx \l__spath_tmpa_tl + {\fp_to_decimal:n {\l__spath_tmpb_tl + ##1 - 1}} + \seq_put_right:NV \l__spath_tmpb_seq \l__spath_tmpa_tl + } } } } - } - % Increment the segment counter - \int_incr:N \l__spath_split_segment_int } % Sort the sequence by reverse order along the path - \seq_sort:Nn \l__spath_split_first_seq + \seq_sort:Nn \l__spath_tmpb_seq { \fp_compare:nNnTF { ##1 } < { ##2 } { \sort_return_swapped: } { \sort_return_same: } } + \seq_get_left:NN \l__spath_tmpb_seq \l__spath_tmpa_tl + \fp_compare:nT + { + \l__spath_tmpa_tl > \seq_count:N \l__spath_tmpa_seq - .01 + } + { + \bool_set_false:N \l__spath_closed_bool + } + \seq_get_right:NN \l__spath_tmpb_seq \l__spath_tmpa_tl + \fp_compare:nT + { + \l__spath_tmpa_tl < .01 + } + { + \bool_set_false:N \l__spath_closed_bool + } + % Restore the original copy of the path - \tl_set_eq:NN \l__spath_split_path_b_tl \l__spath_split_path_b_final_tl + \tl_set_eq:NN \l__spath_tmpe_tl \l__spath_tmpg_tl % Clear the token lists - \tl_clear:N \l__spath_split_path_b_start_tl - \tl_clear:N \l__spath_split_path_b_end_tl - \tl_clear:N \l__spath_split_path_b_final_tl + \tl_clear:N \l__spath_tmpf_tl + \tl_clear:N \l__spath_tmph_tl + \tl_clear:N \l__spath_tmpg_tl - \tl_set:Nn \l__spath_split_prev_first_tl {-1} + \tl_set:Nn \l__spath_tmpi_tl {-1} - \seq_map_inline:Nn \l__spath_split_first_seq + \seq_map_inline:Nn \l__spath_tmpb_seq { - \tl_set:Nn \l__spath_split_first_tl {##1} - \tl_set_eq:NN \l__spath_tmpa_tl \l__spath_split_first_tl + \tl_set:Nn \l__spath_tmpb_tl {##1} + \tl_set_eq:NN \l__spath_tmpa_tl \l__spath_tmpb_tl \int_compare:nT { - \fp_to_int:n {floor( \l__spath_split_first_tl ) } + \fp_to_int:n {floor( \l__spath_tmpb_tl ) } = - \fp_to_int:n {floor( \l__spath_split_prev_first_tl) } + \fp_to_int:n {floor( \l__spath_tmpi_tl) } } { - \tl_set:Nx \l__spath_split_first_tl + \tl_set:Nx \l__spath_tmpb_tl { \fp_eval:n { - floor( \l__spath_split_first_tl ) + floor( \l__spath_tmpb_tl ) + - ( \l__spath_split_first_tl - floor( \l__spath_split_first_tl) ) + ( \l__spath_tmpb_tl - floor( \l__spath_tmpb_tl) ) / - ( \l__spath_split_prev_first_tl - floor( \l__spath_split_prev_first_tl) ) + ( \l__spath_tmpi_tl - floor( \l__spath_tmpi_tl) ) } } } - \tl_set_eq:NN \l__spath_split_prev_first_tl \l__spath_tmpa_tl + \tl_set_eq:NN \l__spath_tmpi_tl \l__spath_tmpa_tl - \spath_split_at:NNVV \l__spath_split_path_b_start_tl \l__spath_split_path_b_end_tl \l__spath_split_path_b_tl \l__spath_split_first_tl + \spath_split_at:NNVV + \l__spath_tmpf_tl + \l__spath_tmph_tl + \l__spath_tmpe_tl + \l__spath_tmpb_tl - \tl_put_left:NV \l__spath_split_path_b_final_tl \l__spath_split_path_b_end_tl - \tl_set_eq:NN \l__spath_split_path_b_tl \l__spath_split_path_b_start_tl + \tl_put_left:NV \l__spath_tmpg_tl \l__spath_tmph_tl + \tl_set_eq:NN \l__spath_tmpe_tl \l__spath_tmpf_tl } - \tl_put_left:NV \l__spath_split_path_b_final_tl \l__spath_split_path_b_tl + \tl_put_left:NV \l__spath_tmpg_tl \l__spath_tmpe_tl - \tl_if_empty:NT \l__spath_split_path_b_final_tl + \tl_if_empty:NT \l__spath_tmpg_tl { - \tl_set_eq:NN \l__spath_split_path_b_final_tl \l__spath_split_path_b_tl + \tl_set_eq:NN \l__spath_tmpg_tl \l__spath_tmpe_tl } - \spath_remove_empty_components:N \l__spath_split_path_b_final_tl + \spath_remove_empty_components:N \l__spath_tmpg_tl + + % Do something with closed + \bool_if:NT \l__spath_closed_bool + { + \spath_join_component:Nn \l__spath_tmpg_tl {1} + } \tl_gclear:N \g__spath_output_tl - \tl_gset_eq:NN \g__spath_output_tl \l__spath_split_path_b_final_tl + \tl_gset_eq:NN \g__spath_output_tl \l__spath_tmpg_tl \group_end: } +\cs_new_protected_nopar:Npn \spath_split_component_at_self_intersections:Nn #1#2 +{ + \__spath_split_component_at_self_intersections:n {#2} + \tl_set_eq:NN #1 \g__spath_output_tl + \tl_gclear:N \g__spath_output_tl +} +\cs_generate_variant:Nn \spath_split_component_at_self_intersections:Nn {NV} +\cs_new_protected_nopar:Npn \spath_split_component_at_self_intersections:N #1 +{ + \spath_split_component_at_self_intersections:NV #1#1 +} +\cs_generate_variant:Nn \spath_split_component_at_self_intersections:N {c} +\cs_new_protected_nopar:Npn \spath_gsplit_component_at_self_intersections:Nn #1#2 +{ + \__spath_split_component_at_self_intersections:n {#2} + \tl_gset_eq:NN #1 \g__spath_output_tl + \tl_gclear:N \g__spath_output_tl +} +\cs_generate_variant:Nn \spath_gsplit_component_at_self_intersections:Nn {NV} +\cs_new_protected_nopar:Npn \spath_gsplit_component_at_self_intersections:N #1 +{ + \spath_gsplit_component_at_self_intersections:NV #1#1 +} +\cs_generate_variant:Nn \spath_gsplit_component_at_self_intersections:N {c} +\cs_new_protected_nopar:Npn \__spath_split_at_self_intersections:n #1 +{ + \group_begin: + \spath_components_to_seq:Nn \l__spath_tmpa_seq {#1} + \seq_clear:N \l__spath_tmpb_seq + \seq_clear:N \l__spath_tmpc_seq + + % Iterate over the components of the original path. + \bool_do_until:nn + { + \seq_if_empty_p:N \l__spath_tmpa_seq + } + { + % Get the next component + \seq_pop_left:NN \l__spath_tmpa_seq \l__spath_tmpa_tl + % Copy for later + \tl_set_eq:NN \l__spath_tmpc_tl \l__spath_tmpa_tl + \int_compare:nT + { + \tl_count:N \l__spath_tmpa_tl > 3 + } + { + + % Split against itself + \spath_split_component_at_self_intersections:N \l__spath_tmpa_tl + % Grab the rest of the path + \tl_set:Nx \l__spath_tmpb_tl + { + \seq_use:Nn \l__spath_tmpb_seq {} + \seq_use:Nn \l__spath_tmpa_seq {} + } + % Split against the rest of the path + \spath_split_path_at_intersections:NV \l__spath_tmpa_tl \l__spath_tmpb_tl + } + % Save the split path + \seq_put_right:NV \l__spath_tmpc_seq \l__spath_tmpa_tl + % Add the original copy to the sequence of processed components + \seq_put_right:NV \l__spath_tmpb_seq \l__spath_tmpc_tl + } + + \tl_gclear:N \g__spath_output_tl + \tl_gset:Nx \g__spath_output_tl {\seq_use:Nn \l__spath_tmpc_seq {} } + \group_end: +} +\cs_generate_variant:Nn \__spath_split_at_self_intersections:n {V, v} \cs_new_protected_nopar:Npn \spath_split_at_self_intersections:Nn #1#2 { \__spath_split_at_self_intersections:n {#2} \tl_set_eq:NN #1 \g__spath_output_tl \tl_gclear:N \g__spath_output_tl } -\cs_generate_variant:Nn \spath_split_at_self_intersections:Nn {NV} +\cs_generate_variant:Nn \spath_split_at_self_intersections:Nn {NV, cn, cV, cv} \cs_new_protected_nopar:Npn \spath_split_at_self_intersections:N #1 { \spath_split_at_self_intersections:NV #1#1 @@ -2728,64 +3444,82 @@ manipulating PGF soft paths} \tl_gset_eq:NN #1 \g__spath_output_tl \tl_gclear:N \g__spath_output_tl } -\cs_generate_variant:Nn \spath_gsplit_at_self_intersections:Nn {NV} +\cs_generate_variant:Nn \spath_gsplit_at_self_intersections:Nn {NV, cn, cV, cv} \cs_new_protected_nopar:Npn \spath_gsplit_at_self_intersections:N #1 { \spath_gsplit_at_self_intersections:NV #1#1 } \cs_generate_variant:Nn \spath_gsplit_at_self_intersections:N {c} -\tl_new:N \l__spath_tmpj_tl \cs_new_protected_nopar:Npn \__spath_join_component:nn #1#2 { \group_begin: - \spath_components_to_seq:Nn \l__spath_tmpa_seq {#1} - \int_compare:nT + \spath_numberofcomponents:Nn \l__spath_tmpa_int {#1} + + \bool_if:nTF { - #2 == 1 + \int_compare_p:n { #2 >= 1 } + && + \int_compare_p:n { #2 <= \l__spath_tmpa_int } } { - \tl_clear:N \l__spath_tmpj_tl - \seq_pop_left:NN \l__spath_tmpa_seq \l__spath_tmpj_tl - - \prg_replicate:nn {3} + \int_compare:nTF { - \tl_set:Nx \l__spath_tmpj_tl {\tl_tail:N \l__spath_tmpj_tl} + #2 == 1 } - - \seq_put_right:NV \l__spath_tmpb_seq \l__spath_tmpj_tl - } - \bool_if:nT - { - \int_compare_p:n { - #2 > 1 + \int_compare:nTF + { + \l__spath_tmpa_int == 1 + } + { + \tl_set:Nn \l__spath_tmpa_tl {#1} + \spath_initialpoint:Nn \l__spath_tmpb_tl {#1} + \tl_put_right:NV \l__spath_tmpa_tl \c_spath_closepath_tl + \tl_put_right:NV \l__spath_tmpa_tl \l__spath_tmpb_tl + \tl_gclear:N \g__spath_output_tl + \tl_gset_eq:NN \g__spath_output_tl \l__spath_tmpa_tl + } + { + \spath_components_to_seq:Nn \l__spath_tmpa_seq {#1} + \seq_pop_left:NN \l__spath_tmpa_seq \l__spath_tmpa_tl + + \prg_replicate:nn {3} + { + \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} + } + + \seq_put_right:NV \l__spath_tmpa_seq \l__spath_tmpa_tl + + \tl_gclear:N \g__spath_output_tl + \tl_gset:Nx \g__spath_output_tl {\seq_use:Nn \l__spath_tmpa_seq {}} + } } - && - \int_compare_p:n { - #2 <= \seq_count:N \l__spath_tmpa_seq - } - } - { + \spath_components_to_seq:Nn \l__spath_tmpa_seq {#1} - \seq_clear:N \l__spath_tmpb_seq - \seq_map_indexed_inline:Nn \l__spath_tmpa_seq - { - \tl_set:Nn \l__spath_tmpj_tl {##2} - \int_compare:nT {##1 = #2} + \seq_clear:N \l__spath_tmpb_seq + \seq_map_indexed_inline:Nn \l__spath_tmpa_seq { - \prg_replicate:nn {3} + \tl_set:Nn \l__spath_tmpa_tl {##2} + \int_compare:nT {##1 = #2} { - \tl_set:Nx \l__spath_tmpj_tl {\tl_tail:N \l__spath_tmpj_tl} + \prg_replicate:nn {3} + { + \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} + } } + \seq_put_right:NV \l__spath_tmpb_seq \l__spath_tmpa_tl } - \seq_put_right:NV \l__spath_tmpb_seq \l__spath_tmpj_tl - } - \seq_set_eq:NN \l__spath_tmpa_seq \l__spath_tmpb_seq + \tl_gclear:N \g__spath_output_tl + \tl_gset:Nx \g__spath_output_tl {\seq_use:Nn \l__spath_tmpb_seq {}} + } + } + { + \tl_gclear:N \g__spath_output_tl + \tl_gset:Nn \g__spath_output_tl {#1} } - \tl_gset:Nx \g__spath_output_tl {\seq_use:Nn \l__spath_tmpa_seq {} } \group_end: } \cs_new_protected_nopar:Npn \spath_join_component:Nnn #1#2#3 @@ -2832,12 +3566,16 @@ manipulating PGF soft paths} { \dim_compare_p:n { - \dim_abs:n {\l__spath_move_x_dim - \tl_item:Nn \l__spath_tmpa_tl {2} } < 0.01pt + \dim_abs:n + {\l__spath_move_x_dim - \tl_item:Nn \l__spath_tmpa_tl {2} } + < 0.01pt } && \dim_compare_p:n { - \dim_abs:n {\l__spath_move_y_dim - \tl_item:Nn \l__spath_tmpa_tl {3} } < 0.01pt + \dim_abs:n + {\l__spath_move_y_dim - \tl_item:Nn \l__spath_tmpa_tl {3} } + < 0.01pt } } { @@ -2864,12 +3602,22 @@ manipulating PGF soft paths} { \dim_compare_p:n { - \dim_abs:n {\tl_item:Nn \l__spath_tmpa_tl {1} - \tl_item:Nn \l__spath_tmpb_tl {1} } < 0.01pt + \dim_abs:n + { + \tl_item:Nn \l__spath_tmpa_tl {1} - \tl_item:Nn \l__spath_tmpb_tl {1} + } + < + 0.01pt } && \dim_compare_p:n { - \dim_abs:n {\tl_item:Nn \l__spath_tmpa_tl {2} - \tl_item:Nn \l__spath_tmpb_tl {2} } < 0.01pt + \dim_abs:n + { + \tl_item:Nn \l__spath_tmpa_tl {2} - \tl_item:Nn \l__spath_tmpb_tl {2} + } + < + 0.01pt } } { @@ -2976,7 +3724,7 @@ manipulating PGF soft paths} +%% Copyright (C) 2011-2021 by Andrew Stacey %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License (LPPL), either @@ -720,7 +897,7 @@ %% This work is "maintained" (as per LPPL maintenance status) by %% Andrew Stacey. %% -%% This work consists of the files spath3.dtx +%% This work consists of the files spath3_code.dtx %% calligraphy_doc.tex %% knots_doc.tex %% spath3.tex diff --git a/Master/texmf-dist/tex/latex/spath3/tikzlibraryknots.code.tex b/Master/texmf-dist/tex/latex/spath3/tikzlibraryknots.code.tex index 5872a71fdf3..c6ae085925a 100644 --- a/Master/texmf-dist/tex/latex/spath3/tikzlibraryknots.code.tex +++ b/Master/texmf-dist/tex/latex/spath3/tikzlibraryknots.code.tex @@ -45,6 +45,7 @@ \dim_new:N \l__knot_tmpa_dim \dim_new:N \l__knot_tmpb_dim \dim_new:N \l__knot_tolerance_dim +\dim_new:N \l__knot_redraw_tolerance_dim \dim_new:N \l__knot_clip_bg_radius_dim \dim_new:N \l__knot_clip_draw_radius_dim @@ -247,6 +248,11 @@ { \pgfscope \pgftransformreset + \dim_set:Nn \l__knot_redraw_tolerance_dim {\fp_to_dim:n + { + sqrt(2) * max(\l__knot_clip_bg_radius_dim, \l__knot_clip_draw_radius_dim) + } + } \int_step_function:nnnN {1} {1} {\l__knot_strands_int} \knot_draw_strand:n \bool_if:NF \l__knot_super_draft_bool { @@ -267,13 +273,21 @@ { \tl_set:Nn \l__knot_node_tl { \exp_not:N \node[coordinate, - pin={[node~ contents={\int_use:N \g__knot_intersections_int},knot~ diagram/draft/crossing~ label, knot~ diagram/draft/crossing~ \int_use:N \g__knot_intersections_int \c_space_tl label/.try] + pin={[ + node~ contents={\int_use:N \g__knot_intersections_int}, + knot~ diagram/draft/crossing~ label, + knot~ diagram/draft/crossing~ + \int_use:N \g__knot_intersections_int \c_space_tl label/.try + ] }] } } \int_step_variable:nnnNn {1} {1} {\l__knot_tmpa_int - 1} \l__knot_tmpa_tl { - \int_step_variable:nnnNn {\tl_use:N \l__knot_tmpa_tl + 1} {1} {\l__knot_tmpa_int} \l__knot_tmpb_tl + \int_step_variable:nnnNn + {\tl_use:N \l__knot_tmpa_tl + 1} + {1} + {\l__knot_tmpa_int} \l__knot_tmpb_tl { \knot_intersections:VV \l__knot_tmpa_tl \l__knot_tmpb_tl } @@ -290,7 +304,12 @@ \spath_bake_round:c {knot strand #1} \tl_set:Nn \l__knot_tmpa_tl {knot~ diagram/every~ strand/.try,} \tl_put_right:Nv \l__knot_tmpa_tl {l__knot_options_strand #1} - \tl_put_right:Nn \l__knot_tmpa_tl {,knot~ diagram/only~ when~ rendering/.try,only~ when~ rendering/.try} + \tl_put_right:Nn \l__knot_tmpa_tl + { + , + knot~ diagram/only~ when~ rendering/.try, + only~ when~ rendering/.try + } \spath_tikz_path:Vv \l__knot_tmpa_tl {knot strand #1} \group_end: \endpgfscope @@ -303,11 +322,15 @@ \spath_finalpoint:Nv \l__knot_tmpb_tl {knot strand #1} \dim_set:Nn \l__knot_tmpa_dim {\tl_item:Nn \l__knot_tmpb_tl {1}} \dim_set:Nn \l__knot_tmpb_dim {\tl_item:Nn \l__knot_tmpb_tl {2}} - \node[knot~ diagram/draft/strand~label] at (\l__knot_tmpa_dim,\l__knot_tmpb_dim) {#1}; + \node[ + knot~ diagram/draft/strand~label + ] at (\l__knot_tmpa_dim,\l__knot_tmpb_dim) {#1}; \spath_initialpoint:Nv \l__knot_tmpb_tl {knot strand #1} \dim_set:Nn \l__knot_tmpa_dim {\tl_item:Nn \l__knot_tmpb_tl {1}} \dim_set:Nn \l__knot_tmpb_dim {\tl_item:Nn \l__knot_tmpb_tl {2}} - \node[knot~ diagram/draft/strand~label] at (\l__knot_tmpa_dim,\l__knot_tmpb_dim) {#1}; + \node[ + knot~ diagram/draft/strand~label + ] at (\l__knot_tmpa_dim,\l__knot_tmpb_dim) {#1}; } \bool_if:nT { \l__knot_self_intersections_bool @@ -316,6 +339,8 @@ } { \tl_clear:N \l__knot_tmpa_tl + \spath_initialpoint:Nv \l__knot_tmpa_tl {knot strand #1} + \tl_put_left:NV \l__knot_tmpa_tl \c_spath_moveto_tl \spath_segments_to_seq:Nv \l__knot_segments_seq {knot strand #1} \seq_map_function:NN \l__knot_segments_seq \knot_split_self_intersects:N \tl_set_eq:cN {knot strand #1} \l__knot_tmpa_tl @@ -330,23 +355,29 @@ { \fp_set:Nn \l__knot_tmpa_fp { - (\tl_item:nn {#1} {3} - 3 * \tl_item:nn {#1} {6} + 3 * \tl_item:nn {#1} {9} - \tl_item:nn {#1} {12}) + (\tl_item:nn {#1} {3} - 3 * \tl_item:nn {#1} {6} + + 3 * \tl_item:nn {#1} {9} - \tl_item:nn {#1} {12}) * (3 * \tl_item:nn {#1} {8} - 3 * \tl_item:nn {#1} {11}) - - (\tl_item:nn {#1} {2} - 3 * \tl_item:nn {#1} {5} + 3 * \tl_item:nn {#1} {8} - \tl_item:nn {#1} {11}) + (\tl_item:nn {#1} {2} - 3 * \tl_item:nn {#1} {5} + + 3 * \tl_item:nn {#1} {8} - \tl_item:nn {#1} {11}) * (3 * \tl_item:nn {#1} {9} - 3 * \tl_item:nn {#1} {12}) } \fp_set:Nn \l__knot_tmpb_fp { - (\tl_item:nn {#1} {2} - 3 * \tl_item:nn {#1} {5} + 3 * \tl_item:nn {#1} {8} - \tl_item:nn {#1} {11}) + (\tl_item:nn {#1} {2} - 3 * \tl_item:nn {#1} {5} + + 3 * \tl_item:nn {#1} {8} - \tl_item:nn {#1} {11}) * - (3 * \tl_item:nn {#1} {6} - 6 * \tl_item:nn {#1} {9} + 3 * \tl_item:nn {#1} {12}) + (3 * \tl_item:nn {#1} {6} - 6 * \tl_item:nn {#1} {9} + + 3 * \tl_item:nn {#1} {12}) - - (\tl_item:nn {#1} {3} - 3 * \tl_item:nn {#1} {6} + 3 * \tl_item:nn {#1} {9} - \tl_item:nn {#1} {12}) + (\tl_item:nn {#1} {3} - 3 * \tl_item:nn {#1} {6} + + 3 * \tl_item:nn {#1} {9} - \tl_item:nn {#1} {12}) * - (3 * \tl_item:nn {#1} {5} - 6 * \tl_item:nn {#1} {8} + 3 * \tl_item:nn {#1} {11}) + (3 * \tl_item:nn {#1} {5} - 6 * \tl_item:nn {#1} {8} + + 3 * \tl_item:nn {#1} {11}) } \fp_compare:nTF { @@ -359,7 +390,11 @@ 0 < \l__knot_tmpa_fp && \l__knot_tmpa_fp < 1 } { - \spath_split_curve:NNnV \l__knot_tmpc_tl \l__knot_tmpd_tl {#1} \l__knot_tmpa_fp + \spath_split_curve:NNnV + \l__knot_tmpc_tl + \l__knot_tmpd_tl + {#1} + \l__knot_tmpa_fp \tl_set:Nx \l__knot_tmpc_tl {\tl_tail:N \l__knot_tmpc_tl} \tl_set:Nx \l__knot_tmpc_tl {\tl_tail:N \l__knot_tmpc_tl} \tl_set:Nx \l__knot_tmpc_tl {\tl_tail:N \l__knot_tmpc_tl} @@ -411,19 +446,33 @@ \bool_if:nTF { \l__knot_save_bool && - \tl_if_exist_p:c {knot~ intersections~ \tl_use:N \l__knot_name_tl - \tl_use:N \l__knot_tmpa_tl - \tl_use:N \l__knot_tmpb_tl} + \tl_if_exist_p:c { + knot~ intersections~ + \tl_use:N \l__knot_name_tl - + \tl_use:N \l__knot_tmpa_tl - + \tl_use:N \l__knot_tmpb_tl + } } { - \tl_use:c {knot~ intersections~ \tl_use:N \l__knot_name_tl - \tl_use:N \l__knot_tmpa_tl - \tl_use:N \l__knot_tmpb_tl} + \tl_use:c + { + knot~ intersections~ \tl_use:N \l__knot_name_tl - + \tl_use:N \l__knot_tmpa_tl - + \tl_use:N \l__knot_tmpb_tl + } } { -\pgfintersectionofpaths{\pgfsetpath\l__knot_tmpc_tl}{\pgfsetpath\l__knot_tmpd_tl} + \pgfintersectionofpaths{\pgfsetpath\l__knot_tmpc_tl}{\pgfsetpath\l__knot_tmpd_tl} } \int_compare:nT {\pgfintersectionsolutions > 0} { - \int_step_function:nnnN {1} {1} {\pgfintersectionsolutions} \knot_do_intersection:n + \int_step_function:nnnN + {1} + {1} + {\pgfintersectionsolutions} + \knot_do_intersection:n } \knot_save_intersections:VV \l__knot_tmpa_tl \l__knot_tmpb_tl @@ -455,7 +504,16 @@ } \tl_put_right:Nx \l__knot_aux_tl { - {\exp_not:N \pgf@x=\dim_use:N \l__knot_tmpa_dim\exp_not:N\relax\exp_not:N \pgf@y =\dim_use:N \l__knot_tmpb_dim\relax} + { + \exp_not:N \pgf@x + = + \dim_use:N \l__knot_tmpa_dim + \exp_not:N \relax + \exp_not:N \pgf@y + = + \dim_use:N \l__knot_tmpb_dim + \exp_not:N \relax + } } } \tl_set:Nn \l__knot_auxa_tl {\expandafter \gdef \csname knot~ intersections~} @@ -480,7 +538,7 @@ \tl_set:Nv \l__knot_tmpc_tl \l__knot_tmpc_tl \tl_if_eq:NNT \l__knot_tmpc_tl \l__knot_tmpb_tl { - \knot_test_endpoint:VnT \l__knot_tmpb_tl {final point} + \knot_test_endpoint:NVnT \l__knot_tolerance_dim \l__knot_tmpb_tl {final point} { \bool_set_true:N \l__knot_skip_bool } @@ -491,7 +549,7 @@ \tl_set:Nv \l__knot_tmpc_tl \l__knot_tmpc_tl \tl_if_eq:NNT \l__knot_tmpc_tl \l__knot_tmpa_tl { - \knot_test_endpoint:VnT \l__knot_tmpa_tl {final point} + \knot_test_endpoint:NVnT \l__knot_tolerance_dim \l__knot_tmpa_tl {final point} { \bool_set_true:N \l__knot_skip_bool } @@ -499,19 +557,19 @@ } \bool_if:NT \l__knot_ignore_ends_bool { - \knot_test_endpoint:VnT \l__knot_tmpa_tl {initial point} + \knot_test_endpoint:NVnT \l__knot_tolerance_dim \l__knot_tmpa_tl {initial point} { \bool_set_true:N \l__knot_skip_bool } - \knot_test_endpoint:VnT \l__knot_tmpa_tl {final point} + \knot_test_endpoint:NVnT \l__knot_tolerance_dim \l__knot_tmpa_tl {final point} { \bool_set_true:N \l__knot_skip_bool } - \knot_test_endpoint:VnT \l__knot_tmpb_tl {initial point} + \knot_test_endpoint:NVnT \l__knot_tolerance_dim \l__knot_tmpb_tl {initial point} { \bool_set_true:N \l__knot_skip_bool } - \knot_test_endpoint:VnT \l__knot_tmpb_tl {final point} + \knot_test_endpoint:NVnT \l__knot_tolerance_dim \l__knot_tmpb_tl {final point} { \bool_set_true:N \l__knot_skip_bool } @@ -545,14 +603,16 @@ } \bool_if:NT \l__knot_self_intersections_bool { - \knot_test_endpoint:VnT \l__knot_tmpg_tl {initial point} + \knot_test_endpoint:NVnT + \l__knot_redraw_tolerance_dim \l__knot_tmpg_tl {initial point} { \bool_set_true:N \l__knot_prepend_prev_bool } { \bool_set_false:N \l__knot_prepend_prev_bool } - \knot_test_endpoint:VnT \l__knot_tmpg_tl {final point} + \knot_test_endpoint:NVnT + \l__knot_redraw_tolerance_dim \l__knot_tmpg_tl {final point} { \bool_set_true:N \l__knot_append_next_bool } @@ -565,10 +625,14 @@ } { \tl_clear_new:c {knot \tl_use:N \l__knot_prefix_tl -1} - \tl_set_eq:cc {knot \tl_use:N \l__knot_prefix_tl -1} {knot \tl_use:N \l__knot_tmpg_tl} + \tl_set_eq:cc + {knot \tl_use:N \l__knot_prefix_tl -1} + {knot \tl_use:N \l__knot_tmpg_tl} \tl_clear_new:c {l__knot_options_ \tl_use:N \l__knot_prefix_tl -1} - \tl_set_eq:cc {l__knot_options_ \tl_use:N \l__knot_prefix_tl -1} {l__knot_options_ \tl_use:N \l__knot_tmpg_tl} + \tl_set_eq:cc + {l__knot_options_ \tl_use:N \l__knot_prefix_tl -1} + {l__knot_options_ \tl_use:N \l__knot_tmpg_tl} \bool_if:nT { @@ -579,7 +643,9 @@ !\tl_if_empty_p:c {knot previous \tl_use:N \l__knot_tmpg_tl} } { - \spath_prepend_no_move:cv {knot \tl_use:N \l__knot_prefix_tl -1} {knot \tl_use:c {knot previous \tl_use:N \l__knot_tmpg_tl}} + \spath_prepend_no_move:cv + {knot \tl_use:N \l__knot_prefix_tl -1} + {knot \tl_use:c {knot previous \tl_use:N \l__knot_tmpg_tl}} \bool_if:nT { \l__knot_splits_bool @@ -589,10 +655,18 @@ !\tl_if_empty_p:c {knot previous \tl_use:N \l__knot_tmpg_tl} } { - \knot_test_endpoint:vnT {knot previous \tl_use:N \l__knot_tmpg_tl} {initial point} + \knot_test_endpoint:NvnT + \l__knot_redraw_tolerance_dim + {knot previous \tl_use:N \l__knot_tmpg_tl} + {initial point} { - - \spath_prepend_no_move:cv {knot \tl_use:N \l__knot_prefix_tl -1} {knot \tl_use:c {knot previous \tl_use:c {knot previous \tl_use:N \l__knot_tmpg_tl}}} + \spath_prepend_no_move:cv + {knot \tl_use:N \l__knot_prefix_tl -1} + {knot \tl_use:c + {knot previous \tl_use:c + {knot previous \tl_use:N \l__knot_tmpg_tl} + } + } \tl_set_eq:Nc \l__knot_tmpa_tl {knot \tl_use:N \l__knot_prefix_tl -1} } } @@ -606,7 +680,9 @@ !\tl_if_empty_p:c {knot previous \tl_use:N \l__knot_tmpg_tl} } { - \spath_append_no_move:cv {knot \tl_use:N \l__knot_prefix_tl -1} {knot \tl_use:c {knot next \tl_use:N \l__knot_tmpg_tl}} + \spath_append_no_move:cv + {knot \tl_use:N \l__knot_prefix_tl -1} + {knot \tl_use:c {knot next \tl_use:N \l__knot_tmpg_tl}} \bool_if:nT { \l__knot_splits_bool @@ -617,42 +693,61 @@ !\tl_if_empty_p:c {knot previous \tl_use:N \l__knot_tmpg_tl} } { - \knot_test_endpoint:vnT {knot previous \tl_use:N \l__knot_tmpg_tl} {final point} + \knot_test_endpoint:NvnT + \l__knot_redraw_tolerance_dim + {knot previous \tl_use:N \l__knot_tmpg_tl} + {final point} { - \spath_append_no_move:cv {knot \tl_use:N \l__knot_prefix_tl -1} {knot \tl_use:c {knot next \tl_use:c {knot next \tl_use:N \l__knot_tmpg_tl}}} - + \spath_append_no_move:cv + {knot \tl_use:N \l__knot_prefix_tl -1} + {knot \tl_use:c + {knot next \tl_use:c + {knot next \tl_use:N \l__knot_tmpg_tl} + } + } } } } - \tl_set:Nn \l__knot_tmpg_tl {\tl_use:N \l__knot_prefix_tl -1} } } \pgfscope \group_begin: - \tikzset{knot~ diagram/every~ intersection/.try, every~ intersection/.try, knot~ diagram/intersection~ \int_use:N \g__knot_intersections_int/.try} + \tikzset{ + knot~ diagram/every~ intersection/.try, + every~ intersection/.try, + knot~ diagram/intersection~ \int_use:N \g__knot_intersections_int/.try + } \knot_draw_crossing:VVV \l__knot_tmpg_tl \l__knot_tmpa_dim \l__knot_tmpb_dim - \coordinate (\l__knot_name_tl \c_space_tl \int_use:N \g__knot_intersections_int) at (\dim_use:N \l__knot_tmpa_dim, \dim_use:N \l__knot_tmpb_dim); + \coordinate + (\l__knot_name_tl \c_space_tl \int_use:N \g__knot_intersections_int) + at (\dim_use:N \l__knot_tmpa_dim, \dim_use:N \l__knot_tmpb_dim); \group_end: \endpgfscope } \tl_if_empty:NF \l__knot_node_tl { - \seq_gpush:Nx \g__knot_nodes_seq { \l__knot_node_tl at (\dim_use:N \l__knot_tmpa_dim, \dim_use:N \l__knot_tmpb_dim) {};} + \seq_gpush:Nx + \g__knot_nodes_seq + { + \l__knot_node_tl + at + (\dim_use:N \l__knot_tmpa_dim, \dim_use:N \l__knot_tmpb_dim) {}; + } } } } \cs_generate_variant:Nn \knot_intersections:nn {VV} -\prg_new_conditional:Npnn \knot_test_endpoint:N #1 {p,T,F,TF} +\prg_new_conditional:Npnn \knot_test_endpoint:NN #1#2 {p,T,F,TF} { \dim_compare:nTF { - \dim_abs:n { \l__knot_tmpa_dim - \tl_item:Nn #1 {1}} + \dim_abs:n { \l__knot_tmpa_dim - \tl_item:Nn #2 {1}} + - \dim_abs:n { \l__knot_tmpb_dim - \tl_item:Nn #1 {2}} + \dim_abs:n { \l__knot_tmpb_dim - \tl_item:Nn #2 {2}} < - \l__knot_tolerance_dim + #1 } { \prg_return_true: @@ -661,10 +756,10 @@ \prg_return_false: } } -\prg_new_protected_conditional:Npnn \knot_test_endpoint:nn #1#2 {T,F,TF} +\prg_new_protected_conditional:Npnn \knot_test_endpoint:Nnn #1#2#3 {T,F,TF} { - \use:c {spath_#2:Nv} \l__knot_tmpd_tl {knot #1} - \knot_test_endpoint:NTF \l__knot_tmpd_tl + \use:c {spath_#3:Nv} \l__knot_tmpd_tl {knot #2} + \knot_test_endpoint:NNTF #1 \l__knot_tmpd_tl { \prg_return_true: } @@ -673,34 +768,44 @@ } } -\cs_generate_variant:Nn \knot_test_endpoint:nnT {VnT,vnT} -\cs_generate_variant:Nn \knot_test_endpoint:nnF {VnF,vnF} -\cs_generate_variant:Nn \knot_test_endpoint:nnTF {VnTF,vnTF} +\cs_generate_variant:Nn \knot_test_endpoint:NnnT {NVnT,NvnT} +\cs_generate_variant:Nn \knot_test_endpoint:NnnF {NVnF,NvnF} +\cs_generate_variant:Nn \knot_test_endpoint:NnnTF {NVnTF,NvnTF} \cs_new_protected_nopar:Npn \knot_draw_crossing:nnn #1#2#3 { \group_begin: \pgfscope - \path[knot~ diagram/background~ clip] (#2, #3) circle[radius=\l__knot_clip_bg_radius_dim]; + \path[knot~ diagram/background~ clip] (#2, #3) + circle[radius=\l__knot_clip_bg_radius_dim]; \tl_set:Nn \l__knot_tmpa_tl {knot~ diagram/every~ strand/.try,} \tl_if_exist:cT {l__knot_options_ #1} { \tl_put_right:Nv \l__knot_tmpa_tl {l__knot_options_ #1} } - \tl_put_right:Nn \l__knot_tmpa_tl {,knotbg,line~ width= \tl_use:N \l__knot_clip_width_tl * \pgflinewidth} + \tl_put_right:Nn \l__knot_tmpa_tl + { + ,knotbg + ,line~ width= \tl_use:N \l__knot_clip_width_tl * \pgflinewidth + } \spath_tikz_path:Vv \l__knot_tmpa_tl {knot #1} \endpgfscope \pgfscope - \path[knot~ diagram/clip] (#2, #3) circle[radius=\l__knot_clip_draw_radius_dim]; + \path[knot~ diagram/clip] (#2, #3) + circle[radius=\l__knot_clip_draw_radius_dim]; \tl_set:Nn \l__knot_tmpa_tl {knot~ diagram/every~ strand/.try,} \tl_if_exist:cT {l__knot_options_ #1} { \tl_put_right:Nv \l__knot_tmpa_tl {l__knot_options_ #1} } - \tl_put_right:Nn \l__knot_tmpa_tl {,knot~ diagram/only~ when~ rendering/.try,only~ when~ rendering/.try} + \tl_put_right:Nn \l__knot_tmpa_tl + { + ,knot~ diagram/only~ when~ rendering/.try + ,only~ when~ rendering/.try + } \spath_tikz_path:Vv \l__knot_tmpa_tl {knot #1} \endpgfscope @@ -752,12 +857,14 @@ \tl_set:cn {knot filament \int_use:N \g__knot_filaments_int} {#1} \tl_clear_new:c {l__knot_options_filament \int_use:N \g__knot_filaments_int} - \tl_set_eq:cN {l__knot_options_filament \int_use:N \g__knot_filaments_int} \l__knot_tmpa_tl + \tl_set_eq:cN {l__knot_options_filament \int_use:N \g__knot_filaments_int} + \l__knot_tmpa_tl \tl_clear_new:c {knot previous filament \int_use:N \g__knot_filaments_int} \int_compare:nF {\l__knot_component_start_int == \g__knot_filaments_int} { - \tl_set:cx {knot previous filament \int_use:N \g__knot_filaments_int} {filament \int_eval:n {\g__knot_filaments_int - 1}} + \tl_set:cx {knot previous filament \int_use:N \g__knot_filaments_int} + {filament \int_eval:n {\g__knot_filaments_int - 1}} } } \c_spath_curvetoa_tl @@ -766,12 +873,15 @@ \tl_clear_new:c {knot filament \int_use:N \g__knot_filaments_int} \tl_set:cn {knot filament \int_use:N \g__knot_filaments_int} {#1} \tl_clear_new:c {l__knot_options_filament \int_use:N \g__knot_filaments_int} - \tl_set_eq:cN {l__knot_options_filament \int_use:N \g__knot_filaments_int} \l__knot_tmpa_tl + \tl_set_eq:cN {l__knot_options_filament \int_use:N \g__knot_filaments_int} + \l__knot_tmpa_tl \tl_clear_new:c {knot previous filament \int_use:N \g__knot_filaments_int} \int_compare:nF {\l__knot_component_start_int == \g__knot_filaments_int} { - \tl_set:cx {knot previous filament \int_use:N \g__knot_filaments_int} {filament \int_eval:n {\g__knot_filaments_int - 1}} + \tl_set:cx + {knot previous filament \int_use:N \g__knot_filaments_int} + {filament \int_eval:n {\g__knot_filaments_int - 1}} } } \c_spath_closepath_tl @@ -779,18 +889,26 @@ \int_gincr:N \g__knot_filaments_int \tl_clear_new:c {knot filament \int_use:N \g__knot_filaments_int} \tl_clear:N \l__knot_tmpa_tl - \tl_put_right:Nx {\tl_item:nn {#1} {1}\tl_item:nn {#1} {2}\tl_item:nn {#1} {3}} + \tl_put_right:Nx + { + \tl_item:nn {#1} {1}\tl_item:nn {#1} {2}\tl_item:nn {#1} {3} + } \tl_put_right:NV \l__knot_tmpa_tl \c_spath_lineto_tl \tl_put_right:Nx {\tl_item:nn {#1} {5}\tl_item:nn {#1} {6}} \tl_set:cV {knot filament \int_use:N \g__knot_filaments_int} \l__knot_tmpa_tl - \tl_set_eq:cN {l__knot_options_filament \int_use:N \g__knot_filaments_int} \l__knot_tmpa_tl + \tl_set_eq:cN {l__knot_options_filament \int_use:N \g__knot_filaments_int} + \l__knot_tmpa_tl \tl_clear_new:c {knot previous filament \int_use:N \g__knot_filaments_int} \int_compare:nF {\l__knot_component_start_int == \g__knot_filaments_int} { - \tl_set:cx {knot previous filament \int_use:N \g__knot_filaments_int} {filament \int_eval:n {\g__knot_filaments_int - 1}} + \tl_set:cx + {knot previous filament \int_use:N \g__knot_filaments_int} + {filament \int_eval:n {\g__knot_filaments_int - 1}} } - \tl_set:cx {knot previous filament \int_use:N \l__knot_component_start_int} {filament \int_use:N \g__knot_filaments_int} + \tl_set:cx + {knot previous filament \int_use:N \l__knot_component_start_int} + {filament \int_use:N \g__knot_filaments_int} } } { @@ -1008,7 +1126,7 @@ } } %% -%% Copyright (C) 2011-2019 by Andrew Stacey +%% Copyright (C) 2011-2021 by Andrew Stacey %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License (LPPL), either @@ -1020,7 +1138,7 @@ %% This work is "maintained" (as per LPPL maintenance status) by %% Andrew Stacey. %% -%% This work consists of the files spath3.dtx +%% This work consists of the files spath3_code.dtx %% calligraphy_doc.tex %% knots_doc.tex %% spath3.tex diff --git a/Master/texmf-dist/tex/latex/spath3/tikzlibraryspath3.code.tex b/Master/texmf-dist/tex/latex/spath3/tikzlibraryspath3.code.tex index 32d0d9fea08..9c1c158e52a 100644 --- a/Master/texmf-dist/tex/latex/spath3/tikzlibraryspath3.code.tex +++ b/Master/texmf-dist/tex/latex/spath3/tikzlibraryspath3.code.tex @@ -24,6 +24,8 @@ \seq_new:N \g__spath_tmpa_seq \seq_new:N \g__spath_tmpb_seq \bool_new:N \l__spath_draft_bool +\msg_new:nnn { spath3 } { missing soft path } { Soft~ path~ #1~ doesn't~ exist } +\msg_new:nnn { spath3 } { empty soft path } { Soft~ path~ #1~ is~ empty } \tl_set:Nn \l__spath_prefix_tl {tikz@intersect@path@name@} \tl_set:Nn \l__spath_suffix_tl {} \tl_new:N \g__spath_tikzfinish_tl @@ -53,6 +55,20 @@ } } \cs_generate_variant:Nn \spath_gsave_path:Nn {cn, NV, cV} +\cs_new_protected_nopar:Npn \__spath_process_tikz_point:Nn #1#2 +{ + \group_begin: + \use:c {tikz@scan@one@point} \use:n #2 \scan_stop: + \tl_gset:Nx \g__spath_output_tl + { + { \dim_use:c {pgf@x} } + { \dim_use:c {pgf@y} } + } + \group_end: + \tl_set_eq:NN #1 \g__spath_output_tl + \tl_gclear:N \g__spath_output_tl +} +\cs_set_eq:NN \getComponentOf \clist_item:Nn \tikzset{ spath/.is~family, spath/.cd, @@ -74,11 +90,14 @@ \tikz@addmode{ \spath_get_current_path:N \l__spath_tmpa_tl \spath_bake_round:NV \l__spath_tmpa_tl \l__spath_tmpa_tl - \spath_save_path:cV {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} \l__spath_tmpa_tl + \spath_save_path:cV + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \l__spath_tmpa_tl } }, clone/.code~ 2~ args={ - \tl_if_exist:cT {\tl_use:N \l__spath_prefix_tl #2 \tl_use:N \l__spath_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #2 \tl_use:N \l__spath_suffix_tl} { \tl_clear_new:c {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} @@ -86,9 +105,13 @@ {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} {\tl_use:N \l__spath_prefix_tl #2 \tl_use:N \l__spath_suffix_tl} } + { + \msg_warning:nnn { spath3 } { missing soft path } { #2 } + } }, clone~ global/.code~ 2~ args={ - \tl_if_exist:cT {\tl_use:N \l__spath_prefix_tl #2 \tl_use:N \l__spath_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #2 \tl_use:N \l__spath_suffix_tl} { \tl_gclear_new:c {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} @@ -96,6 +119,9 @@ {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} {\tl_use:N \l__spath_prefix_tl #2 \tl_use:N \l__spath_suffix_tl} } + { + \msg_warning:nnn { spath3 } { missing soft path } { #2 } + } }, save~ global/.code={ \tikz@addmode{ @@ -107,19 +133,75 @@ } }, save~ to~ aux/.code={ - \tl_if_exist:cT {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} { \spath_save_to_aux:c {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } }, restore/.code={ - \tl_if_exist:cT {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} { - \spath_set_current_path:c + \tl_if_empty:cTF {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} - \spath_set_tikz_coords:v + { + \tl_clear:N \l__spath_tmpa_tl + \tl_put_right:NV \l__spath_tmpa_tl \c_spath_moveto_tl + \tl_put_right:Nn \l__spath_tmpa_tl {{0pt}{0pt}} + \spath_set_current_path:V \l__spath_tmpa_tl + \spath_set_tikz_data:V \l__spath_tmpa_tl + \msg_warning:nnn { spath3 } { empty soft path } { #1 } + } + { + \spath_set_current_path:c + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \spath_set_tikz_data:v + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + } + } + { + \tl_clear:N \l__spath_tmpa_tl + \tl_put_right:NV \l__spath_tmpa_tl \c_spath_moveto_tl + \tl_put_right:Nn \l__spath_tmpa_tl {{0pt}{0pt}} + \spath_set_current_path:V \l__spath_tmpa_tl + \spath_set_tikz_data:V \l__spath_tmpa_tl + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + restore~ reverse/.code={ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \tl_if_empty:cTF {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \tl_clear:N \l__spath_tmpa_tl + \tl_put_right:NV \l__spath_tmpa_tl \c_spath_moveto_tl + \tl_put_right:Nn \l__spath_tmpa_tl {{0pt}{0pt}} + \spath_set_current_path:V \l__spath_tmpa_tl + \spath_set_tikz_data:V \l__spath_tmpa_tl + \msg_warning:nnn { spath3 } { empty soft path } { #1 } + } + { + \spath_reverse:Nv + \l__spath_reverse_tl + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \spath_set_current_path:N \l__spath_reverse_tl + \spath_set_tikz_data:V \l__spath_reverse_tl + } + } + { + \tl_clear:N \l__spath_tmpa_tl + \tl_put_right:NV \l__spath_tmpa_tl \c_spath_moveto_tl + \tl_put_right:Nn \l__spath_tmpa_tl {{0pt}{0pt}} + \spath_set_current_path:V \l__spath_tmpa_tl + \spath_set_tikz_data:V \l__spath_tmpa_tl + \msg_warning:nnn { spath3 } { missing soft path } { #1 } } }, show~current~path/.code={ @@ -130,73 +212,142 @@ } }, show/.code={ - \tl_if_exist:cT {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \tl_if_empty:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \msg_warning:nnn { spath3 } { empty soft path } { #1 } + } + { + \iow_term:n {---~ soft~ path~ #1~ ---} + \spath_show:v + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + } + } { - \iow_term:n {---~ soft~ path~ #1~ ---} - \spath_show:v {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \msg_warning:nnn { spath3 } { missing soft path } { #1 } } }, append/.code={ - \tl_if_exist:cT {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} { \spath_get_current_path:N \l__spath_current_tl - \spath_weld:Nv - \l__spath_current_tl + \spath_finalpoint:NV \l__spath_tmpa_tl \l__spath_current_tl + \tl_set_eq:Nc + \l__spath_tmpb_tl {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \spath_translate_to:NV \l__spath_tmpb_tl \l__spath_tmpa_tl + \spath_append_no_move:NV \l__spath_current_tl \l__spath_tmpb_tl \spath_set_current_path:N \l__spath_current_tl - \spath_set_tikz_coords:V \l__spath_current_tl + \spath_set_tikz_data:V \l__spath_tmpb_tl + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } } }, join~ with/.code~ 2~ args={ - \tl_if_exist:cT {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} { - \tl_if_exist:cT {\tl_use:N \l__spath_prefix_tl #2 \tl_use:N \l__spath_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #2 \tl_use:N \l__spath_suffix_tl} { \spath_append:cv {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} {\tl_use:N \l__spath_prefix_tl #2 \tl_use:N \l__spath_suffix_tl} } + { + \msg_warning:nnn { spath3 } { missing soft path } { #2 } + } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } } }, spot~ weld/.code={ - \tl_if_exist:cT {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} { \spath_spot_weld_components:c {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + spot~ weld~ globally/.code={ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \spath_spot_gweld_components:c + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } }, reverse/.code={ - \tl_if_exist:cT {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} { \spath_reverse:c {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + reverse~ globally/.code={ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \spath_reverse:c + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } }, append~ reverse/.code={ - \tl_if_exist:cT {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} { \spath_reverse:Nv \l__spath_reverse_tl {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} \spath_get_current_path:N \l__spath_current_tl - \spath_weld:NV \l__spath_current_tl \l__spath_reverse_tl + \spath_finalpoint:NV \l__spath_tmpa_tl \l__spath_current_tl + \spath_translate_to:NV \l__spath_reverse_tl \l__spath_tmpa_tl + \spath_append_no_move:NV \l__spath_current_tl \l__spath_reverse_tl \spath_set_current_path:N \l__spath_current_tl - \spath_set_tikz_coords:V \l__spath_current_tl + \spath_set_tikz_data:V \l__spath_reverse_tl + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } } }, insert/.code={ - \tl_if_exist:cT {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} { \spath_get_current_path:N \l__spath_current_tl \spath_append:Nv \l__spath_current_tl {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} \spath_set_current_path:N \l__spath_current_tl - \spath_set_tikz_coords:V \l__spath_current_tl + \spath_set_tikz_data:v + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } } }, insert~ reverse/.code={ - \tl_if_exist:cT {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} { \spath_reverse:Nv \l__spath_reverse_tl @@ -204,48 +355,391 @@ \spath_get_current_path:N \l__spath_current_tl \spath_append:NV \l__spath_current_tl \l__spath_reverse_tl \spath_set_current_path:N \l__spath_current_tl - \spath_set_tikz_coords:V \l__spath_current_tl + \spath_set_tikz_data:V \l__spath_reverse_tl + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + append~ no~ move/.code={ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \spath_get_current_path:N \l__spath_current_tl + \spath_append_no_move:Nv + \l__spath_current_tl + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \spath_set_current_path:N \l__spath_current_tl + \spath_set_tikz_data:v + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + append~ reverse~ no~ move/.code={ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \spath_reverse:Nv + \l__spath_reverse_tl + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \spath_get_current_path:N \l__spath_current_tl + \spath_append_no_move:NV \l__spath_current_tl \l__spath_reverse_tl + \spath_set_current_path:N \l__spath_current_tl + \spath_set_tikz_data:V \l__spath_reverse_tl + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + span/.code ~n~ args={3}{ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \__spath_process_tikz_point:Nn \l__spath_tmpa_tl {#2} + \__spath_process_tikz_point:Nn \l__spath_tmpb_tl {#3} + \spath_span:cVV + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \l__spath_tmpa_tl \l__spath_tmpb_tl + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + span~ global/.code ~n~ args={3}{ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \__spath_process_tikz_point:Nn \l__spath_tmpa_tl {#2} + \__spath_process_tikz_point:Nn \l__spath_tmpb_tl {#3} + \spath_gspan:cVV + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \l__spath_tmpa_tl \l__spath_tmpb_tl + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + to/.style={ + to~path={ + [ + spath/span={#1}{(\tikztostart)}{(\tikztotarget)}, + spath/append~no~move={#1}, + ] + \tikztonodes + } + }, + splice/.code ~n~ args={3}{ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #2 \tl_use:N \l__spath_suffix_tl} + { + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #3 \tl_use:N \l__spath_suffix_tl} + { + \spath_splice_between:cvv + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + {\tl_use:N \l__spath_prefix_tl #2 \tl_use:N \l__spath_suffix_tl} + {\tl_use:N \l__spath_prefix_tl #3 \tl_use:N \l__spath_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #3 } + } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #2 } + } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + splice~ global/.code ~n~ args={3}{ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #2 \tl_use:N \l__spath_suffix_tl} + { + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #3 \tl_use:N \l__spath_suffix_tl} + { + \spath_gsplice_between:cvv + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + {\tl_use:N \l__spath_prefix_tl #2 \tl_use:N \l__spath_suffix_tl} + {\tl_use:N \l__spath_prefix_tl #3 \tl_use:N \l__spath_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #3 } + } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #2 } + } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + join~ components~ with/.code~2~args={ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #2 \tl_use:N \l__spath_suffix_tl} + { + \spath_spot_weld_components:c + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + + \spath_components_to_seq:Nv + \l__spath_tmpa_seq + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + + \seq_pop_left:NN \l__spath_tmpa_seq \l__spath_tmpa_tl + + \seq_map_inline:Nn \l__spath_tmpa_seq + { + \spath_splice_between:Nvn \l__spath_tmpa_tl + {\tl_use:N \l__spath_prefix_tl #2 \tl_use:N \l__spath_suffix_tl} + {##1} + } + \tl_set_eq:cN + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \l__spath_tmpa_tl + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #2 } + } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + join~ components~ globally~ with/.code~2~args={ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #2 \tl_use:N \l__spath_suffix_tl} + { + \spath_spot_gweld_components:c + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + + \spath_components_to_seq:Nv + \l__spath_tmpa_seq + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + + \seq_pop_left:NN \l__spath_tmpa_seq \l__spath_tmpa_tl + + \seq_map_inline:Nn \l__spath_tmpa_seq + { + \spath_gsplice_between:Nvn \l__spath_tmpa_tl + {\tl_use:N \l__spath_prefix_tl #2 \tl_use:N \l__spath_suffix_tl} + {##1} + } + \tl_set_eq:cN + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \l__spath_tmpa_tl + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #2 } + } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + close/.code={ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \spath_close:c + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + close~ globally/.code={ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \spath_gclose:c + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + close~ with/.code~ 2~ args={ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #2 \tl_use:N \l__spath_suffix_tl} + { + \spath_close_with:cv + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + {\tl_use:N \l__spath_prefix_tl #2 \tl_use:N \l__spath_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #2 } + } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + close~ globally~ with/.code~ 2~ args={ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #2 \tl_use:N \l__spath_suffix_tl} + { + \spath_gclose_with:cv + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + {\tl_use:N \l__spath_prefix_tl #2 \tl_use:N \l__spath_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #2 } + } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } } }, shorten~ at~ end/.code~ 2~ args={ - \tl_if_exist:cT {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \spath_shorten_at_end:cn + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} {#2} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + shorten~ at~ start/.code~ 2~ args ={ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \spath_shorten_at_start:cn + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} {#2} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + shorten~ at~ both~ ends/.code~ 2~ args={ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} { \spath_shorten_at_end:cn {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} {#2} + \spath_shorten_at_start:cn + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} {#2} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + shorten~ globally~ at~ end/.code~ 2~ args={ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \spath_gshorten_at_end:cn + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} {#2} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + shorten~ globally~ at~ start/.code~ 2~ args ={ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \spath_gshorten_at_start:cn + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} {#2} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + shorten~ globally~ at~ both~ ends/.code~ 2~ args={ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \spath_shorten_at_end:cn + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} {#2} + \spath_shorten_at_start:cn + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} {#2} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + translate/.code~ n~ args={3}{ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \spath_translate:cnn + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl}{#2}{#3} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + translate~ globally/.code~ n~ args={3}{ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \spath_gtranslate:cnn + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl}{#2}{#3} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + normalise/.code={ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \spath_normalise:c + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} } - }, - shorten~ at~ start/.code~ 2~ args ={ - \tl_if_exist:cT {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} { - \spath_shorten_at_start:cn - {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} {#2} + \msg_warning:nnn { spath3 } { missing soft path } { #1 } } }, - shorten~ at~ both~ ends/.code~ 2~ args={ - \tl_if_exist:cT {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + normalise~ globally/.code={ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} { - \spath_shorten_at_end:cn - {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} {#2} - \spath_shorten_at_start:cn - {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} {#2} + \spath_gnormalise:c + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} } - }, - translate/.code~ n~ args={3}{ - \tl_if_exist:cT {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} { - \spath_translate:cnn - {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl}{#2}{#3} + \msg_warning:nnn { spath3 } { missing soft path } { #1 } } }, export~ to~ svg/.code={ - \tl_if_exist:cT {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} { - \spath_export_to_svg:c + \spath_export_to_svg:nv {#1} {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } }, transform/.code~ 2~ args={ - \tl_if_exist:cT {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} { \group_begin: \pgftransformreset @@ -260,9 +754,13 @@ \group_end: \tl_use:N \g__spath_smuggle_tl } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } }, - transform~global/.code~ 2~ args={ - \tl_if_exist:cT {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + transform~globally/.code~ 2~ args={ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} { \group_begin: \pgftransformreset @@ -277,27 +775,111 @@ \group_end: \tl_use:N \g__spath_smuggle_tl } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + split~ at~ intersections~ with/.code~ n~ args={2}{ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #2 \tl_use:N \l__spath_suffix_tl} + { + \spath_split_path_at_intersections:cv + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + {\tl_use:N \l__spath_prefix_tl #2 \tl_use:N \l__spath_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #2 } + } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + split~ globally~ at~ intersections~ with/.code~ n~ args={2}{ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #2 \tl_use:N \l__spath_suffix_tl} + { + \spath_gsplit_path_at_intersections:cv + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + {\tl_use:N \l__spath_prefix_tl #2 \tl_use:N \l__spath_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #2 } + } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } }, split~ at~ intersections/.code~ n~ args={2}{ - \tl_if_exist:cT {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} { - \tl_if_exist:cT {\tl_use:N \l__spath_prefix_tl #2 \tl_use:N \l__spath_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #2 \tl_use:N \l__spath_suffix_tl} { \spath_split_at_intersections:cc {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} {\tl_use:N \l__spath_prefix_tl #2 \tl_use:N \l__spath_suffix_tl} } + { + \msg_warning:nnn { spath3 } { missing soft path } { #2 } + } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + split~ globally~ at~ intersections/.code~ n~ args={2}{ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #2 \tl_use:N \l__spath_suffix_tl} + { + \spath_gsplit_at_intersections:cc + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + {\tl_use:N \l__spath_prefix_tl #2 \tl_use:N \l__spath_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #2 } + } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } } }, split~ at~ self~ intersections/.code={ - \tl_if_exist:cT {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} { \spath_split_at_self_intersections:c {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + split~ globally~ at~ self~ intersections/.code={ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \spath_gsplit_at_self_intersections:c + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } }, get~ components~ of/.code~ 2~ args={ - \tl_if_exist:cT {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} { \clist_clear_new:N #2 \spath_components_to_seq:Nv @@ -306,16 +888,58 @@ \seq_map_inline:Nn \l__spath_tmpa_seq { \tl_new:c - {\tl_use:N \l__spath_prefix_tl anonymous_\int_use:N \g__spath_anon_int \tl_use:N \l__spath_suffix_tl} + { + \tl_use:N \l__spath_prefix_tl + anonymous_\int_use:N \g__spath_anon_int + \tl_use:N \l__spath_suffix_tl + } \tl_set:cn - {\tl_use:N \l__spath_prefix_tl anonymous_\int_use:N \g__spath_anon_int \tl_use:N \l__spath_suffix_tl} {##1} + { + \tl_use:N \l__spath_prefix_tl + anonymous_\int_use:N \g__spath_anon_int + \tl_use:N \l__spath_suffix_tl + } {##1} \clist_put_right:Nx #2 {anonymous_\int_use:N \g__spath_anon_int} \int_gincr:N \g__spath_anon_int } } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + get~ components~ of~ globally/.code~ 2~ args={ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \clist_gclear_new:N #2 + \spath_components_to_seq:Nv + \l__spath_tmpa_seq + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \seq_map_inline:Nn \l__spath_tmpa_seq + { + \tl_new:c + { + \tl_use:N \l__spath_prefix_tl + anonymous_\int_use:N \g__spath_anon_int + \tl_use:N \l__spath_suffix_tl + } + \tl_gset:cn + { + \tl_use:N \l__spath_prefix_tl + anonymous_\int_use:N \g__spath_anon_int + \tl_use:N \l__spath_suffix_tl + } {##1} + \clist_gput_right:Nx #2 {anonymous_\int_use:N \g__spath_anon_int} + \int_gincr:N \g__spath_anon_int + } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } }, render~ components/.code={ - \tl_if_exist:cT {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} { \group_begin: \spath_components_to_seq:Nv @@ -338,17 +962,29 @@ } \group_end: } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } }, insert~ gaps~ after~ components/.code~ n~ args={3}{ - \tl_if_exist:cT {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} { \group_begin: \seq_gclear:N \g__spath_tmpa_seq \seq_gclear:N \g__spath_tmpb_seq + \spath_numberofcomponents:Nv \l__spath_tmpa_int + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} \foreach \l__spath_tmpa_tl in {#3} { \seq_gput_right:NV \g__spath_tmpa_seq \l__spath_tmpa_tl - \seq_gput_right:Nx \g__spath_tmpb_seq {\int_eval:n { \l__spath_tmpa_tl + 1 }} + \seq_gput_right:Nx + \g__spath_tmpb_seq + {\int_eval:n + { + \int_mod:nn { \l__spath_tmpa_tl }{ \l__spath_tmpa_int } + 1 + } + } } \spath_components_to_seq:Nv \l__spath_tmpa_seq @@ -374,9 +1010,62 @@ \g__spath_output_tl \tl_gclear:N \g__spath_output_tl } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + insert~ gaps~ globally~ after~ components/.code~ n~ args={3}{ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \group_begin: + \seq_gclear:N \g__spath_tmpa_seq + \seq_gclear:N \g__spath_tmpb_seq + \spath_numberofcomponents:Nv \l__spath_tmpa_int + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \foreach \l__spath_tmpa_tl in {#3} + { + \seq_gput_right:NV \g__spath_tmpa_seq \l__spath_tmpa_tl + \seq_gput_right:Nx + \g__spath_tmpb_seq + { + \int_eval:n + { + \int_mod:nn { \l__spath_tmpa_tl }{ \l__spath_tmpa_int } + 1 + } + } + } + \spath_components_to_seq:Nv + \l__spath_tmpa_seq + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \seq_clear:N \l__spath_tmpb_seq + \seq_map_indexed_inline:Nn \l__spath_tmpa_seq + { + \tl_set:Nn \l__spath_tmpa_tl {##2} + \seq_if_in:NnT \g__spath_tmpa_seq {##1} + { + \spath_shorten_at_end:Nn \l__spath_tmpa_tl {#2/2} + } + \seq_if_in:NnT \g__spath_tmpb_seq {##1} + { + \spath_shorten_at_start:Nn \l__spath_tmpa_tl {#2/2} + } + \seq_put_right:NV \l__spath_tmpb_seq \l__spath_tmpa_tl + } + \tl_gset:Nx \g__spath_output_tl {\seq_use:Nn \l__spath_tmpb_seq {} } + \group_end: + \tl_gset_eq:cN + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \g__spath_output_tl + \tl_gclear:N \g__spath_output_tl + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } }, join~ components/.code~ 2~ args={ - \tl_if_exist:cT {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} { \seq_gclear:N \g__spath_tmpa_seq \foreach \l__spath_tmpa_tl in {#2} @@ -395,13 +1084,144 @@ {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl}{##1} } } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + join~ components~ globally/.code~ 2~ args={ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \seq_gclear:N \g__spath_tmpa_seq + \foreach \l__spath_tmpa_tl in {#2} + { + \seq_gput_right:NV \g__spath_tmpa_seq \l__spath_tmpa_tl + } + \seq_gsort:Nn \g__spath_tmpa_seq + { + \int_compare:nNnTF {##1} > {##2} + { \sort_return_same: } + { \sort_return_swapped: } + } + \seq_map_inline:Nn \g__spath_tmpa_seq + { + \spath_gjoin_component:cn + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl}{##1} + } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } }, remove~ empty~ components/.code={ - \tl_if_exist:cT {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} { \spath_remove_empty_components:c {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + remove~ empty~ components~ globally/.code={ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \spath_gremove_empty_components:c + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + remove~ components/.code~ 2~ args={ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \seq_gclear:N \g__spath_tmpa_seq + \foreach \l__spath_tmpa_tl in {#2} + { + \seq_gput_right:NV \g__spath_tmpa_seq \l__spath_tmpa_tl + } + \seq_gsort:Nn \g__spath_tmpa_seq + { + \int_compare:nNnTF {##1} < {##2} + { \sort_return_same: } + { \sort_return_swapped: } + } + \spath_components_to_seq:Nv + \l__spath_tmpa_seq + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \seq_gpop_left:NNF \g__spath_tmpa_seq \l__spath_tmpa_tl + { + \tl_clear:N \l__spath_tmpa_tl + } + \seq_clear:N \l__spath_tmpb_seq + \seq_map_indexed_inline:Nn \l__spath_tmpa_seq + { + \tl_set:Nn \l__spath_tmpb_tl {##1} + \tl_if_eq:NNTF \l__spath_tmpb_tl \l__spath_tmpa_tl + { + \seq_gpop_left:NNF \g__spath_tmpa_seq \l__spath_tmpa_tl + { + \tl_clear:N \l__spath_tmpa_tl + } + } + { + \seq_put_right:Nn \l__spath_tmpb_seq {##2} + } + } + \tl_set:cx {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + {\seq_use:Nn \l__spath_tmpb_seq {} } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + }, + remove~ components~ globally/.code~ 2~ args={ + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \seq_gclear:N \g__spath_tmpa_seq + \foreach \l__spath_tmpa_tl in {#2} + { + \seq_gput_right:NV \g__spath_tmpa_seq \l__spath_tmpa_tl + } + \seq_gsort:Nn \g__spath_tmpa_seq + { + \int_compare:nNnTF {##1} < {##2} + { \sort_return_same: } + { \sort_return_swapped: } + } + \spath_components_to_seq:Nv + \l__spath_tmpa_seq + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \seq_gpop_left:NNF \g__spath_tmpa_seq \l__spath_tmpa_tl + { + \tl_clear:N \l__spath_tmpa_tl + } + \seq_clear:N \l__spath_tmpb_seq + \seq_map_indexed_inline:Nn \l__spath_tmpa_seq + { + \tl_set:Nn \l__spath_tmpb_tl {##1} + \tl_if_eq:NNTF \l__spath_tmpb_tl \l__spath_tmpa_tl + { + \seq_gpop_left:NNF \g__spath_tmpa_seq \l__spath_tmpa_tl + { + \tl_clear:N \l__spath_tmpa_tl + } + } + { + \seq_put_right:Nn \l__spath_tmpb_seq {##2} + } + } + \tl_gset:cx {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + {\seq_use:Nn \l__spath_tmpb_seq {} } + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } }, draft~ mode/.is~ choice, draft~ mode/true/.code={ @@ -413,11 +1233,29 @@ maybe~ spot~ weld/.code={ \bool_if:NF \l__spath_draft_bool { - \tl_if_exist:cT {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} { \spath_spot_weld_components:c {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } + } + }, + maybe~ spot~ weld~ globally/.code={ + \bool_if:NF \l__spath_draft_bool + { + \tl_if_exist:cTF + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + { + \spath_spot_gweld_components:c + {\tl_use:N \l__spath_prefix_tl #1 \tl_use:N \l__spath_suffix_tl} + } + { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } + } } }, transform~ to/.code~ 2~ args={ @@ -449,6 +1287,7 @@ \tl_gset_eq:NN \g__spath_smuggle_tl \l__spath_tmpc_tl } { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } \tl_gset_eq:NN \g__spath_smuggle_tl { {1}{0}{0}{1}{0pt}{0pt} } } \group_end: @@ -484,6 +1323,7 @@ \tl_gset_eq:NN \g__spath_smuggle_tl \l__spath_tmpc_tl } { + \msg_warning:nnn { spath3 } { missing soft path } { #1 } \tl_gset_eq:NN \g__spath_smuggle_tl { {1}{0}{0}{1}{0pt}{0pt} } } \fp_compare:nT { \tl_item:Nn \g__spath_smuggle_tl {4} < 0} @@ -503,11 +1343,18 @@ \tl_gclear:N \g__spath_smuggle_tl }, knot/.style~ n~ args={3}{ - spath/.cd, - split~ at~ self~ intersections=#1, - insert~ gaps~ after~ components={#1}{#2}{#3}, - maybe~ spot~ weld=#1, - render~ components=#1 + spath/split~ at~ self~ intersections=#1, + spath/remove~ empty~ components=#1, + spath/insert~ gaps~ after~ components={#1}{#2}{#3}, + spath/maybe~ spot~ weld=#1, + spath/render~ components=#1 + }, + global~ knot/.style~ n~ args={3}{ + spath/split~ globally~ at~ self~ intersections=#1, + spath/remove~ empty~ components~ globally=#1, + spath/insert~ gaps~ globally ~after~ components={#1}{#2}{#3}, + spath/maybe~ spot~ weld~ globally=#1, + spath/render~ components=#1 }, } \tikzdeclarecoordinatesystem{spath}{% @@ -556,15 +1403,20 @@ } } { + \msg_warning:nnx { spath3 } { missing soft path } { \tl_use:N \l__spath_tmpa_tl } \tl_gset_eq:NN \g__spath_smuggle_tl \pgfpointorigin } - \group_end: + \group_end: + \use:c {pgf@process}{% \tl_use:N \g__spath_smuggle_tl + \pgftransforminvert + \use:c {pgf@pos@transform@glob} + } } \ExplSyntaxOff %% -%% Copyright (C) 2011-2019 by Andrew Stacey +%% Copyright (C) 2011-2021 by Andrew Stacey %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License (LPPL), either @@ -576,7 +1428,7 @@ %% This work is "maintained" (as per LPPL maintenance status) by %% Andrew Stacey. %% -%% This work consists of the files spath3.dtx +%% This work consists of the files spath3_code.dtx %% calligraphy_doc.tex %% knots_doc.tex %% spath3.tex -- cgit v1.2.3