diff options
author | Karl Berry <karl@freefriends.org> | 2023-09-01 21:15:20 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2023-09-01 21:15:20 +0000 |
commit | c4e29d3cd52d9e65cc006e579462a8d01b5b83e2 (patch) | |
tree | 1944ec66776fb6356bf094e2f422073dfb1eddec /Master/texmf-dist/source | |
parent | 07c4be51b051fed0eefb0b319287d09f06781369 (diff) |
hobby (1sep23)
git-svn-id: svn://tug.org/texlive/trunk@68137 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source')
-rw-r--r-- | Master/texmf-dist/source/latex/hobby/hobby_code.dtx (renamed from Master/texmf-dist/source/latex/hobby/hobby.dtx) | 1170 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/hobby/hobby_code.ins (renamed from Master/texmf-dist/source/latex/hobby/hobby.ins) | 31 |
2 files changed, 658 insertions, 543 deletions
diff --git a/Master/texmf-dist/source/latex/hobby/hobby.dtx b/Master/texmf-dist/source/latex/hobby/hobby_code.dtx index d555a5b2f36..1d616477f2a 100644 --- a/Master/texmf-dist/source/latex/hobby/hobby.dtx +++ b/Master/texmf-dist/source/latex/hobby/hobby_code.dtx @@ -41,7 +41,7 @@ See http://www.latex-project.org/lppl.txt \endpreamble \postamble -Copyright (C) 2012 by Andrew Stacey <loopspace@mathforge.org> +Copyright (C) 2012-2021 by Andrew Stacey <loopspace@mathforge.org> This file may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3 of this @@ -56,12 +56,13 @@ version 2005/12/01 or later. This work is "maintained" (as per LPPL maintenance status) by Andrew Stacey. -This work consists of the files hobby.dtx - hobby_doc.tex +This work consists of the files hobby_code.dtx + hobby.tex and the derived files hobby.code.tex pgflibraryhobby.code.tex tikzlibraryhobby.code.tex pml3array.sty + hobby-l3draw.sty hobby.ins hobby.pdf hobby_code.pdf @@ -69,12 +70,11 @@ and the derived files hobby.code.tex \endpostamble \usedir{tex/latex/hobby} -\generate{\file{tikzlibraryhobby.code.tex} {\from{hobby.dtx}{tikzlibrary}}} -\generate{\file{pgflibraryhobby.code.tex} {\from{hobby.dtx}{pgflibrary}}} -\generate{\file{hobby.code.tex} -{\from{hobby.dtx}{hobby}}} -\generate{\file{pml3array.sty} -{\from{hobby.dtx}{array}}} +\generate{\file{tikzlibraryhobby.code.tex} {\from{hobby_code.dtx}{tikzlibrary}}} +\generate{\file{pgflibraryhobby.code.tex} {\from{hobby_code.dtx}{pgflibrary}}} +\generate{\file{hobby.code.tex} {\from{hobby_code.dtx}{hobby}}} +\generate{\file{pml3array.sty} {\from{hobby_code.dtx}{array}}} +\generate{\file{hobby-l3draw.sty} {\from{hobby_code.dtx}{l3hobby}}} %</install> %<install>\endbatchfile %<*internal> @@ -111,7 +111,7 @@ and the derived files hobby.code.tex %</driver> % \fi % -% \CheckSum{3382} +% \CheckSum{3427} % % \CharacterTable % {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z @@ -151,8 +151,6 @@ and the derived files hobby.code.tex % % We use \LaTeX3 syntax so need to load the requisite packages % \begin{macrocode} -\RequirePackage{expl3} -\RequirePackage{xparse} \RequirePackage{pml3array} \ExplSyntaxOn % \end{macrocode} @@ -167,7 +165,7 @@ and the derived files hobby.code.tex % % We declare all our variables. % -% Start with version and date, together with a check to see if we've been loaded twice (fail gracefully if so). +% Start with version and date, together with a check to see if we've been loaded twice (fail gracefully if so). % % \begin{macrocode} \tl_clear:N \l_tmpa_tl @@ -183,8 +181,8 @@ and the derived files hobby.code.tex \tl_new:N \g__hobby_version \tl_new:N \g__hobby_date -\tl_set:Nn \g__hobby_version {1.8} -\tl_set:Nn \g__hobby_date {2017-06-01} +\tl_gset:Nn \g__hobby_version {1.12} +\tl_gset:Nn \g__hobby_date {2023-09-01} \DeclareDocumentCommand \hobbyVersion {} { \tl_use:N \g__hobby_version @@ -234,186 +232,186 @@ and the derived files hobby.code.tex % \end{macrocode} % \end{macro} % -% \begin{macro}{\l_hobby_points_array} -% \Verb+\l_hobby_points_array+ is an array holding the specified points on the path. -% In the \LaTeX3 code, a ``point'' is a token list of the form \Verb+x = <number>, y = <number>+. +% \begin{macro}{\g__hobby_points_array} +% \Verb+\g__hobby_points_array+ is an array holding the specified points on the path. +% In the \LaTeX3 code, a ``point'' is a token list of the form \Verb+<number>, <number>+. % This gives us the greatest flexibility in passing points back and forth between the \LaTeX3 code and any calling code. % The array is indexed by integers beginning with \(0\). % In the documentation, we will use the notation \(z_k\) to refer to the \(k\)th point. % \begin{macrocode} -\array_new:N \l_hobby_points_array +\array_new:N \g__hobby_points_array % \end{macrocode} % \end{macro} % -% \begin{macro}{\l_hobby_points_x_array} -% \Verb+\l_hobby_points_x_array+ is an array holding the \(x\)--{}coordinates of the specified points. +% \begin{macro}{\g__hobby_points_x_array} +% \Verb+\g__hobby_points_x_array+ is an array holding the \(x\)--{}coordinates of the specified points. % \begin{macrocode} -\array_new:N \l_hobby_points_x_array +\array_new:N \g__hobby_points_x_array % \end{macrocode} % \end{macro} % % \begin{macro}{\l_hobby_points_y_array} -% \Verb+\l_hobby_points_y_array+ is an array holding the \(y\)--{}coordinates of the specified points. +% \Verb+\g__hobby_points_y_array+ is an array holding the \(y\)--{}coordinates of the specified points. % \begin{macrocode} -\array_new:N \l_hobby_points_y_array +\array_new:N \g__hobby_points_y_array % \end{macrocode} % \end{macro} % -% \begin{macro}{\l_hobby_actions_array} -% \Verb+\l_hobby_actions_array+ is an array holding the (encoded) action to be taken out on the segment of the path ending at that point. +% \begin{macro}{\g__hobby_actions_array} +% \Verb+\g__hobby_actions_array+ is an array holding the (encoded) action to be taken out on the segment of the path ending at that point. % \begin{macrocode} -\array_new:N \l_hobby_actions_array +\array_new:N \g__hobby_actions_array % \end{macrocode} % \end{macro} % -% \begin{macro}{\l_hobby_angles_array} -% \Verb+\l_hobby_angles_array+ is an array holding the angles of the lines between the points. +% \begin{macro}{\g__hobby_angles_array} +% \Verb+\g__hobby_angles_array+ is an array holding the angles of the lines between the points. % Specifically, the angle indexed by \(k\) is the angle in radians of the line from \(z_k\) to \(z_{k+1}\). % \begin{macrocode} -\array_new:N \l_hobby_angles_array +\array_new:N \g__hobby_angles_array % \end{macrocode} % \end{macro} % -% \begin{macro}{\l_hobby_distances_array} -% \Verb+\l_hobby_distances_array+ is an array holding the distances between the points. +% \begin{macro}{\g__hobby_distances_array} +% \Verb+\g__hobby_distances_array+ is an array holding the distances between the points. % Specifically, the distance indexed by \(k\), which we will write as \(d_k\), is the length of the line from \(z_k\) to \(z_{k+1}\). % \begin{macrocode} -\array_new:N \l_hobby_distances_array +\array_new:N \g__hobby_distances_array % \end{macrocode} % \end{macro} % -% \begin{macro}{\l_hobby_tension_out_array} -% \Verb+\l_hobby_tension_out_array+ is an array holding the tension for the path as it leaves each point. +% \begin{macro}{\g__hobby_tension_out_array} +% \Verb+\g__hobby_tension_out_array+ is an array holding the tension for the path as it leaves each point. % This is a parameter that controls how much the curve ``flexes'' as it leaves the point. % In the following, this will be written \(\tau_k\). % \begin{macrocode} -\array_new:N \l_hobby_tension_out_array +\array_new:N \g__hobby_tension_out_array % \end{macrocode} % \end{macro} % -% \begin{macro}{\l_hobby_tension_in_array} -% \Verb+\l_hobby_tension_in_array+ is an array holding the tension for the path as it arrives at each point. +% \begin{macro}{\g__hobby_tension_in_array} +% \Verb+\g__hobby_tension_in_array+ is an array holding the tension for the path as it arrives at each point. % This is a parameter that controls how much the curve ``flexes'' as it gets to the point. % In the following, this will be written \(\overline{\tau}_k\). % \begin{macrocode} -\array_new:N \l_hobby_tension_in_array +\array_new:N \g__hobby_tension_in_array % \end{macrocode} % \end{macro} % -% \begin{macro}{\l_hobby_matrix_a_array} -% \Verb+\l_hobby_matrix_a_array+ is an array holding the subdiagonal of the linear system that has to be solved to find the angles of the control points. +% \begin{macro}{\g__hobby_matrix_a_array} +% \Verb+\g__hobby_matrix_a_array+ is an array holding the subdiagonal of the linear system that has to be solved to find the angles of the control points. % In the following, this will be denoted by \(A_i\). % The first index is \(1\). % \begin{macrocode} -\array_new:N \l_hobby_matrix_a_array +\array_new:N \g__hobby_matrix_a_array % \end{macrocode} % \end{macro} % -% \begin{macro}{\l_hobby_matrix_b_array} -% \Verb+\l_hobby_matrix_b_array+ is an array holding the diagonal of the linear system that has to be solved to find the angles of the control points. +% \begin{macro}{\g__hobby_matrix_b_array} +% \Verb+\g__hobby_matrix_b_array+ is an array holding the diagonal of the linear system that has to be solved to find the angles of the control points. % In the following, this will be denoted by \(B_i\). % The first index is \(0\). % \begin{macrocode} -\array_new:N \l_hobby_matrix_b_array +\array_new:N \g__hobby_matrix_b_array % \end{macrocode} % \end{macro} % -% \begin{macro}{\l_hobby_matrix_c_array} -% \Verb+\l_hobby_matrix_c_array+ is an array holding the superdiagonal of the linear system that has to be solved to find the angles of the control points. +% \begin{macro}{\g__hobby_matrix_c_array} +% \Verb+\g__hobby_matrix_c_array+ is an array holding the superdiagonal of the linear system that has to be solved to find the angles of the control points. % In the following, this will be denoted by \(C_i\). % The first index is \(0\). % \begin{macrocode} -\array_new:N \l_hobby_matrix_c_array +\array_new:N \g__hobby_matrix_c_array % \end{macrocode} % \end{macro} % -% \begin{macro}{\l_hobby_matrix_d_array} -% \Verb+\l_hobby_matrix_d_array+ is an array holding the target vector of the linear system that has to be solved to find the angles of the control points. +% \begin{macro}{\g__hobby_matrix_d_array} +% \Verb+\g__hobby_matrix_d_array+ is an array holding the target vector of the linear system that has to be solved to find the angles of the control points. % In the following, this will be denoted by \(D_i\). % The first index is \(1\). % \begin{macrocode} -\array_new:N \l_hobby_matrix_d_array +\array_new:N \g__hobby_matrix_d_array % \end{macrocode} % \end{macro} % -% \begin{macro}{\l_hobby_vector_u_array} -% \Verb+\l_hobby_vector_u_array+ is an array holding the perturbation of the linear system for closed paths. +% \begin{macro}{\g__hobby_vector_u_array} +% \Verb+\g__hobby_vector_u_array+ is an array holding the perturbation of the linear system for closed paths. % The coefficient matrix for an \emph{open} path is tridiagonal and that means that Gaussian elimination runs faster than expected (\(O(n)\) instead of \(O(n^3)\)). % The matrix for a closed path is not tridiagonal but is not far off. % It can be solved by perturbing it to a tridiagonal matrix and then modifying the result. -% This array represents a utility vector in that perturbation. +% This array represents a utility vector in that perturbation. % In the following, the vector will be denoted by \(u\). % The first index is \(1\). % \begin{macrocode} -\array_new:N \l_hobby_vector_u_array +\array_new:N \g__hobby_vector_u_array % \end{macrocode} % \end{macro} % -% \begin{macro}{\l_hobby_excess_angle_array} -% \Verb+\l_hobby_excess_angle_array+ is an array that allows the user to say that the algorithm should add a multiple of \(2 \pi\) to the angle differences. +% \begin{macro}{\g__hobby_excess_angle_array} +% \Verb+\g__hobby_excess_angle_array+ is an array that allows the user to say that the algorithm should add a multiple of \(2 \pi\) to the angle differences. % This is because these angles are wrapped to the interval \((-\pi,\pi]\) but the wrapping might go wrong near the end points due to computation accuracy. % The first index is \(1\). % \begin{macrocode} -\array_new:N \l_hobby_excess_angle_array +\array_new:N \g__hobby_excess_angle_array % \end{macrocode} % \end{macro} % -% \begin{macro}{\l_hobby_psi_array} -% \Verb+\l_hobby_psi_array+ is an array holding the difference of the angles of the lines entering and exiting a point. +% \begin{macro}{\g__hobby_psi_array} +% \Verb+\g__hobby_psi_array+ is an array holding the difference of the angles of the lines entering and exiting a point. % That is, \(\psi_k\) is the angle between the lines joining \(z_k\) to \(z_{k-1}\) and \(z_{k+1}\). % The first index is \(1\). % \begin{macrocode} -\array_new:N \l_hobby_psi_array +\array_new:N \g__hobby_psi_array % \end{macrocode} % \end{macro} % -% \begin{macro}{\l_hobby_theta_array} -% \Verb+\l_hobby_theta_array+ is an array holding the angles of the outgoing control points for the generated path. +% \begin{macro}{\g__hobby_theta_array} +% \Verb+\g__hobby_theta_array+ is an array holding the angles of the outgoing control points for the generated path. % These are measured relative to the line joining the point to the next point on the path. % The first index is \(0\). % \begin{macrocode} -\array_new:N \l_hobby_theta_array +\array_new:N \g__hobby_theta_array % \end{macrocode} % \end{macro} % -% \begin{macro}{\l_hobby_phi_array} -% \Verb+\l_hobby_phi_array+ is an array holding the angles of the incoming control points for the generated path. +% \begin{macro}{\g__hobby_phi_array} +% \Verb+\g__hobby_phi_array+ is an array holding the angles of the incoming control points for the generated path. % These are measured relative to the line joining the point to the previous point on the path. % The first index is \(1\). % \begin{macrocode} -\array_new:N \l_hobby_phi_array +\array_new:N \g__hobby_phi_array % \end{macrocode} % \end{macro} % -% \begin{macro}{\l_hobby_sigma_array} -% \Verb+\l_hobby_sigma_array+ is an array holding the lengths of the outgoing control points for the generated path. +% \begin{macro}{\g__hobby_sigma_array} +% \Verb+\g__hobby_sigma_array+ is an array holding the lengths of the outgoing control points for the generated path. % The units are such that the length of the line to the next specified point is one unit. % \begin{macrocode} -\array_new:N \l_hobby_sigma_array +\array_new:N \g__hobby_sigma_array % \end{macrocode} % \end{macro} % -% \begin{macro}{\l_hobby_rho_array} -% \Verb+\l_hobby_rho_array+ is an array holding the lengths of the incoming control points for the generated path. +% \begin{macro}{\g__hobby_rho_array} +% \Verb+\g__hobby_rho_array+ is an array holding the lengths of the incoming control points for the generated path. % The units are such that the length of the line to the previous specified point is one unit. % \begin{macrocode} -\array_new:N \l_hobby_rho_array +\array_new:N \g__hobby_rho_array % \end{macrocode} % \end{macro} % -% \begin{macro}{\l_hobby_controla_array} -% \Verb+\l_hobby_controla_array+ is an array holding the coordinates of the first control points on the curves. -% The format is the same as for \Verb+\l_hobby_points_array+. +% \begin{macro}{\g__hobby_controla_array} +% \Verb+\g__hobby_controla_array+ is an array holding the coordinates of the first control points on the curves. +% The format is the same as for \Verb+\g__hobby_points_array+. % \begin{macrocode} -\array_new:N \l_hobby_controla_array +\array_new:N \g__hobby_controla_array % \end{macrocode} % \end{macro} % -% \begin{macro}{\l_hobby_controlb_array} -% \Verb+\l_hobby_controlb_array+ is an array holding the coordinates of the second control points on the curves. -% The format is the same as for \Verb+\l_hobby_points_array+. +% \begin{macro}{\g__hobby_controlb_array} +% \Verb+\g__hobby_controlb_array+ is an array holding the coordinates of the second control points on the curves. +% The format is the same as for \Verb+\g__hobby_points_array+. % \begin{macrocode} -\array_new:N \l_hobby_controlb_array +\array_new:N \g__hobby_controlb_array % \end{macrocode} % \end{macro} % @@ -425,6 +423,20 @@ and the derived files hobby.code.tex % \end{macrocode} % \end{macro} % +% \begin{macro}{\l_hobby_tempa_tl} +% \Verb+\l_hobby_tempa_tl+ is a temporary variable of type \Verb+tl+. +% \begin{macrocode} +\fp_new:N \l_hobby_tempa_tl +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\l_hobby_tempb_tl} +% \Verb+\l_hobby_tempb_tl+ is a temporary variable of type \Verb+tl+. +% \begin{macrocode} +\fp_new:N \l_hobby_tempb_tl +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\l_hobby_tempa_fp} % \Verb+\l_hobby_tempa_fp+ is a temporary variable of type \Verb+fp+. % \begin{macrocode} @@ -460,56 +472,56 @@ and the derived files hobby.code.tex % \end{macrocode} % \end{macro} % -% \begin{macro}{\l_hobby_in_curl_fp} -% \Verb+\l_hobby_in_curl_fp+ is the ``curl'' at the end of an open path. +% \begin{macro}{\g__hobby_in_curl_fp} +% \Verb+\g__hobby_in_curl_fp+ is the ``curl'' at the end of an open path. % This is used if the angle at the end is not specified. % \begin{macrocode} -\fp_new:N \l_hobby_in_curl_fp -\fp_set:Nn \l_hobby_in_curl_fp {1} +\fp_new:N \g__hobby_in_curl_fp +\fp_gset:Nn \g__hobby_in_curl_fp {1} % \end{macrocode} % \end{macro} % -% \begin{macro}{\l_hobby_out_curl_fp} -% \Verb+\l_hobby_out_curl_fp+ is the ``curl'' at the start of an open path. +% \begin{macro}{\g__hobby_out_curl_fp} +% \Verb+\g__hobby_out_curl_fp+ is the ``curl'' at the start of an open path. % This is used if the angle at the start is not specified. % \begin{macrocode} -\fp_new:N \l_hobby_out_curl_fp -\fp_set:Nn \l_hobby_out_curl_fp {1} +\fp_new:N \g__hobby_out_curl_fp +\fp_gset:Nn \g__hobby_out_curl_fp {1} % \end{macrocode} % \end{macro} % -% \begin{macro}{\l_hobby_in_angle_fp} -% \Verb+\l_hobby_in_angle_fp+ is the angle at the end of an open path. +% \begin{macro}{\g__hobby_in_angle_fp} +% \Verb+\g__hobby_in_angle_fp+ is the angle at the end of an open path. % If this is not specified, it will be computed automatically. % It is set to \Verb+\c_inf_fp+ to allow easy detection of when it has been specified. % \begin{macrocode} -\fp_new:N \l_hobby_in_angle_fp -\fp_set_eq:NN \l_hobby_in_angle_fp \c_inf_fp +\fp_new:N \g__hobby_in_angle_fp +\fp_gset_eq:NN \g__hobby_in_angle_fp \c_inf_fp % \end{macrocode} % \end{macro} % -% \begin{macro}{\l_hobby_out_angle_fp} -% \Verb+\l_hobby_out_angle_fp+ is the angle at the start of an open path. +% \begin{macro}{\g__hobby_out_angle_fp} +% \Verb+\g__hobby_out_angle_fp+ is the angle at the start of an open path. % If this is not specified, it will be computed automatically. % It is set to \Verb+\c_inf_fp+ to allow easy detection of when it has been specified. % \begin{macrocode} -\fp_new:N \l_hobby_out_angle_fp -\fp_set_eq:NN \l_hobby_out_angle_fp \c_inf_fp +\fp_new:N \g__hobby_out_angle_fp +\fp_gset_eq:NN \g__hobby_out_angle_fp \c_inf_fp % \end{macrocode} % \end{macro} % -% \begin{macro}{\l_hobby_npoints_int} -% \Verb+\l_hobby_npoints_int+ is one less than the number of points on the curve. +% \begin{macro}{\g__hobby_npoints_int} +% \Verb+\g__hobby_npoints_int+ is one less than the number of points on the curve. % As our list of points starts at \(0\), this is the index of the last point. -% In the algorithm for a closed curve, some points are repeated whereupon this is incremented so that it is always the index of the last point. +% In the algorithm for a closed curve, some points are repeated whereupon this is incremented so that it is always the index of the last point. % \begin{macrocode} -\int_new:N \l_hobby_npoints_int +\int_new:N \g__hobby_npoints_int % \end{macrocode} % \end{macro} % -% \begin{macro}{\l_hobby_draw_int} +% \begin{macro}{\g__hobby_draw_int} % \begin{macrocode} -\int_new:N \l_hobby_draw_int +\int_new:N \g__hobby_draw_int % \end{macrocode} % \end{macro} % @@ -517,8 +529,10 @@ and the derived files hobby.code.tex % Using keys makes it easier to pass points from the algorithm code to the calling code and vice versa without either knowing too much about the other. % \begin{macrocode} \keys_define:nn {hobby / read in all} { - x .fp_set:N = \l_hobby_tempa_fp, - y .fp_set:N = \l_hobby_tempb_fp, + point .code:n = { + \fp_set:Nn \l_hobby_tempa_fp {\clist_item:nn {#1} {1}} + \fp_set:Nn \l_hobby_tempb_fp {\clist_item:nn {#1} {2}} + }, tension~out .fp_set:N = \l_hobby_tempc_fp, tension~in .fp_set:N = \l_hobby_tempd_fp, excess~angle .fp_set:N = \l_hobby_temps_fp, @@ -529,31 +543,31 @@ and the derived files hobby.code.tex blank .default:n = false, invert~soft~blanks .choice:, invert~soft~blanks / true .code:n = { - \int_gset:Nn \l_hobby_draw_int {0} + \int_gset:Nn \g__hobby_draw_int {0} }, invert~soft~blanks / false .code:n = { - \int_gset:Nn \l_hobby_draw_int {1} + \int_gset:Nn \g__hobby_draw_int {1} }, invert~soft~blanks .default:n = true, tension~out .default:n = 1, tension~in .default:n = 1, excess~angle .default:n = 0, - in~angle .fp_gset:N = \l_hobby_in_angle_fp, - out~angle .fp_gset:N = \l_hobby_out_angle_fp, - in~curl .fp_gset:N = \l_hobby_in_curl_fp, - out~curl .fp_gset:N = \l_hobby_out_curl_fp, - closed .bool_gset:N = \l_hobby_closed_bool, + in~angle .fp_gset:N = \g__hobby_in_angle_fp, + out~angle .fp_gset:N = \g__hobby_out_angle_fp, + in~curl .fp_gset:N = \g__hobby_in_curl_fp, + out~curl .fp_gset:N = \g__hobby_out_curl_fp, + closed .bool_gset:N = \g__hobby_closed_bool, closed .default:n = true, - disjoint .bool_gset:N = \l_hobby_disjoint_bool, + disjoint .bool_gset:N = \g__hobby_disjoint_bool, disjoint .default:n = true, break~default .code:n = { - \keys_define:nn { hobby / read in all } + \keys_define:nn { hobby / read in all } { break .default:n = #1 } }, blank~default .code:n = { - \keys_define:nn { hobby / read in all } + \keys_define:nn { hobby / read in all } { blank .default:n = #1 } @@ -563,32 +577,32 @@ and the derived files hobby.code.tex % There are certain other parameters that can be set for a given curve. % \begin{macrocode} \keys_define:nn { hobby / read in params} { - in~angle .fp_gset:N = \l_hobby_in_angle_fp, - out~angle .fp_gset:N = \l_hobby_out_angle_fp, - in~curl .fp_gset:N = \l_hobby_in_curl_fp, - out~curl .fp_gset:N = \l_hobby_out_curl_fp, - closed .bool_gset:N = \l_hobby_closed_bool, + in~angle .fp_gset:N = \g__hobby_in_angle_fp, + out~angle .fp_gset:N = \g__hobby_out_angle_fp, + in~curl .fp_gset:N = \g__hobby_in_curl_fp, + out~curl .fp_gset:N = \g__hobby_out_curl_fp, + closed .bool_gset:N = \g__hobby_closed_bool, closed .default:n = true, - disjoint .bool_gset:N = \l_hobby_disjoint_bool, + disjoint .bool_gset:N = \g__hobby_disjoint_bool, disjoint .default:n = true, break~default .code:n = { - \keys_define:nn { hobby / read in all } + \keys_define:nn { hobby / read in all } { break .default:n = #1 } }, blank~default .code:n = { - \keys_define:nn { hobby / read in all } + \keys_define:nn { hobby / read in all } { blank .default:n = #1 } }, invert~soft~blanks .choice:, invert~soft~blanks / true .code:n = { - \int_gset:Nn \l_hobby_draw_int {0} + \int_gset:Nn \g__hobby_draw_int {0} }, invert~soft~blanks / false .code:n = { - \int_gset:Nn \l_hobby_draw_int {1} + \int_gset:Nn \g__hobby_draw_int {1} }, invert~soft~blanks .default:n = true, } @@ -596,22 +610,22 @@ and the derived files hobby.code.tex % \begin{macro}{\hobby_distangle:n} % Computes the distance and angle between successive points. % The argument given is the index of the current point. -% Assumptions: the points are in \Verb+\l_hobby_points_x_array+ and \Verb+\l_hobby_points_y_array+ and the index of the last point is \Verb+\l_hobby_npoints_int+. +% Assumptions: the points are in \Verb+\g__hobby_points_x_array+ and \Verb+\g__hobby_points_y_array+ and the index of the last point is \Verb+\g__hobby_npoints_int+. % \begin{macrocode} \cs_set:Nn \hobby_distangle:n { \fp_set:Nn \l_hobby_tempa_fp { - (\array_get:Nn \l_hobby_points_x_array {#1 + 1}) - - (\array_get:Nn \l_hobby_points_x_array {#1})} + (\array_get:Nn \g__hobby_points_x_array {#1 + 1}) + - (\array_get:Nn \g__hobby_points_x_array {#1})} \fp_set:Nn \l_hobby_tempb_fp { - (\array_get:Nn \l_hobby_points_y_array {#1 + 1}) - - (\array_get:Nn \l_hobby_points_y_array {#1})} + (\array_get:Nn \g__hobby_points_y_array {#1 + 1}) + - (\array_get:Nn \g__hobby_points_y_array {#1})} \fp_set:Nn \l_hobby_tempc_fp { atan ( \l_hobby_tempb_fp, \l_hobby_tempa_fp ) } \fp_veclen:NVV \l_hobby_tempd_fp \l_hobby_tempa_fp \l_hobby_tempb_fp - \array_push:Nx \l_hobby_angles_array {\fp_to_tl:N \l_hobby_tempc_fp} - \array_push:Nx \l_hobby_distances_array {\fp_to_tl:N \l_hobby_tempd_fp} + \array_gpush:Nx \g__hobby_angles_array {\fp_to_tl:N \l_hobby_tempc_fp} + \array_gpush:Nx \g__hobby_distances_array {\fp_to_tl:N \l_hobby_tempd_fp} } % \end{macrocode} % \end{macro} @@ -647,13 +661,13 @@ and the derived files hobby.code.tex % \begin{macrocode} \cs_new_protected:Npn \hobby_append_point_copy:n #1 { - \hobby_append_point_copy_aux:Nn \l_hobby_points_array {#1} - \hobby_append_point_copy_aux:Nn \l_hobby_points_x_array {#1} - \hobby_append_point_copy_aux:Nn \l_hobby_points_y_array {#1} - \hobby_append_point_copy_aux:Nn \l_hobby_tension_in_array {#1} - \hobby_append_point_copy_aux:Nn \l_hobby_tension_out_array {#1} - \hobby_append_point_copy_aux:Nn \l_hobby_excess_angle_array {#1} - \hobby_append_point_copy_aux:Nn \l_hobby_actions_array {#1} + \hobby_append_point_copy_aux:Nn \g__hobby_points_array {#1} + \hobby_append_point_copy_aux:Nn \g__hobby_points_x_array {#1} + \hobby_append_point_copy_aux:Nn \g__hobby_points_y_array {#1} + \hobby_append_point_copy_aux:Nn \g__hobby_tension_in_array {#1} + \hobby_append_point_copy_aux:Nn \g__hobby_tension_out_array {#1} + \hobby_append_point_copy_aux:Nn \g__hobby_excess_angle_array {#1} + \hobby_append_point_copy_aux:Nn \g__hobby_actions_array {#1} } \cs_new_protected:Npn \hobby_append_point_copy_aux:Nn #1#2 { \array_gpush:Nx #1 { \array_get:Nn #1 {#2} } } @@ -666,17 +680,17 @@ and the derived files hobby.code.tex % So these must be set up by a wrapper function which then calls this one. % The list of required information is: % \begin{enumerate} -% \item \Verb+\l_hobby_points_x_array+ -% \item \Verb+\l_hobby_points_y_array+ -% \item \Verb+\l_hobby_tension_out_array+ -% \item \Verb+\l_hobby_tension_in_array+ -% \item \Verb+\l_hobby_excess_angle_array+ -% \item \Verb+\l_hobby_in_curl_fp+ -% \item \Verb+\l_hobby_out_curl_fp+ -% \item \Verb+\l_hobby_in_angle_fp+ -% \item \Verb+\l_hobby_out_angle_fp+ -% \item \Verb+\l_hobby_closed_bool+ -% \item \Verb+\l_hobby_actions_array+ +% \item \Verb+\g__hobby_points_x_array+ +% \item \Verb+\g__hobby_points_y_array+ +% \item \Verb+\g__hobby_tension_out_array+ +% \item \Verb+\g__hobby_tension_in_array+ +% \item \Verb+\g__hobby_excess_angle_array+ +% \item \Verb+\g__hobby_in_curl_fp+ +% \item \Verb+\g__hobby_out_curl_fp+ +% \item \Verb+\g__hobby_in_angle_fp+ +% \item \Verb+\g__hobby_out_angle_fp+ +% \item \Verb+\g__hobby_closed_bool+ +% \item \Verb+\g__hobby_actions_array+ % \end{enumerate} % % \begin{macrocode} @@ -687,22 +701,22 @@ and the derived files hobby.code.tex % To do this, we need to make the end node an internal node by repeating the \(z_1\) node as the \(z_{n+1}\)th node. % We also check that the last (\(z_n\)) and first (\(z_0\)) nodes are the same, otherwise we repeat the \(z_0\) node as well. % \begin{macrocode} -\bool_if:NT \l_hobby_closed_bool { +\bool_if:NT \g__hobby_closed_bool { % \end{macrocode} % Are the \(x\)-values of the first and last points different? % \begin{macrocode} - \fp_compare:nTF {(\array_get:Nn \l_hobby_points_x_array {0}) + \fp_compare:nTF {(\array_get:Nn \g__hobby_points_x_array {0}) = - (\array_top:N \l_hobby_points_x_array)} + (\array_top:N \g__hobby_points_x_array)} { % \end{macrocode} % No, so compare the \(y\)-values. % Are the \(y\)-values of the first and last points different? % \begin{macrocode} \fp_compare:nF { - \array_get:Nn \l_hobby_points_y_array {0} + \array_get:Nn \g__hobby_points_y_array {0} = - \array_top:N \l_hobby_points_y_array + \array_top:N \g__hobby_points_y_array } { % \end{macrocode} @@ -724,29 +738,29 @@ and the derived files hobby.code.tex } % \end{macrocode} % -% Set \Verb+\l_hobby_npoints_int+ to the number of points (minus one). +% Set \Verb+\g__hobby_npoints_int+ to the number of points (minus one). % \begin{macrocode} -\int_gset:Nn \l_hobby_npoints_int {\array_length:N \l_hobby_points_y_array} +\int_gset:Nn \g__hobby_npoints_int {\array_length:N \g__hobby_points_y_array} % \end{macrocode} % At this point, we need to decide what to do. % This will depend on whether we have any intermediate points. % \begin{macrocode} -\int_compare:nNnTF {\l_hobby_npoints_int} = {0} { +\int_compare:nNnTF {\g__hobby_npoints_int} = {0} { % \end{macrocode} % Only one point, do nothing % \begin{macrocode} } { - \int_compare:nNnTF {\l_hobby_npoints_int} = {1} { + \int_compare:nNnTF {\g__hobby_npoints_int} = {1} { % \end{macrocode} % Only two points, skip processing. % Just need to set the incoming and outgoing angles % \begin{macrocode} \hobby_distangle:n {0} -\fp_compare:nF { \l_hobby_out_angle_fp == \c_inf_fp } +\fp_compare:nF { \g__hobby_out_angle_fp == \c_inf_fp } { - \fp_set:Nn \l_hobby_tempa_fp { \l_hobby_out_angle_fp - - \array_get:Nn \l_hobby_angles_array {0}} + \fp_set:Nn \l_hobby_tempa_fp { \g__hobby_out_angle_fp + - \array_get:Nn \g__hobby_angles_array {0}} % \end{macrocode} % We want to ensure that these angles lie in the range \((-\pi,\pi]\). % So if the angle is bigger than \(\pi\), we subtract \(2 \pi\). @@ -763,24 +777,24 @@ and the derived files hobby.code.tex { \fp_add:Nn \l_hobby_tempa_fp {2 * \c_pi_fp} } - \array_put:Nnx \l_hobby_theta_array {0} {\fp_to_tl:N \l_hobby_tempa_fp} - \fp_compare:nT { \l_hobby_in_angle_fp == \c_inf_fp } + \array_gput:Nnx \g__hobby_theta_array {0} {\fp_to_tl:N \l_hobby_tempa_fp} + \fp_compare:nT { \g__hobby_in_angle_fp == \c_inf_fp } { %^^A \fp_mul:Nn \l_hobby_tempa_fp {-1} - \array_put:Nnx \l_hobby_phi_array {1}{ \fp_to_tl:N \l_hobby_tempa_fp} + \array_gput:Nnx \g__hobby_phi_array {1}{ \fp_to_tl:N \l_hobby_tempa_fp} } } -\fp_compare:nTF { \l_hobby_in_angle_fp == \c_inf_fp } +\fp_compare:nTF { \g__hobby_in_angle_fp == \c_inf_fp } { - \fp_compare:nT { \l_hobby_out_angle_fp == \c_inf_fp } + \fp_compare:nT { \g__hobby_out_angle_fp == \c_inf_fp } { - \array_put:Nnx \l_hobby_phi_array {1} {0} - \array_put:Nnx \l_hobby_theta_array {0} {0} + \array_gput:Nnx \g__hobby_phi_array {1} {0} + \array_gput:Nnx \g__hobby_theta_array {0} {0} } } { - \fp_set:Nn \l_hobby_tempa_fp { - \l_hobby_in_angle_fp + \c_pi_fp -+ (\array_get:Nn \l_hobby_angles_array {0})} + \fp_set:Nn \l_hobby_tempa_fp { - \g__hobby_in_angle_fp + \c_pi_fp ++ (\array_get:Nn \g__hobby_angles_array {0})} \fp_compare:nT {\l_hobby_tempa_fp > \c_pi_fp } { \fp_sub:Nn \l_hobby_tempa_fp {2 * \c_pi_fp} @@ -790,12 +804,12 @@ and the derived files hobby.code.tex \fp_add:Nn \l_hobby_tempa_fp {2 * \c_pi_fp} } - \array_put:Nnx \l_hobby_phi_array {1} + \array_gput:Nnx \g__hobby_phi_array {1} {\fp_to_tl:N \l_hobby_tempa_fp} - \fp_compare:nT { \l_hobby_out_angle_fp == \c_inf_fp } + \fp_compare:nT { \g__hobby_out_angle_fp == \c_inf_fp } { %^^A \fp_mul:Nn \l_hobby_tempa_fp {-1} - \array_put:Nnx \l_hobby_theta_array {0}{ \fp_to_tl:N \l_hobby_tempa_fp} + \array_gput:Nnx \g__hobby_theta_array {0}{ \fp_to_tl:N \l_hobby_tempa_fp} } } @@ -811,7 +825,7 @@ and the derived files hobby.code.tex } % \end{macrocode} % \end{macro} -% +% % % \begin{macro}{\hobby_compute_path:} % This is the path builder where we have enough points to run the algorithm. @@ -822,16 +836,16 @@ and the derived files hobby.code.tex % Our first step is to go through the list of points and compute the distances and angles between successive points. % Thus \(d_i\) is the distance from \(z_i\) to \(z_{i+1}\) and the angle is the angle of the line from \(z_i\) to \(z_{i+1}\). % \begin{macrocode} -\int_step_function:nnnN {0} {1} {\l_hobby_npoints_int - 1} \hobby_distangle:n +\int_step_function:nnnN {0} {1} {\g__hobby_npoints_int - 1} \hobby_distangle:n % \end{macrocode} % % For the majority of the code, we're only really interested in the differences of the angles. % So for each internal point we compute the differences in the angles. % \begin{macrocode} - \int_step_inline:nnnn {1} {1} {\l_hobby_npoints_int - 1} { + \int_step_inline:nnnn {1} {1} {\g__hobby_npoints_int - 1} { \fp_set:Nx \l_hobby_tempa_fp { - \array_get:Nn \l_hobby_angles_array {##1} - - \array_get:Nn \l_hobby_angles_array {##1 - 1}} + \array_get:Nn \g__hobby_angles_array {##1} + - \array_get:Nn \g__hobby_angles_array {##1 - 1}} % \end{macrocode} % We want to ensure that these angles lie in the range \((-\pi,\pi]\). % So if the angle is bigger than \(\pi\), we subtract \(2 \pi\). @@ -851,14 +865,14 @@ and the derived files hobby.code.tex } {} % \end{macrocode} -% The wrapping routine might not get it right at the edges so we add in the override. +% The wrapping routine might not get it right at the edges so we add in the override. % \begin{macrocode} -\array_get:NnNTF \l_hobby_excess_angle_array {##1} \l_tmpa_tl { +\array_get:NnNTF \g__hobby_excess_angle_array {##1} \l_tmpa_tl { \fp_add:Nn \l_hobby_tempa_fp {2 * \c_pi_fp * \l_tmpa_tl} }{} % \end{macrocode} % \begin{macrocode} - \array_put:Nnx \l_hobby_psi_array {##1}{\fp_to_tl:N \l_hobby_tempa_fp} + \array_gput:Nnx \g__hobby_psi_array {##1}{\fp_to_tl:N \l_hobby_tempa_fp} } % \end{macrocode} % @@ -866,11 +880,11 @@ and the derived files hobby.code.tex % We start with the subdiagonal. % This is indexed from \(1\) to \(n-1\). % \begin{macrocode} - \int_step_inline:nnnn {1} {1} {\l_hobby_npoints_int - 1} { - \array_put:Nnx \l_hobby_matrix_a_array {##1} {\fp_to_tl:n { - \array_get:Nn \l_hobby_tension_in_array {##1}^2 - * \array_get:Nn \l_hobby_distances_array {##1} - * \array_get:Nn \l_hobby_tension_in_array {##1 + 1} + \int_step_inline:nnnn {1} {1} {\g__hobby_npoints_int - 1} { + \array_gput:Nnx \g__hobby_matrix_a_array {##1} {\fp_to_tl:n { + \array_get:Nn \g__hobby_tension_in_array {##1}^2 + * \array_get:Nn \g__hobby_distances_array {##1} + * \array_get:Nn \g__hobby_tension_in_array {##1 + 1} }} } % \end{macrocode} @@ -878,30 +892,30 @@ and the derived files hobby.code.tex % Next, we attack main diagonal. % We might need to adjust the first and last terms, but we'll do that in a minute. % \begin{macrocode} - \int_step_inline:nnnn {1} {1} {\l_hobby_npoints_int - 1} { + \int_step_inline:nnnn {1} {1} {\g__hobby_npoints_int - 1} { - \array_put:Nnx \l_hobby_matrix_b_array {##1} {\fp_to_tl:n -{(3 * (\array_get:Nn \l_hobby_tension_in_array {##1 + 1}) - 1) * - (\array_get:Nn \l_hobby_tension_out_array {##1})^2 * -(\array_get:Nn \l_hobby_tension_out_array {##1 - 1}) -* ( \array_get:Nn \l_hobby_distances_array {##1 - 1}) + \array_gput:Nnx \g__hobby_matrix_b_array {##1} {\fp_to_tl:n +{(3 * (\array_get:Nn \g__hobby_tension_in_array {##1 + 1}) - 1) * + (\array_get:Nn \g__hobby_tension_out_array {##1})^2 * +(\array_get:Nn \g__hobby_tension_out_array {##1 - 1}) +* ( \array_get:Nn \g__hobby_distances_array {##1 - 1}) + -(3 * (\array_get:Nn \l_hobby_tension_out_array {##1 - 1}) - 1) -* (\array_get:Nn \l_hobby_tension_in_array {##1})^2 -* (\array_get:Nn \l_hobby_tension_in_array {##1 + 1}) -* (\array_get:Nn \l_hobby_distances_array {##1})} +(3 * (\array_get:Nn \g__hobby_tension_out_array {##1 - 1}) - 1) +* (\array_get:Nn \g__hobby_tension_in_array {##1})^2 +* (\array_get:Nn \g__hobby_tension_in_array {##1 + 1}) +* (\array_get:Nn \g__hobby_distances_array {##1})} } } % \end{macrocode} % % Next, the superdiagonal. % \begin{macrocode} - \int_step_inline:nnnn {1} {1} {\l_hobby_npoints_int - 2} { + \int_step_inline:nnnn {1} {1} {\g__hobby_npoints_int - 2} { - \array_put:Nnx \l_hobby_matrix_c_array {##1} {\fp_to_tl:n -{(\array_get:Nn \l_hobby_tension_in_array {##1})^2 -* (\array_get:Nn \l_hobby_tension_in_array {##1 - 1}) -* (\array_get:Nn \l_hobby_distances_array {##1 - 1}) + \array_gput:Nnx \g__hobby_matrix_c_array {##1} {\fp_to_tl:n +{(\array_get:Nn \g__hobby_tension_in_array {##1})^2 +* (\array_get:Nn \g__hobby_tension_in_array {##1 - 1}) +* (\array_get:Nn \g__hobby_distances_array {##1 - 1}) }} } @@ -909,19 +923,19 @@ and the derived files hobby.code.tex % % Lastly (before the adjustments), the target vector. % \begin{macrocode} - \int_step_inline:nnnn {1} {1} {\l_hobby_npoints_int - 2} { + \int_step_inline:nnnn {1} {1} {\g__hobby_npoints_int - 2} { - \array_put:Nnx \l_hobby_matrix_d_array {##1} {\fp_to_tl:n + \array_gput:Nnx \g__hobby_matrix_d_array {##1} {\fp_to_tl:n { -- (\array_get:Nn \l_hobby_psi_array {##1 + 1}) -* (\array_get:Nn \l_hobby_tension_out_array {##1})^2 -* (\array_get:Nn \l_hobby_tension_out_array {##1 - 1}) -* (\array_get:Nn \l_hobby_distances_array {##1 - 1}) -- (3 * (\array_get:Nn \l_hobby_tension_out_array {##1 - 1}) - 1) -* (\array_get:Nn \l_hobby_psi_array {##1}) -* (\array_get:Nn \l_hobby_tension_in_array {##1})^2 -* (\array_get:Nn \l_hobby_tension_in_array {##1 + 1}) -* (\array_get:Nn \l_hobby_distances_array {##1}) +- (\array_get:Nn \g__hobby_psi_array {##1 + 1}) +* (\array_get:Nn \g__hobby_tension_out_array {##1})^2 +* (\array_get:Nn \g__hobby_tension_out_array {##1 - 1}) +* (\array_get:Nn \g__hobby_distances_array {##1 - 1}) +- (3 * (\array_get:Nn \g__hobby_tension_out_array {##1 - 1}) - 1) +* (\array_get:Nn \g__hobby_psi_array {##1}) +* (\array_get:Nn \g__hobby_tension_in_array {##1})^2 +* (\array_get:Nn \g__hobby_tension_in_array {##1 + 1}) +* (\array_get:Nn \g__hobby_distances_array {##1}) } } } @@ -930,51 +944,51 @@ and the derived files hobby.code.tex % Next, there are some adjustments at the ends. % These differ depending on whether the path is open or closed. % \begin{macrocode} -\bool_if:NTF \l_hobby_closed_bool { +\bool_if:NTF \g__hobby_closed_bool { % \end{macrocode} % Closed path % \begin{macrocode} -\array_put:Nnx \l_hobby_matrix_c_array {0} {\fp_to_tl:n { -- (\array_get:Nn \l_hobby_distances_array {\l_hobby_npoints_int - 2}) -* (\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int - 2}) -* (\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int - 1})^2 +\array_gput:Nnx \g__hobby_matrix_c_array {0} {\fp_to_tl:n { +- (\array_get:Nn \g__hobby_distances_array {\g__hobby_npoints_int - 2}) +* (\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int - 2}) +* (\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int - 1})^2 }} -\array_put:Nnn \l_hobby_matrix_b_array {0} {1} -\array_put:Nnn \l_hobby_matrix_d_array {0} {0} +\array_gput:Nnn \g__hobby_matrix_b_array {0} {1} +\array_gput:Nnn \g__hobby_matrix_d_array {0} {0} -\array_put:Nnx \l_hobby_matrix_b_array {\l_hobby_npoints_int - 1} {\fp_to_tl:n { -(\array_get:Nn \l_hobby_matrix_b_array {\l_hobby_npoints_int - 1}) -+ 1 +\array_gput:Nnx \g__hobby_matrix_b_array {\g__hobby_npoints_int - 1} {\fp_to_tl:n { +(\array_get:Nn \g__hobby_matrix_b_array {\g__hobby_npoints_int - 1}) ++ 1 }} - \array_put:Nnx \l_hobby_matrix_d_array {\l_hobby_npoints_int - 1} {\fp_to_tl:n { -- (\array_get:Nn \l_hobby_psi_array {1}) -* (\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int -1})^2 -* (\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int -2}) -* (\array_get:Nn \l_hobby_distances_array {\l_hobby_npoints_int - 2}) -- (3 * (\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int - 2}) - 1) -* (\array_get:Nn \l_hobby_psi_array {\l_hobby_npoints_int - 1}) -* (\array_get:Nn \l_hobby_tension_in_array {\l_hobby_npoints_int - 1})^2 -* (\array_get:Nn \l_hobby_tension_in_array {\l_hobby_npoints_int}) -* (\array_get:Nn \l_hobby_distances_array {\l_hobby_npoints_int -1}) + \array_gput:Nnx \g__hobby_matrix_d_array {\g__hobby_npoints_int - 1} {\fp_to_tl:n { +- (\array_get:Nn \g__hobby_psi_array {1}) +* (\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int -1})^2 +* (\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int -2}) +* (\array_get:Nn \g__hobby_distances_array {\g__hobby_npoints_int - 2}) +- (3 * (\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int - 2}) - 1) +* (\array_get:Nn \g__hobby_psi_array {\g__hobby_npoints_int - 1}) +* (\array_get:Nn \g__hobby_tension_in_array {\g__hobby_npoints_int - 1})^2 +* (\array_get:Nn \g__hobby_tension_in_array {\g__hobby_npoints_int}) +* (\array_get:Nn \g__hobby_distances_array {\g__hobby_npoints_int -1}) } } % \end{macrocode} % We also need to populate the \(u\)-vector % \begin{macrocode} - \array_put:Nnn \l_hobby_vector_u_array {0} {1} -\array_put:Nnn \l_hobby_vector_u_array {\l_hobby_npoints_int - 1} {1} - \int_step_inline:nnnn {1} {1} {\l_hobby_npoints_int - 2} { - \array_put:Nnn \l_hobby_vector_u_array {##1} {0} + \array_gput:Nnn \g__hobby_vector_u_array {0} {1} +\array_gput:Nnn \g__hobby_vector_u_array {\g__hobby_npoints_int - 1} {1} + \int_step_inline:nnnn {1} {1} {\g__hobby_npoints_int - 2} { + \array_gput:Nnn \g__hobby_vector_u_array {##1} {0} } % \end{macrocode} % And define the significant entry in the \(v\)-vector. % \begin{macrocode} \fp_set:Nn \l_hobby_matrix_v_fp { -(\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int -1})^2 -* (\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int -2}) -* (\array_get:Nn \l_hobby_distances_array {\l_hobby_npoints_int -2}) +(\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int -1})^2 +* (\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int -2}) +* (\array_get:Nn \g__hobby_distances_array {\g__hobby_npoints_int -2}) } } { @@ -982,39 +996,39 @@ and the derived files hobby.code.tex % Open path. % First, we test to see if \(\theta_0\) has been specified. % \begin{macrocode} -\fp_compare:nTF { \l_hobby_out_angle_fp == \c_inf_fp } +\fp_compare:nTF { \g__hobby_out_angle_fp == \c_inf_fp } { - \array_put:Nnx \l_hobby_matrix_b_array {0} {\fp_to_tl:n { - (\array_get:Nn \l_hobby_tension_in_array {1})^3 -* \l_hobby_in_curl_fp + \array_gput:Nnx \g__hobby_matrix_b_array {0} {\fp_to_tl:n { + (\array_get:Nn \g__hobby_tension_in_array {1})^3 +* \g__hobby_in_curl_fp + -(3 * (\array_get:Nn \l_hobby_tension_in_array {1}) - 1) -* (\array_get:Nn \l_hobby_tension_out_array {0})^3 +(3 * (\array_get:Nn \g__hobby_tension_in_array {1}) - 1) +* (\array_get:Nn \g__hobby_tension_out_array {0})^3 }} - \array_put:Nnx \l_hobby_matrix_c_array {0} {\fp_to_tl:n { - (\array_get:Nn \l_hobby_tension_out_array {0})^3 + \array_gput:Nnx \g__hobby_matrix_c_array {0} {\fp_to_tl:n { + (\array_get:Nn \g__hobby_tension_out_array {0})^3 + -(3 * (\array_get:Nn \l_hobby_tension_out_array {0}) - 1) -* (\array_get:Nn \l_hobby_tension_in_array {1})^3 -* \l_hobby_in_curl_fp +(3 * (\array_get:Nn \g__hobby_tension_out_array {0}) - 1) +* (\array_get:Nn \g__hobby_tension_in_array {1})^3 +* \g__hobby_in_curl_fp }} - \array_put:Nnx \l_hobby_matrix_d_array {0} {\fp_to_tl:n { --( (\array_get:Nn \l_hobby_tension_out_array {0})^3 + \array_gput:Nnx \g__hobby_matrix_d_array {0} {\fp_to_tl:n { +-( (\array_get:Nn \g__hobby_tension_out_array {0})^3 + -(3 * (\array_get:Nn \l_hobby_tension_out_array {0}) - 1) -* (\array_get:Nn \l_hobby_tension_in_array {1})^3 -* \l_hobby_in_curl_fp) -* (\array_get:Nn \l_hobby_psi_array {1}) +(3 * (\array_get:Nn \g__hobby_tension_out_array {0}) - 1) +* (\array_get:Nn \g__hobby_tension_in_array {1})^3 +* \g__hobby_in_curl_fp) +* (\array_get:Nn \g__hobby_psi_array {1}) }} - + } { - \array_put:Nnn \l_hobby_matrix_b_array {0} {1} - \array_put:Nnn \l_hobby_matrix_c_array {0} {0} - \fp_set:Nn \l_hobby_tempa_fp { \l_hobby_out_angle_fp - - \array_get:Nn \l_hobby_angles_array {0}} + \array_gput:Nnn \g__hobby_matrix_b_array {0} {1} + \array_gput:Nnn \g__hobby_matrix_c_array {0} {0} + \fp_set:Nn \l_hobby_tempa_fp { \g__hobby_out_angle_fp + - \array_get:Nn \g__hobby_angles_array {0}} % \end{macrocode} % We want to ensure that these angles lie in the range \((-\pi,\pi]\). % So if the angle is bigger than \(\pi\), we subtract \(2 \pi\). @@ -1031,46 +1045,46 @@ and the derived files hobby.code.tex { \fp_add:Nn \l_hobby_tempa_fp {2 * \c_pi_fp} } - \array_put:Nnx \l_hobby_matrix_d_array {0} {\fp_to_tl:N \l_hobby_tempa_fp} + \array_gput:Nnx \g__hobby_matrix_d_array {0} {\fp_to_tl:N \l_hobby_tempa_fp} } % \end{macrocode} % % Next, if \(\phi_n\) has been given. % \begin{macrocode} -\fp_compare:nTF { \l_hobby_in_angle_fp == \c_inf_fp } +\fp_compare:nTF { \g__hobby_in_angle_fp == \c_inf_fp } { - \array_put:Nnx \l_hobby_matrix_b_array {\l_hobby_npoints_int - 1} {\fp_to_tl:n { -\array_get:Nn \l_hobby_matrix_b_array {\l_hobby_npoints_int - 1} -- (\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int - 1})^2 -* (\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int - 2}) -* (\array_get:Nn \l_hobby_distances_array {\l_hobby_npoints_int - 2}) + \array_gput:Nnx \g__hobby_matrix_b_array {\g__hobby_npoints_int - 1} {\fp_to_tl:n { +\array_get:Nn \g__hobby_matrix_b_array {\g__hobby_npoints_int - 1} +- (\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int - 1})^2 +* (\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int - 2}) +* (\array_get:Nn \g__hobby_distances_array {\g__hobby_npoints_int - 2}) * -((3 * (\array_get:Nn \l_hobby_tension_in_array {\l_hobby_npoints_int} ) - 1) -* (\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int - 1})^3 \l_tmpa_tl -* \l_hobby_out_curl_fp +((3 * (\array_get:Nn \g__hobby_tension_in_array {\g__hobby_npoints_int} ) - 1) +* (\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int - 1})^3 \l_tmpa_tl +* \g__hobby_out_curl_fp + -(\array_get:Nn \l_hobby_tension_in_array {\l_hobby_npoints_int })^3) +(\array_get:Nn \g__hobby_tension_in_array {\g__hobby_npoints_int })^3) / -((3 * (\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int -2}) - 1) -* (\array_get:Nn \l_hobby_tension_in_array {\l_hobby_npoints_int})^3 +((3 * (\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int -2}) - 1) +* (\array_get:Nn \g__hobby_tension_in_array {\g__hobby_npoints_int})^3 + -( \array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int - 1})^3 -* \l_hobby_out_curl_fp) +( \array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int - 1})^3 +* \g__hobby_out_curl_fp) }} - \array_put:Nnx \l_hobby_matrix_d_array {\l_hobby_npoints_int - 1} {\fp_to_tl:n { -- (3 * (\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int - 2}) - 1) -* (\array_get:Nn \l_hobby_psi_array {\l_hobby_npoints_int - 1}) -* (\array_get:Nn \l_hobby_tension_in_array {\l_hobby_npoints_int - 1})^2 -* (\array_get:Nn \l_hobby_tension_in_array {\l_hobby_npoints_int}) -* (\array_get:Nn \l_hobby_distances_array {\l_hobby_npoints_int - 1}) + \array_gput:Nnx \g__hobby_matrix_d_array {\g__hobby_npoints_int - 1} {\fp_to_tl:n { +- (3 * (\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int - 2}) - 1) +* (\array_get:Nn \g__hobby_psi_array {\g__hobby_npoints_int - 1}) +* (\array_get:Nn \g__hobby_tension_in_array {\g__hobby_npoints_int - 1})^2 +* (\array_get:Nn \g__hobby_tension_in_array {\g__hobby_npoints_int}) +* (\array_get:Nn \g__hobby_distances_array {\g__hobby_npoints_int - 1}) }} } { - \fp_set:Nn \l_hobby_tempa_fp { - \l_hobby_in_angle_fp + \c_pi_fp -+ (\array_get:Nn \l_hobby_angles_array {\l_hobby_npoints_int - 1})} + \fp_set:Nn \l_hobby_tempa_fp { - \g__hobby_in_angle_fp + \c_pi_fp ++ (\array_get:Nn \g__hobby_angles_array {\g__hobby_npoints_int - 1})} \fp_compare:nT {\l_hobby_tempa_fp > \c_pi_fp } { \fp_sub:Nn \l_hobby_tempa_fp {2 * \c_pi_fp} @@ -1080,20 +1094,20 @@ and the derived files hobby.code.tex \fp_add:Nn \l_hobby_tempa_fp {2 * \c_pi_fp} } - \array_put:Nnx \l_hobby_phi_array {\l_hobby_npoints_int} + \array_gput:Nnx \g__hobby_phi_array {\g__hobby_npoints_int} {\fp_to_tl:N \l_hobby_tempa_fp} - \array_put:Nnx \l_hobby_matrix_d_array {\l_hobby_npoints_int - 1} {\fp_to_tl:n { + \array_gput:Nnx \g__hobby_matrix_d_array {\g__hobby_npoints_int - 1} {\fp_to_tl:n { \l_hobby_tempa_fp - * (\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int - 1})^2 -* (\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int - 2}) -* (\array_get:Nn \l_hobby_distances_array {\l_hobby_npoints_int - 2}) + * (\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int - 1})^2 +* (\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int - 2}) +* (\array_get:Nn \g__hobby_distances_array {\g__hobby_npoints_int - 2}) - -(3 * ( \array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int - 2}) - 1) -* (\array_get:Nn \l_hobby_psi_array {\l_hobby_npoints_int - 1}) -* (\array_get:Nn \l_hobby_tension_in_array {\l_hobby_npoints_int - 1})^2 -* (\array_get:Nn \l_hobby_tension_in_array {\l_hobby_npoints_int}) -* (\array_get:Nn \l_hobby_distances_array {\l_hobby_npoints_int - 1}) }} +(3 * ( \array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int - 2}) - 1) +* (\array_get:Nn \g__hobby_psi_array {\g__hobby_npoints_int - 1}) +* (\array_get:Nn \g__hobby_tension_in_array {\g__hobby_npoints_int - 1})^2 +* (\array_get:Nn \g__hobby_tension_in_array {\g__hobby_npoints_int}) +* (\array_get:Nn \g__hobby_distances_array {\g__hobby_npoints_int - 1}) }} } % \end{macrocode} % End of adjustments for open paths. @@ -1104,43 +1118,43 @@ and the derived files hobby.code.tex % Now we have the tridiagonal matrix in place, we implement the solution. % We start with the forward eliminations. % \begin{macrocode} -\int_step_inline:nnnn {1} {1} {\l_hobby_npoints_int - 1} { +\int_step_inline:nnnn {1} {1} {\g__hobby_npoints_int - 1} { - \array_put:Nnx \l_hobby_matrix_b_array {##1} {\fp_to_tl:n { - (\array_get:Nn \l_hobby_matrix_b_array {##1 - 1}) -* (\array_get:Nn \l_hobby_matrix_b_array {##1}) + \array_gput:Nnx \g__hobby_matrix_b_array {##1} {\fp_to_tl:n { + (\array_get:Nn \g__hobby_matrix_b_array {##1 - 1}) +* (\array_get:Nn \g__hobby_matrix_b_array {##1}) - -(\array_get:Nn \l_hobby_matrix_c_array {##1 - 1}) -* (\array_get:Nn \l_hobby_matrix_a_array {##1}) +(\array_get:Nn \g__hobby_matrix_c_array {##1 - 1}) +* (\array_get:Nn \g__hobby_matrix_a_array {##1}) }} % \end{macrocode} % The last time, we don't touch the \(C\)-vector. % \begin{macrocode} - \int_compare:nT {##1 < \l_hobby_npoints_int - 1} { + \int_compare:nT {##1 < \g__hobby_npoints_int - 1} { - \array_put:Nnx \l_hobby_matrix_c_array {##1} {\fp_to_tl:n { -(\array_get:Nn \l_hobby_matrix_b_array {##1 - 1}) - * (\array_get:Nn \l_hobby_matrix_c_array {##1}) + \array_gput:Nnx \g__hobby_matrix_c_array {##1} {\fp_to_tl:n { +(\array_get:Nn \g__hobby_matrix_b_array {##1 - 1}) + * (\array_get:Nn \g__hobby_matrix_c_array {##1}) }} } - \array_put:Nnx \l_hobby_matrix_d_array {##1} {\fp_to_tl:n { -(\array_get:Nn \l_hobby_matrix_b_array {##1 - 1}) - * (\array_get:Nn \l_hobby_matrix_d_array {##1}) + \array_gput:Nnx \g__hobby_matrix_d_array {##1} {\fp_to_tl:n { +(\array_get:Nn \g__hobby_matrix_b_array {##1 - 1}) + * (\array_get:Nn \g__hobby_matrix_d_array {##1}) - - (\array_get:Nn \l_hobby_matrix_d_array {##1 - 1}) - * (\array_get:Nn \l_hobby_matrix_a_array {##1}) + (\array_get:Nn \g__hobby_matrix_d_array {##1 - 1}) + * (\array_get:Nn \g__hobby_matrix_a_array {##1}) }} % \end{macrocode} % On a closed path, we also want to know \(M^{-1} u\) so need to do the elimination steps on \(u\) as well. % \begin{macrocode} - \bool_if:NT \l_hobby_closed_bool { - \array_put:Nnx \l_hobby_vector_u_array {##1} {\fp_to_tl:n { -(\array_get:Nn \l_hobby_matrix_b_array {##1 - 1}) -* (\array_get:Nn \l_hobby_vector_u_array {##1}) + \bool_if:NT \g__hobby_closed_bool { + \array_gput:Nnx \g__hobby_vector_u_array {##1} {\fp_to_tl:n { +(\array_get:Nn \g__hobby_matrix_b_array {##1 - 1}) +* (\array_get:Nn \g__hobby_vector_u_array {##1}) - -(\array_get:Nn \l_hobby_vector_u_array {##1 - 1}) -* (\array_get:Nn \l_hobby_matrix_a_array {##1}) +(\array_get:Nn \g__hobby_vector_u_array {##1 - 1}) +* (\array_get:Nn \g__hobby_matrix_a_array {##1}) }} } } @@ -1148,42 +1162,42 @@ and the derived files hobby.code.tex % Now we start the back substitution. % The first step is slightly different to the general step. % \begin{macrocode} - \array_put:Nnx \l_hobby_theta_array {\l_hobby_npoints_int - 1} {\fp_to_tl:n { -(\array_get:Nn \l_hobby_matrix_d_array {\l_hobby_npoints_int - 1}) -/ (\array_get:Nn \l_hobby_matrix_b_array {\l_hobby_npoints_int - 1}) + \array_gput:Nnx \g__hobby_theta_array {\g__hobby_npoints_int - 1} {\fp_to_tl:n { +(\array_get:Nn \g__hobby_matrix_d_array {\g__hobby_npoints_int - 1}) +/ (\array_get:Nn \g__hobby_matrix_b_array {\g__hobby_npoints_int - 1}) }} % \end{macrocode} % For a closed path, we need to work with \(u\) as well. % \begin{macrocode} -\bool_if:NT \l_hobby_closed_bool { - \array_put:Nnx \l_hobby_vector_u_array {\l_hobby_npoints_int - 1} {\fp_to_tl:n { - (\array_get:Nn \l_hobby_vector_u_array {\l_hobby_npoints_int - 1}) -/ (\array_get:Nn \l_hobby_matrix_b_array {\l_hobby_npoints_int - 1}) +\bool_if:NT \g__hobby_closed_bool { + \array_gput:Nnx \g__hobby_vector_u_array {\g__hobby_npoints_int - 1} {\fp_to_tl:n { + (\array_get:Nn \g__hobby_vector_u_array {\g__hobby_npoints_int - 1}) +/ (\array_get:Nn \g__hobby_matrix_b_array {\g__hobby_npoints_int - 1}) }} } % \end{macrocode} % Now we iterate over the vectors, doing the remaining back substitutions. % \begin{macrocode} -\int_step_inline:nnnn {\l_hobby_npoints_int - 2} {-1} {0} { +\int_step_inline:nnnn {\g__hobby_npoints_int - 2} {-1} {0} { - \array_put:Nnx \l_hobby_theta_array {##1} {\fp_to_tl:n { -( (\array_get:Nn \l_hobby_matrix_d_array {##1}) - - (\array_get:Nn \l_hobby_theta_array {##1 + 1}) - * (\array_get:Nn \l_hobby_matrix_c_array {##1}) -) / (\array_get:Nn \l_hobby_matrix_b_array {##1}) + \array_gput:Nnx \g__hobby_theta_array {##1} {\fp_to_tl:n { +( (\array_get:Nn \g__hobby_matrix_d_array {##1}) + - (\array_get:Nn \g__hobby_theta_array {##1 + 1}) + * (\array_get:Nn \g__hobby_matrix_c_array {##1}) +) / (\array_get:Nn \g__hobby_matrix_b_array {##1}) }} } -\bool_if:NT \l_hobby_closed_bool { +\bool_if:NT \g__hobby_closed_bool { % \end{macrocode} % On a closed path, we also need to work out \(M^{-1} u\). % \begin{macrocode} -\int_step_inline:nnnn {\l_hobby_npoints_int - 2} {-1} {0} { - \array_put:Nnx \l_hobby_vector_u_array {##1} {\fp_to_tl:n +\int_step_inline:nnnn {\g__hobby_npoints_int - 2} {-1} {0} { + \array_gput:Nnx \g__hobby_vector_u_array {##1} {\fp_to_tl:n { - ((\array_get:Nn \l_hobby_vector_u_array {##1}) - - (\array_get:Nn \l_hobby_vector_u_array {##1 + 1}) - * (\array_get:Nn \l_hobby_matrix_c_array {##1}) - ) / (\array_get:Nn \l_hobby_matrix_b_array {##1}) + ((\array_get:Nn \g__hobby_vector_u_array {##1}) + - (\array_get:Nn \g__hobby_vector_u_array {##1 + 1}) + * (\array_get:Nn \g__hobby_matrix_c_array {##1}) + ) / (\array_get:Nn \g__hobby_matrix_b_array {##1}) }} } % \end{macrocode} @@ -1192,21 +1206,21 @@ and the derived files hobby.code.tex % \begin{macrocode} \fp_set:Nn \l_hobby_tempb_fp { -((\array_get:Nn \l_hobby_theta_array {1}) +((\array_get:Nn \g__hobby_theta_array {1}) * \l_hobby_matrix_v_fp -- (\array_get:Nn \l_hobby_theta_array {\l_hobby_npoints_int - 1}) +- (\array_get:Nn \g__hobby_theta_array {\g__hobby_npoints_int - 1}) ) / ( -(\array_get:Nn \l_hobby_vector_u_array {1}) +(\array_get:Nn \g__hobby_vector_u_array {1}) * \l_hobby_matrix_v_fp -- (\array_get:Nn \l_hobby_vector_u_array {\l_hobby_npoints_int - 1}) +- (\array_get:Nn \g__hobby_vector_u_array {\g__hobby_npoints_int - 1}) + 1 )} -\int_step_inline:nnnn {0} {1} {\l_hobby_npoints_int - 1} { +\int_step_inline:nnnn {0} {1} {\g__hobby_npoints_int - 1} { - \array_put:Nnx \l_hobby_theta_array {##1} {\fp_to_tl:n { - (\array_get:Nn \l_hobby_theta_array {##1}) - - (\array_get:Nn \l_hobby_vector_u_array {##1}) + \array_gput:Nnx \g__hobby_theta_array {##1} {\fp_to_tl:n { + (\array_get:Nn \g__hobby_theta_array {##1}) + - (\array_get:Nn \g__hobby_vector_u_array {##1}) * \l_hobby_tempb_fp }} } @@ -1216,11 +1230,11 @@ and the derived files hobby.code.tex % Now that we have computed the \(\theta_i\)s, we can quickly compute the \(\phi_i\)s. % % \begin{macrocode} -\int_step_inline:nnnn {1} {1} {\l_hobby_npoints_int - 1} { +\int_step_inline:nnnn {1} {1} {\g__hobby_npoints_int - 1} { - \array_put:Nnx \l_hobby_phi_array {##1} {\fp_to_tl:n { - - (\array_get:Nn \l_hobby_psi_array {##1}) - - (\array_get:Nn \l_hobby_theta_array {##1}) + \array_gput:Nnx \g__hobby_phi_array {##1} {\fp_to_tl:n { + - (\array_get:Nn \g__hobby_psi_array {##1}) + - (\array_get:Nn \g__hobby_theta_array {##1}) }} } % \end{macrocode} @@ -1229,28 +1243,28 @@ and the derived files hobby.code.tex % If the path is closed, we can drop our added point. % Cheaply, of course. % \begin{macrocode} -\bool_if:NTF \l_hobby_closed_bool { - \int_gdecr:N \l_hobby_npoints_int +\bool_if:NTF \g__hobby_closed_bool { + \int_gdecr:N \g__hobby_npoints_int }{ % \end{macrocode} % If \(\phi_n\) was not given, we compute it from \(\theta_{n-1}\). % \begin{macrocode} -\fp_compare:nT { \l_hobby_in_angle_fp == \c_inf_fp } +\fp_compare:nT { \g__hobby_in_angle_fp == \c_inf_fp } { - \array_put:Nnx \l_hobby_phi_array {\l_hobby_npoints_int} {\fp_to_tl:n { -((3 * (\array_get:Nn \l_hobby_tension_in_array {\l_hobby_npoints_int}) - 1) -* (\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int - 1})^3 -* \l_hobby_out_curl_fp + \array_gput:Nnx \g__hobby_phi_array {\g__hobby_npoints_int} {\fp_to_tl:n { +((3 * (\array_get:Nn \g__hobby_tension_in_array {\g__hobby_npoints_int}) - 1) +* (\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int - 1})^3 +* \g__hobby_out_curl_fp + -(\array_get:Nn \l_hobby_tension_in_array {\l_hobby_npoints_int })^3) +(\array_get:Nn \g__hobby_tension_in_array {\g__hobby_npoints_int })^3) / -((3 * (\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int -2}) - 1) -* (\array_get:Nn \l_hobby_tension_in_array {\l_hobby_npoints_int})^3 \l_tmpa_tl +((3 * (\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int -2}) - 1) +* (\array_get:Nn \g__hobby_tension_in_array {\g__hobby_npoints_int})^3 \l_tmpa_tl + -(\array_get:Nn \l_hobby_tension_out_array {\l_hobby_npoints_int - 1})^3 -* \l_hobby_out_curl_fp) +(\array_get:Nn \g__hobby_tension_out_array {\g__hobby_npoints_int - 1})^3 +* \g__hobby_out_curl_fp) * -(\array_get:Nn \l_hobby_theta_array {\l_hobby_npoints_int -1}) +(\array_get:Nn \g__hobby_theta_array {\g__hobby_npoints_int -1}) }} } } @@ -1267,58 +1281,58 @@ and the derived files hobby.code.tex % \end{macrocode} % Next task is to compute the \(\rho_i\) and \(\sigma_i\). % \begin{macrocode} -\int_step_inline:nnnn {0} {1} {\l_hobby_npoints_int - 1} { +\int_step_inline:nnnn {0} {1} {\g__hobby_npoints_int - 1} { - \fp_set:Nn \l_hobby_tempa_fp {\array_get:Nn \l_hobby_theta_array {##1}} + \fp_set:Nn \l_hobby_tempa_fp {\array_get:Nn \g__hobby_theta_array {##1}} - \fp_set:Nn \l_hobby_tempb_fp {\array_get:Nn \l_hobby_phi_array {##1 + 1}} + \fp_set:Nn \l_hobby_tempb_fp {\array_get:Nn \g__hobby_phi_array {##1 + 1}} \hobby_ctrllen:NVV \l_hobby_temps_fp \l_hobby_tempa_fp \l_hobby_tempb_fp - \array_put:Nnx \l_hobby_sigma_array {##1 + 1} {\fp_to_tl:N \l_hobby_temps_fp} + \array_gput:Nnx \g__hobby_sigma_array {##1 + 1} {\fp_to_tl:N \l_hobby_temps_fp} \hobby_ctrllen:NVV \l_hobby_temps_fp \l_hobby_tempb_fp \l_hobby_tempa_fp - \array_put:Nnx \l_hobby_rho_array {##1} {\fp_to_tl:N \l_hobby_temps_fp} + \array_gput:Nnx \g__hobby_rho_array {##1} {\fp_to_tl:N \l_hobby_temps_fp} } % \end{macrocode} % Lastly, we generate the coordinates of the control points. % \begin{macrocode} -\int_step_inline:nnnn {0} {1} {\l_hobby_npoints_int - 1} { -\array_gput:Nnx \l_hobby_controla_array {##1 + 1} {x = \fp_eval:n { -(\array_get:Nn \l_hobby_points_x_array {##1}) +\int_step_inline:nnnn {0} {1} {\g__hobby_npoints_int - 1} { +\array_gput:Nnx \g__hobby_controla_array {##1 + 1} {\fp_eval:n { +(\array_get:Nn \g__hobby_points_x_array {##1}) + - (\array_get:Nn \l_hobby_distances_array {##1}) * - (\array_get:Nn \l_hobby_rho_array {##1}) * -cos ( (\array_get:Nn \l_hobby_angles_array {##1}) + (\array_get:Nn \g__hobby_distances_array {##1}) * + (\array_get:Nn \g__hobby_rho_array {##1}) * +cos ( (\array_get:Nn \g__hobby_angles_array {##1}) + - (\array_get:Nn \l_hobby_theta_array {##1})) + (\array_get:Nn \g__hobby_theta_array {##1})) /3 -}, y = \fp_eval:n { -( \array_get:Nn \l_hobby_points_y_array {##1}) + - (\array_get:Nn \l_hobby_distances_array {##1}) * - (\array_get:Nn \l_hobby_rho_array {##1}) * -sin ( (\array_get:Nn \l_hobby_angles_array {##1}) +}, \fp_eval:n { +( \array_get:Nn \g__hobby_points_y_array {##1}) + + (\array_get:Nn \g__hobby_distances_array {##1}) * + (\array_get:Nn \g__hobby_rho_array {##1}) * +sin ( (\array_get:Nn \g__hobby_angles_array {##1}) + - (\array_get:Nn \l_hobby_theta_array {##1})) + (\array_get:Nn \g__hobby_theta_array {##1})) /3 } } } -\int_step_inline:nnnn {1} {1} {\l_hobby_npoints_int} { - \array_gput:Nnx \l_hobby_controlb_array {##1} { - x = \fp_eval:n {\array_get:Nn \l_hobby_points_x_array {##1} -- (\array_get:Nn \l_hobby_distances_array {##1 - 1}) -* (\array_get:Nn \l_hobby_sigma_array {##1}) -* cos((\array_get:Nn \l_hobby_angles_array {##1 - 1}) -- (\array_get:Nn \l_hobby_phi_array {##1}))/3 -}, y = \fp_eval:n { - (\array_get:Nn \l_hobby_points_y_array {##1}) -- (\array_get:Nn \l_hobby_distances_array {##1 - 1}) -* (\array_get:Nn \l_hobby_sigma_array {##1}) -* sin((\array_get:Nn \l_hobby_angles_array {##1 - 1}) -- (\array_get:Nn \l_hobby_phi_array {##1}))/3 +\int_step_inline:nnnn {1} {1} {\g__hobby_npoints_int} { + \array_gput:Nnx \g__hobby_controlb_array {##1} { + \fp_eval:n {\array_get:Nn \g__hobby_points_x_array {##1} +- (\array_get:Nn \g__hobby_distances_array {##1 - 1}) +* (\array_get:Nn \g__hobby_sigma_array {##1}) +* cos((\array_get:Nn \g__hobby_angles_array {##1 - 1}) +- (\array_get:Nn \g__hobby_phi_array {##1}))/3 +}, \fp_eval:n { + (\array_get:Nn \g__hobby_points_y_array {##1}) +- (\array_get:Nn \g__hobby_distances_array {##1 - 1}) +* (\array_get:Nn \g__hobby_sigma_array {##1}) +* sin((\array_get:Nn \g__hobby_angles_array {##1 - 1}) +- (\array_get:Nn \g__hobby_phi_array {##1}))/3 } } } } @@ -1329,7 +1343,7 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1}) % Initialise the settings for Hobby's algorithm % \begin{macrocode} \NewDocumentCommand \hobbyinit {m m m} { - \hobby_set_cmds:nnn#1#2#3 + \hobby_set_cmds:NNN #1#2#3 \hobby_clear_path: } % \end{macrocode} @@ -1339,35 +1353,45 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1}) % This adds a point, possibly with tensions, to the current stack. % \begin{macrocode} \NewDocumentCommand \hobbyaddpoint { m } { - \keys_set:nn { hobby/read in all } - { - tension~out, - tension~in, - excess~angle, - blank, - break, - #1 - } - \tl_if_eq:VnTF {\l_tmpa_tl} {true} - {\tl_set:Nn \l_tmpa_tl {2}} - { - \tl_if_eq:VnTF {\l_tmpa_tl} {soft} - {\tl_set:Nn \l_tmpa_tl {0}} - {\tl_set:Nn \l_tmpa_tl {1}} - } - \tl_if_eq:VnTF {\l_tmpb_tl} {true} - {\tl_put_right:Nn \l_tmpa_tl {1}} - {\tl_put_right:Nn \l_tmpa_tl {0}} - \array_gpush:Nx \l_hobby_actions_array {\l_tmpa_tl} - \array_gpush:Nx \l_hobby_tension_out_array {\fp_to_tl:N \l_hobby_tempc_fp} - \array_gpush:Nx \l_hobby_tension_in_array {\fp_to_tl:N \l_hobby_tempd_fp} - \array_gpush:Nx \l_hobby_excess_angle_array {\fp_to_tl:N \l_hobby_temps_fp} - \array_gpush:Nx \l_hobby_points_array { - x = \fp_use:N \l_hobby_tempa_fp, - y = \fp_use:N \l_hobby_tempb_fp } - \array_gpush:Nx \l_hobby_points_x_array {\fp_to_tl:N \l_hobby_tempa_fp} - \array_gpush:Nx \l_hobby_points_y_array {\fp_to_tl:N \l_hobby_tempb_fp} + \keys_set:nn { hobby/read in all } + { + tension~out, + tension~in, + excess~angle, + blank, + break, + #1 + } + \tl_if_eq:VnTF \l_tmpa_tl {true} + {\tl_set:Nn \l_tmpa_tl {2}} + { + \tl_if_eq:VnTF \l_tmpa_tl {soft} + {\tl_set:Nn \l_tmpa_tl {0}} + {\tl_set:Nn \l_tmpa_tl {1}} + } + \tl_if_eq:VnTF \l_tmpb_tl {true} + {\tl_put_right:Nn \l_tmpa_tl {1}} + {\tl_put_right:Nn \l_tmpa_tl {0}} + \tl_set:Nx \l_hobby_tempa_tl {\fp_use:N \l_hobby_tempa_fp} + \tl_set:Nx \l_hobby_tempb_tl {\fp_use:N \l_hobby_tempb_fp} + \hobby_add_point:VVVVVV \l_hobby_tempa_tl \l_hobby_tempb_tl \l_hobby_tempc_fp \l_hobby_tempd_fp \l_hobby_temps_fp \l_tmpa_tl +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby_add_point:n} +% \begin{macrocode} +\cs_new_nopar:Npn \hobby_add_point:nnnnnn #1#2#3#4#5#6 +{ + \array_gpush:Nn \g__hobby_actions_array { #6 } + \array_gpush:Nn \g__hobby_tension_out_array { #3 } + \array_gpush:Nn \g__hobby_tension_in_array { #4 } + \array_gpush:Nn \g__hobby_excess_angle_array { #5 } + \array_gpush:Nn \g__hobby_points_array { #1, #2 } + \array_gpush:Nn \g__hobby_points_x_array { #1 } + \array_gpush:Nn \g__hobby_points_y_array { #2 } } +\cs_generate_variant:Nn \hobby_add_point:nnnnnn {VVVVVV} % \end{macrocode} % \end{macro} % @@ -1383,7 +1407,7 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1}) % \end{macrocode} % \end{macro} % -% \begin{macro}{\hobby_set_cmds:nnn} +% \begin{macro}{\hobby_set_cmds:NNN} % The path-generation code doesn't know what to actually do with the path so the initialisation code will set some macros to do that. % This is an auxiliary command that sets these macros. % \begin{macrocode} @@ -1393,7 +1417,7 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1}) \cs_generate_variant:Nn \hobby_moveto:nnn {VVV,nnV} \cs_generate_variant:Nn \hobby_curveto:nnn {VVV} \cs_generate_variant:Nn \hobby_close:n {V} -\cs_new:Nn \hobby_set_cmds:nnn { +\cs_new:Nn \hobby_set_cmds:NNN { \cs_gset_eq:NN \hobby_moveto:nnn #1 \cs_gset_eq:NN \hobby_curveto:nnn #2 \cs_gset_eq:NN \hobby_close:n #3 @@ -1405,7 +1429,7 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1}) % This is the user (well, sort of) command that generates the curve. % \begin{macrocode} \NewDocumentCommand \hobbygenpath { } { - \array_if_empty:NF \l_hobby_points_array { + \array_if_empty:NF \g__hobby_points_array { \hobby_gen_path: } } @@ -1496,7 +1520,7 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1}) % This is the user (well, sort of) command that generates a curve and uses it. % \begin{macrocode} \NewDocumentCommand \hobbygenusepath { } { - \array_if_empty:NF \l_hobby_points_array { + \array_if_empty:NF \g__hobby_points_array { \hobby_gen_path: \hobby_use_path: } @@ -1518,29 +1542,30 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1}) % As the curve data is stored globally, the same data can be reused by calling this function more than once without calling the generating function. % \begin{macrocode} \tl_new:N \l_tmpc_tl +\tl_new:N \l_tmpd_tl \cs_new:Nn \hobby_use_path: { - \bool_if:NT \l_hobby_disjoint_bool { - \array_get:NnN \l_hobby_points_array {0} \l_tmpa_tl + \bool_if:NT \g__hobby_disjoint_bool { + \array_get:NnN \g__hobby_points_array {0} \l_tmpa_tl \hobby_moveto:nnV {} {} \l_tmpa_tl } - \int_step_inline:nnnn {1} {1} {\l_hobby_npoints_int} { - \array_get:NnN \l_hobby_controla_array {##1} \l_tmpa_tl - \array_get:NnN \l_hobby_controlb_array {##1} \l_tmpb_tl - \array_get:NnN \l_hobby_points_array {##1} \l_tmpc_tl - \array_get:NnN \l_hobby_actions_array {##1} \l_tmpd_tl - \int_compare:nNnTF {\tl_item:Nn \l_tmpd_tl {1}} = {\l_hobby_draw_int} { + \int_step_inline:nnnn {1} {1} {\g__hobby_npoints_int} { + \array_get:NnN \g__hobby_controla_array {##1} \l_tmpa_tl + \array_get:NnN \g__hobby_controlb_array {##1} \l_tmpb_tl + \array_get:NnN \g__hobby_points_array {##1} \l_tmpc_tl + \array_get:NnN \g__hobby_actions_array {##1} \l_tmpd_tl + \int_compare:nNnTF {\tl_item:Nn \l_tmpd_tl {1}} = {\g__hobby_draw_int} { \hobby_curveto:VVV \l_tmpa_tl \l_tmpb_tl \l_tmpc_tl }{ - \bool_gset_false:N \l_hobby_closed_bool + \bool_gset_false:N \g__hobby_closed_bool \hobby_moveto:VVV \l_tmpa_tl \l_tmpb_tl \l_tmpc_tl } \tl_if_eq:xnTF {\tl_item:Nn \l_tmpd_tl {2}} {1} { - \bool_gset_false:N \l_hobby_closed_bool + \bool_gset_false:N \g__hobby_closed_bool \hobby_moveto:VVV \l_tmpa_tl \l_tmpb_tl \l_tmpc_tl }{} } - \bool_if:NT \l_hobby_closed_bool { - \array_get:NnN \l_hobby_points_array {0} \l_tmpa_tl + \bool_if:NT \g__hobby_closed_bool { + \array_get:NnN \g__hobby_points_array {0} \l_tmpa_tl \hobby_close:V \l_tmpa_tl } } @@ -1552,42 +1577,42 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1}) % \begin{macrocode} \cs_new:Nn \hobby_save_path:n { \tl_clear:N \l_tmpa_tl - \tl_put_right:Nn \l_tmpa_tl {\int_gset:Nn \l_hobby_npoints_int} - \tl_put_right:Nx \l_tmpa_tl {{\int_use:N \l_hobby_npoints_int}} - \bool_if:NTF \l_hobby_disjoint_bool { + \tl_put_right:Nn \l_tmpa_tl {\int_gset:Nn \g__hobby_npoints_int} + \tl_put_right:Nx \l_tmpa_tl {{\int_use:N \g__hobby_npoints_int}} + \bool_if:NTF \g__hobby_disjoint_bool { \tl_put_right:Nn \l_tmpa_tl {\bool_gset_true:N} }{ \tl_put_right:Nn \l_tmpa_tl {\bool_gset_false:N} } - \tl_put_right:Nn \l_tmpa_tl {\l_hobby_disjoint_bool} - \bool_if:NTF \l_hobby_closed_bool { + \tl_put_right:Nn \l_tmpa_tl {\g__hobby_disjoint_bool} + \bool_if:NTF \g__hobby_closed_bool { \tl_put_right:Nn \l_tmpa_tl {\bool_gset_true:N} }{ \tl_put_right:Nn \l_tmpa_tl {\bool_gset_false:N} } - \tl_put_right:Nn \l_tmpa_tl {\l_hobby_closed_bool} - \tl_put_right:Nn \l_tmpa_tl {\array_gclear:N \l_hobby_points_array} - \array_map_inline:Nn \l_hobby_points_array { + \tl_put_right:Nn \l_tmpa_tl {\g__hobby_closed_bool} + \tl_put_right:Nn \l_tmpa_tl {\array_gclear:N \g__hobby_points_array} + \array_map_inline:Nn \g__hobby_points_array { \tl_put_right:Nn \l_tmpa_tl { - \array_gput:Nnn \l_hobby_points_array {##1} {##2} + \array_gput:Nnn \g__hobby_points_array {##1} {##2} } } - \tl_put_right:Nn \l_tmpa_tl {\array_gclear:N \l_hobby_actions_array} - \array_map_inline:Nn \l_hobby_actions_array { + \tl_put_right:Nn \l_tmpa_tl {\array_gclear:N \g__hobby_actions_array} + \array_map_inline:Nn \g__hobby_actions_array { \tl_put_right:Nn \l_tmpa_tl { - \array_gput:Nnn \l_hobby_actions_array {##1} {##2} + \array_gput:Nnn \g__hobby_actions_array {##1} {##2} } } - \tl_put_right:Nn \l_tmpa_tl {\array_gclear:N \l_hobby_controla_array} - \array_map_inline:Nn \l_hobby_controla_array { + \tl_put_right:Nn \l_tmpa_tl {\array_gclear:N \g__hobby_controla_array} + \array_map_inline:Nn \g__hobby_controla_array { \tl_put_right:Nn \l_tmpa_tl { - \array_gput:Nnn \l_hobby_controla_array {##1} {##2} + \array_gput:Nnn \g__hobby_controla_array {##1} {##2} } } - \tl_put_right:Nn \l_tmpa_tl {\array_gclear:N \l_hobby_controlb_array} - \array_map_inline:Nn \l_hobby_controlb_array { + \tl_put_right:Nn \l_tmpa_tl {\array_gclear:N \g__hobby_controlb_array} + \array_map_inline:Nn \g__hobby_controlb_array { \tl_put_right:Nn \l_tmpa_tl { - \array_gput:Nnn \l_hobby_controlb_array {##1} {##2} + \array_gput:Nnn \g__hobby_controlb_array {##1} {##2} } } \tl_gclear_new:c {g_hobby_#1_path} @@ -1636,36 +1661,36 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1}) % \begin{macrocode} \cs_new:Nn \hobby_clear_path: { -\array_gclear:N \l_hobby_points_array -\array_gclear:N \l_hobby_points_x_array -\array_gclear:N \l_hobby_points_y_array -\array_gclear:N \l_hobby_angles_array -\array_gclear:N \l_hobby_actions_array -\array_gclear:N \l_hobby_distances_array -\array_gclear:N \l_hobby_tension_out_array -\array_gclear:N \l_hobby_tension_in_array -\array_gclear:N \l_hobby_excess_angle_array -\array_gclear:N \l_hobby_matrix_a_array -\array_gclear:N \l_hobby_matrix_b_array -\array_gclear:N \l_hobby_matrix_c_array -\array_gclear:N \l_hobby_matrix_d_array -\array_gclear:N \l_hobby_vector_u_array -\array_gclear:N \l_hobby_psi_array -\array_gclear:N \l_hobby_theta_array -\array_gclear:N \l_hobby_phi_array -\array_gclear:N \l_hobby_sigma_array -\array_gclear:N \l_hobby_rho_array -\array_gclear:N \l_hobby_controla_array -\array_gclear:N \l_hobby_controlb_array -\bool_gset_false:N \l_hobby_closed_bool -\bool_gset_false:N \l_hobby_disjoint_bool +\array_gclear:N \g__hobby_points_array +\array_gclear:N \g__hobby_points_x_array +\array_gclear:N \g__hobby_points_y_array +\array_gclear:N \g__hobby_angles_array +\array_gclear:N \g__hobby_actions_array +\array_gclear:N \g__hobby_distances_array +\array_gclear:N \g__hobby_tension_out_array +\array_gclear:N \g__hobby_tension_in_array +\array_gclear:N \g__hobby_excess_angle_array +\array_gclear:N \g__hobby_matrix_a_array +\array_gclear:N \g__hobby_matrix_b_array +\array_gclear:N \g__hobby_matrix_c_array +\array_gclear:N \g__hobby_matrix_d_array +\array_gclear:N \g__hobby_vector_u_array +\array_gclear:N \g__hobby_psi_array +\array_gclear:N \g__hobby_theta_array +\array_gclear:N \g__hobby_phi_array +\array_gclear:N \g__hobby_sigma_array +\array_gclear:N \g__hobby_rho_array +\array_gclear:N \g__hobby_controla_array +\array_gclear:N \g__hobby_controlb_array +\bool_gset_false:N \g__hobby_closed_bool +\bool_gset_false:N \g__hobby_disjoint_bool - \int_gset:Nn \l_hobby_npoints_int {-1} - \int_gset:Nn \l_hobby_draw_int {1} - \fp_gset_eq:NN \l_hobby_in_angle_fp \c_inf_fp - \fp_gset_eq:NN \l_hobby_out_angle_fp \c_inf_fp - \fp_gset_eq:NN \l_hobby_in_curl_fp \c_one_fp - \fp_gset_eq:NN \l_hobby_out_curl_fp \c_one_fp + \int_gset:Nn \g__hobby_npoints_int {-1} + \int_gset:Nn \g__hobby_draw_int {1} + \fp_gset_eq:NN \g__hobby_in_angle_fp \c_inf_fp + \fp_gset_eq:NN \g__hobby_out_angle_fp \c_inf_fp + \fp_gset_eq:NN \g__hobby_in_curl_fp \c_one_fp + \fp_gset_eq:NN \g__hobby_out_curl_fp \c_one_fp } % \end{macrocode} % \end{macro} @@ -1681,7 +1706,7 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1}) % \iffalse %<*pgflibrary> % \fi -% +% % The PGF level is very simple. % All we do is set up the path-construction commands that get passed to the path-generation function. % \begin{macrocode} @@ -1693,8 +1718,12 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1}) \pgfkeys{ /pgf/hobby/.is family, /pgf/hobby/.cd, - x/.code={\pgf@x=#1cm}, - y/.code={\pgf@y=#1cm} + point/.code={% + \hobby@parse@pt#1\relax} +} +\def\hobby@parse@pt#1,#2\relax{% + \pgf@x=#1cm\relax + \pgf@y=#2cm\relax } % \end{macrocode} % @@ -1738,7 +1767,7 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1}) % Translates a \LaTeX3 point to a PGF point. % \begin{macrocode} \def\hobby@topgf#1{% - \pgfqkeys{/pgf/hobby}{#1}% + \pgfqkeys{/pgf/hobby}{point={#1}}% } % \end{macrocode} % \end{macro} @@ -1763,7 +1792,7 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1}) \hobbysetparams{#1}% \pgfmathsetmacro\hobby@x{\the\pgf@path@lastx/1cm}% \pgfmathsetmacro\hobby@y{\the\pgf@path@lasty/1cm}% - \hobbyaddpoint{x = \hobby@x, y = \hobby@y}% + \hobbyaddpoint{point={\hobby@x, \hobby@y}}% } % \end{macrocode} % \end{macro} @@ -1783,7 +1812,7 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1}) % \begin{macro}{\pgfpathhobbyptparams} % \begin{macrocode} \def\pgfpathhobbyptparams#1{% - \hobbyaddpoint{#1,x = \hobby@x, y = \hobby@y}% + \hobbyaddpoint{#1,point={\hobby@x, \hobby@y}}% } % \end{macrocode} % \end{macro} @@ -1890,7 +1919,7 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1}) #1% \pgfmathsetmacro\hobby@x{\the\pgf@x/1cm}% \pgfmathsetmacro\hobby@y{\the\pgf@y/1cm}% - \hobbyaddpoint{x = \hobby@x, y = \hobby@y}% + \hobbyaddpoint{point={\hobby@x, \hobby@y}}% } % \end{macrocode} % \end{macro} @@ -2046,7 +2075,7 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1}) % \begin{macrocode} \hobby@quick@ctrlpts{\hobby@thetazero}{\hobby@phione}{\hobby@qpoints}{\hobby@qpointa}{\hobby@dzero}{\hobby@omegazero}% % \end{macrocode} -% Now call the call-back function +% Now call the call-back function % \begin{macrocode} \edef\hobby@temp{\noexpand\hobby@quick@curveto{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}{\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}}% \hobby@temp @@ -2077,7 +2106,7 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1}) % \begin{macrocode} \hobby@quick@ctrlpts{\hobby@thetaone}{\hobby@phitwo}{\hobby@qpoints}{\hobby@qpointa}{\hobby@done}{\hobby@omegaone}% % \end{macrocode} -% Now call the call-back function +% Now call the call-back function % \begin{macrocode} \edef\hobby@temp{\noexpand\hobby@quick@curveto{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}{\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}}% \hobby@temp @@ -2131,7 +2160,7 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1}) % \iffalse %<*tikzlibrary> % \fi -% +% % \begin{macrocode} \usepgflibrary{hobby} \let\hobby@this@opts=\pgfutil@empty @@ -2163,7 +2192,7 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1}) \expandafter\gdef\expandafter\hobby@point@options\expandafter% {\hobby@point@options,tension out=#1}% }, - tension/.code = {% + tension/.append code = {% \expandafter\gdef\expandafter\hobby@point@options\expandafter% {\hobby@point@options,tension=#1}% }, @@ -2221,7 +2250,7 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1}) in curl/.style = {% add option to Hobby path={in curl=#1}% }, - out curl/.code = {% + out curl/.style = {% add option to Hobby path={out curl=#1}% }, use Hobby shortcut/.code={% @@ -2233,28 +2262,25 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1}) \global\let\hobby@curveto@delegate=\hobby@qcurveto@auto }, use previous Hobby path/.code={% - \pgfextra{\hobbyusepath{#1}} + \hobbyusepath{#1}% }, use previous Hobby path/.default={},% save Hobby path/.code={% \xdef\hobby@path@name{#1}% }, restore Hobby path/.code={% - \pgfextra{% - \hobbyinit\hobby@tikz@moveto\hobby@tikz@curveto\hobby@tikz@close - \global\let\hobby@collected@onpath\pgfutil@empty - \hobbyrestorepath{#1}} + \hobbyinit\hobby@tikz@moveto\hobby@tikz@curveto\hobby@tikz@close + \global\let\hobby@collected@onpath\pgfutil@empty + \hobbyrestorepath{#1}% }, restore and use Hobby path/.code 2 args={% - \pgfextra{% - \hobbyinit\hobby@tikz@moveto\hobby@tikz@curveto\hobby@tikz@close - \global\let\hobby@collected@onpath\pgfutil@empty - \hobbyrestorepath{#1}% - \hobbyusepath{#2}% - } + \hobbyinit\hobby@tikz@moveto\hobby@tikz@curveto\hobby@tikz@close + \global\let\hobby@collected@onpath\pgfutil@empty + \hobbyrestorepath{#1}% + \hobbyusepath{#2}% }, show Hobby path/.code={% - \pgfextra{\hobbyshowpath{#1}} + \hobbyshowpath{#1}% }, Hobby action/.code={% \expandafter\gdef\expandafter\hobby@action\expandafter{\hobby@action#1}% @@ -2390,10 +2416,10 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1}) \pgfmathsetmacro\hobby@x{\the\pgf@x/1cm}% \pgfmathsetmacro\hobby@y{\the\pgf@y/1cm}% \ifx\hobby@initial@pt\pgfutil@empty - \xdef\hobby@initial@pt{x = \hobby@x, y = \hobby@y}% + \xdef\hobby@initial@pt{\hobby@x, \hobby@y}% \fi \expandafter\hobbyaddpoint\expandafter{\hobby@point@options,% - x = \hobby@x, y = \hobby@y}% + point={\hobby@x, \hobby@y}}% \def\hobby@point@options{}% \let\tikz@scan@point@options=\pgfutil@empty \pgfutil@ifnextchar\relax{% @@ -2452,10 +2478,10 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1}) \let\tikz@collected@onpath=\pgfutil@empty \pgfmathsetmacro\hobby@x{\the\tikz@lastx/1cm}% \pgfmathsetmacro\hobby@y{\the\tikz@lasty/1cm}% - \xdef\hobby@initial@pt{x = \hobby@x, y = \hobby@y}% + \xdef\hobby@initial@pt{\hobby@x, \hobby@y}% \expandafter\hobbysetparams\expandafter{\hobby@next@opts}% \expandafter\hobbyaddpoint\expandafter{\hobby@point@options,% - x = \hobby@x, y = \hobby@y}% + point={\hobby@x, \hobby@y} }% \hobby@init@tikz@commands \tikzset{designated Hobby path=this}% \let\tikz@scan@point@options=\pgfutil@empty @@ -2478,7 +2504,7 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1}) \pgfmathsetmacro\hobby@y{\the\pgf@y/1cm}% \expandafter\hobbysetparams\expandafter{\hobby@this@opts}% \expandafter\hobbyaddpoint\expandafter{\hobby@point@options,% - x = \hobby@x, y = \hobby@y}% + point={\hobby@x, \hobby@y}}% \hobby@action \global\let\hobby@this@opts=\pgfutil@empty \global\let\hobby@action=\pgfutil@empty @@ -2936,7 +2962,7 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1}) % \iffalse %<*array> % \fi -% +% % % A lot of our data structures are really arrays. % These are implemented as \LaTeX3 ``property lists''. @@ -2953,11 +2979,12 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1}) \int_new:N \l_array_base_int \int_new:N \l_array_top_int \int_new:N \l_array_tmp_int +\int_new:N \g_array_map_int % \end{macrocode} % The global variable \Verb+\g_array_base_int+ says what index a blank array should start with when pushed or unshifted. % \begin{macrocode} \int_new:N \g_array_base_int -\int_set:Nn \g_array_base_int {0} +\int_gset:Nn \g_array_base_int {0} % \end{macrocode} % \begin{macro}{\array_adjust_ends:Nn} % This ensures that the ``base'' and ``top'' are big enough to include the given index. @@ -3164,12 +3191,12 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1}) % \begin{macrocode} \cs_new_protected:Npn \array_map_inline:Nn #1#2 { - \int_gincr:N \g__prg_map_int - \cs_gset:cpn { array_map_inline_ \int_use:N \g__prg_map_int :nn } + \int_gincr:N \g_array_map_int + \cs_gset:cpn { array_map_inline_ \int_use:N \g_array_map_int :nn } ##1##2 {#2} \exp_args:NNc \array_map_function:NN #1 - { array_map_inline_ \int_use:N \g__prg_map_int :nn } - \__prg_break_point:Nn \array_map_break: { \int_gdecr:N \g__prg_map_int } + { array_map_inline_ \int_use:N \g_array_map_int :nn } + \prg_break_point:Nn \array_map_break: { \int_gdecr:N \g_array_map_int } } \cs_generate_variant:Nn \array_map_inline:Nn { c } % \end{macrocode} @@ -3180,12 +3207,12 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1}) % \begin{macrocode} \cs_new_protected:Npn \array_reverse_map_inline:Nn #1#2 { - \int_gincr:N \g__prg_map_int - \cs_gset:cpn { array_map_inline_ \int_use:N \g__prg_map_int :nn } + \int_gincr:N \g_array_map_int + \cs_gset:cpn { array_map_inline_ \int_use:N \g_array_map_int :nn } ##1##2 {#2} \exp_args:NNc \array_reverse_map_function:NN #1 - { array_map_inline_ \int_use:N \g__prg_map_int :nn } - \__prg_break_point:Nn \array_map_break: { \int_gdecr:N \g__prg_map_int } + { array_map_inline_ \int_use:N \g_array_map_int :nn } + \prg_break_point:Nn \array_map_break: { \int_gdecr:N \g_array_map_int } } \cs_generate_variant:Nn \array_reverse_map_inline:Nn { c } % \end{macrocode} @@ -3194,9 +3221,9 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1}) % \begin{macro}{\array_map_break:} % \begin{macrocode} \cs_new_nopar:Npn \array_map_break: - { \__prg_map_break:Nn \array_map_break: { } } + { \prg_map_break:Nn \array_map_break: { } } \cs_new_nopar:Npn \array_map_break:n - { \__prg_map_break:Nn \array_map_break: } + { \prg_map_break:Nn \array_map_break: } % \end{macrocode} % \end{macro} % @@ -3245,7 +3272,7 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1}) % \end{macrocode} % \end{macro} % -% \begin{macro}{\array_gpush:Nn}b +% \begin{macro}{\array_gpush:Nn} % \begin{macrocode} \cs_new_protected:Npn \array_gpush:Nn #1#2 { @@ -3435,7 +3462,7 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1}) % \begin{macrocode} \cs_new_protected:Npn \array_gdel:Nn #1#2 { - \exp_args:NNx \prop_gpop:Nn #1 {\int_eval:n {#2}} + \exp_args:NNx \prop_gremove:Nn #1 {\int_eval:n {#2}} \int_set:Nn \l_array_tmp_int {0} \array_map_inline:Nn #1 { \tl_if_eq:NNTF {##2} {\q_no_value} {} @@ -3496,5 +3523,92 @@ sin ( (\array_get:Nn \l_hobby_angles_array {##1}) % \iffalse %</array> % \fi -% +% +% \iffalse +%<*l3hobby> +% \fi +% +% \begin{macrocode} +\RequirePackage{expl3} +% \end{macrocode} +% +% Load the hobby core +% \begin{macrocode} +\input{hobby.code.tex} +% \end{macrocode} +% +% Register as an expl3 package +% \begin{macrocode} +\ProvidesExplPackage {hobby-l3draw} {2018/02/20} {1.0} {Interface for l3draw and hobby} +% \end{macrocode} +% +% Load the l3draw package +% \begin{macrocode} +\RequirePackage{l3draw} +% \end{macrocode} +% +% +% \begin{macro}{\hobby_draw_moveto:nnn} +% This provides our interface between hobby's moveto and l3draw's moveto +% \begin{macrocode} +\cs_new_protected:Npn \hobby_draw_moveto:nnn #1#2#3 +{ + \draw_path_canvas_moveto:n {#3} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby_draw_curveto:nnn} +% This provides our interface between hobby's curveto and l3draw's curveto +% \begin{macrocode} +\cs_set_eq:NN \hobby_draw_curveto:nnn \draw_path_canvas_curveto:nnn +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby_draw_close:n} +% This provides our interface between hobby's close and l3draw's close +% \begin{macrocode} +\cs_new_protected:Npn \hobby_draw_close:n #1 +{ + \draw_path_close: +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby_draw_addpoint:n} +% This processes a point and passes it one more step towards the hobby algorithm +% \begin{macrocode} +\cs_new_protected:Npn \hobby_draw_addpoint:n #1 +{ + \__draw_point_process:nn + { \__hobby_draw_addpoint:nn } + { \draw_point_transform:n {#1} } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\__hobby_draw_curveto:nn} +% This provides our interface between l3draw's points and hobby's syntax +% \begin{macrocode} +\cs_new_protected:Npn \__hobby_draw_addpoint:nn #1#2 +{ + \hobby_add_point:nnnnnn {#1} {#2} {1} {1} {0} {10} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hobby_draw_init:} +% This initialises hobby's algorithm with the l3draw commands +% \begin{macrocode} +\cs_new_protected:Npn \hobby_draw_init: +{ + \hobby_set_cmds:NNN \hobby_draw_moveto:nnn \hobby_draw_curveto:nnn \hobby_draw_close:n + \hobby_clear_path: +} +% \end{macrocode} +% \end{macro} +% +% \iffalse +%</l3hobby> +% \fi %\Finale diff --git a/Master/texmf-dist/source/latex/hobby/hobby.ins b/Master/texmf-dist/source/latex/hobby/hobby_code.ins index bb46a8c08ba..a1703f980e8 100644 --- a/Master/texmf-dist/source/latex/hobby/hobby.ins +++ b/Master/texmf-dist/source/latex/hobby/hobby_code.ins @@ -1,10 +1,10 @@ %% -%% This is file `hobby.ins', +%% This is file `hobby_code.ins', %% generated with the docstrip utility. %% %% The original source files were: %% -%% hobby.dtx (with options: `install') +%% hobby_code.dtx (with options: `install') %% ---------------------------------------------------------------- %% hobby --- a TikZ/PGF library for drawing smooth(ish) curves using %% Hobby's algorithm (implemented in LaTeX3) @@ -28,7 +28,7 @@ See http://www.latex-project.org/lppl.txt \endpreamble \postamble -Copyright (C) 2012 by Andrew Stacey <loopspace@mathforge.org> +Copyright (C) 2012-2021 by Andrew Stacey <loopspace@mathforge.org> This file may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3 of this @@ -43,12 +43,13 @@ version 2005/12/01 or later. This work is "maintained" (as per LPPL maintenance status) by Andrew Stacey. -This work consists of the files hobby.dtx - hobby_doc.tex +This work consists of the files hobby_code.dtx + hobby.tex and the derived files hobby.code.tex pgflibraryhobby.code.tex tikzlibraryhobby.code.tex pml3array.sty + hobby-l3draw.sty hobby.ins hobby.pdf hobby_code.pdf @@ -56,15 +57,14 @@ and the derived files hobby.code.tex \endpostamble \usedir{tex/latex/hobby} -\generate{\file{tikzlibraryhobby.code.tex} {\from{hobby.dtx}{tikzlibrary}}} -\generate{\file{pgflibraryhobby.code.tex} {\from{hobby.dtx}{pgflibrary}}} -\generate{\file{hobby.code.tex} -{\from{hobby.dtx}{hobby}}} -\generate{\file{pml3array.sty} -{\from{hobby.dtx}{array}}} +\generate{\file{tikzlibraryhobby.code.tex} {\from{hobby_code.dtx}{tikzlibrary}}} +\generate{\file{pgflibraryhobby.code.tex} {\from{hobby_code.dtx}{pgflibrary}}} +\generate{\file{hobby.code.tex} {\from{hobby_code.dtx}{hobby}}} +\generate{\file{pml3array.sty} {\from{hobby_code.dtx}{array}}} +\generate{\file{hobby-l3draw.sty} {\from{hobby_code.dtx}{l3hobby}}} \endbatchfile %% -%% Copyright (C) 2012 by Andrew Stacey <loopspace@mathforge.org> +%% Copyright (C) 2012-2021 by Andrew Stacey <loopspace@mathforge.org> %% %% This file may be distributed and/or modified under the conditions %% of the LaTeX Project Public License, either version 1.3 of this @@ -79,16 +79,17 @@ and the derived files hobby.code.tex %% This work is "maintained" (as per LPPL maintenance status) by %% Andrew Stacey. %% -%% This work consists of the files hobby.dtx -%% hobby_doc.tex +%% This work consists of the files hobby_code.dtx +%% hobby.tex %% and the derived files hobby.code.tex %% pgflibraryhobby.code.tex %% tikzlibraryhobby.code.tex %% pml3array.sty +%% hobby-l3draw.sty %% hobby.ins %% hobby.pdf %% hobby_code.pdf %% README.txt %% %% -%% End of file `hobby.ins'. +%% End of file `hobby_code.ins'. |