summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/l3experimental/l3draw-transforms.dtx
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/l3experimental/l3draw-transforms.dtx
Initial commit
Diffstat (limited to 'macros/latex/contrib/l3experimental/l3draw-transforms.dtx')
-rw-r--r--macros/latex/contrib/l3experimental/l3draw-transforms.dtx339
1 files changed, 339 insertions, 0 deletions
diff --git a/macros/latex/contrib/l3experimental/l3draw-transforms.dtx b/macros/latex/contrib/l3experimental/l3draw-transforms.dtx
new file mode 100644
index 0000000000..3ab6a81bd6
--- /dev/null
+++ b/macros/latex/contrib/l3experimental/l3draw-transforms.dtx
@@ -0,0 +1,339 @@
+% \iffalse meta-comment
+%
+%% File: l3draw-transforms.dtx
+%
+% Copyright (C) 2018,2019 The LaTeX3 Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% http://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3experimental bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\RequirePackage{expl3}
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3draw-transforms} package\\ Transformations^^A
+% }
+%
+% \author{^^A
+% The \LaTeX3 Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2019-08-25}
+%
+% \maketitle
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3draw-transforms} implementation}
+%
+% \begin{macrocode}
+%<*initex|package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=draw>
+% \end{macrocode}
+%
+% This sub-module covers more-or-less the same ideas as
+% \texttt{pgfcoretransformations.code.tex}. At present, equivalents of the
+% following are currently absent:
+% \begin{itemize}
+% \item \cs{pgfgettransform}, \cs{pgfgettransformentries}: Awaiting use cases.
+% \item \cs{pgftransformlineattime}, \cs{pgftransformarcaxesattime},
+% \cs{pgftransformcurveattime}: Need to look at the use cases for
+% these to fully understand them.
+% \item \cs{pgftransformarrow}: Likely to be done when other arrow functions
+% are added.
+% \item \cs{pgflowlevelsynccm}, \cs{pgflowlevel}: Likely to be added when
+% use cases are encountered in other parts of the code.
+% \end{itemize}
+%
+% \begin{variable}{\l_@@_matrix_active_bool}
+% An internal flag to avoid redundant calculations.
+% \begin{macrocode}
+\bool_new:N \l_@@_matrix_active_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}
+% {
+% \l_@@_matrix_a_fp,
+% \l_@@_matrix_b_fp,
+% \l_@@_matrix_c_fp,
+% \l_@@_matrix_a_fp,
+% \l_@@_xshift_dim,
+% \l_@@_yshift_dim
+% }
+% The active matrix and shifts.
+% \begin{macrocode}
+\fp_new:N \l_@@_matrix_a_fp
+\fp_new:N \l_@@_matrix_b_fp
+\fp_new:N \l_@@_matrix_c_fp
+\fp_new:N \l_@@_matrix_d_fp
+\dim_new:N \l_@@_xshift_dim
+\dim_new:N \l_@@_yshift_dim
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\draw_transform_matrix_reset:, \draw_transform_shift_reset:}
+% Fast resetting.
+% \begin{macrocode}
+\cs_new_protected:Npn \draw_transform_matrix_reset:
+ {
+ \fp_set:Nn \l_@@_matrix_a_fp { 1 }
+ \fp_zero:N \l_@@_matrix_b_fp
+ \fp_zero:N \l_@@_matrix_c_fp
+ \fp_set:Nn \l_@@_matrix_d_fp { 1 }
+ }
+\cs_new_protected:Npn \draw_transform_shift_reset:
+ {
+ \dim_zero:N \l_@@_xshift_dim
+ \dim_zero:N \l_@@_yshift_dim
+ }
+\draw_transform_matrix_reset:
+\draw_transform_shift_reset:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\draw_transform_matrix_absolute:nnnn}
+% \begin{macro}{\draw_transform_shift_absolute:n}
+% \begin{macro}{\@@_transform_shift_absolute:nn}
+% Setting the transform matrix is straight-forward, with just a bit
+% of expansion to sort out. With the mechanism active, the identity
+% matrix is set.
+% \begin{macrocode}
+\cs_new_protected:Npn \draw_transform_matrix_absolute:nnnn #1#2#3#4
+ {
+ \fp_set:Nn \l_@@_matrix_a_fp {#1}
+ \fp_set:Nn \l_@@_matrix_b_fp {#2}
+ \fp_set:Nn \l_@@_matrix_c_fp {#3}
+ \fp_set:Nn \l_@@_matrix_d_fp {#4}
+ \bool_lazy_all:nTF
+ {
+ { \fp_compare_p:nNn \l_@@_matrix_a_fp = \c_one_fp }
+ { \fp_compare_p:nNn \l_@@_matrix_b_fp = \c_zero_fp }
+ { \fp_compare_p:nNn \l_@@_matrix_c_fp = \c_zero_fp }
+ { \fp_compare_p:nNn \l_@@_matrix_d_fp = \c_one_fp }
+ }
+ { \bool_set_false:N \l_@@_matrix_active_bool }
+ { \bool_set_true:N \l_@@_matrix_active_bool }
+ }
+\cs_new_protected:Npn \draw_transform_shift_absolute:n #1
+ {
+ \@@_point_process:nn
+ { \@@_transform_shift_absolute:nn } {#1}
+ }
+\cs_new_protected:Npn \@@_transform_shift_absolute:nn #1#2
+ {
+ \dim_set:Nn \l_@@_xshift_dim {#1}
+ \dim_set:Nn \l_@@_yshift_dim {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\draw_transform_matrix:nnnn}
+% \begin{macro}{\@@_transform:nnnn}
+% \begin{macro}{\draw_transform_shift:n}
+% \begin{macro}{\@@_transform_shift:nn}
+% Much the same story for adding to an existing matrix, with a bit of
+% pre-expansion so that the calculation uses \enquote{frozen} values.
+% \begin{macrocode}
+\cs_new_protected:Npn \draw_transform_matrix:nnnn #1#2#3#4
+ {
+ \use:x
+ {
+ \@@_transform:nnnn
+ { \fp_eval:n {#1} }
+ { \fp_eval:n {#2} }
+ { \fp_eval:n {#3} }
+ { \fp_eval:n {#4} }
+ }
+ }
+\cs_new_protected:Npn \@@_transform:nnnn #1#2#3#4
+ {
+ \use:x
+ {
+ \draw_transform_matrix_absolute:nnnn
+ { #1 * \l_@@_matrix_a_fp + #2 * \l_@@_matrix_c_fp }
+ { #1 * \l_@@_matrix_b_fp + #2 * \l_@@_matrix_d_fp }
+ { #3 * \l_@@_matrix_a_fp + #4 * \l_@@_matrix_c_fp }
+ { #3 * \l_@@_matrix_b_fp + #4 * \l_@@_matrix_d_fp }
+ }
+ }
+\cs_new_protected:Npn \draw_transform_shift:n #1
+ {
+ \@@_point_process:nn
+ { \@@_transform_shift:nn } {#1}
+ }
+\cs_new_protected:Npn \@@_transform_shift:nn #1#2
+ {
+ \dim_set:Nn \l_@@_xshift_dim { \l_@@_xshift_dim + #1 }
+ \dim_set:Nn \l_@@_yshift_dim { \l_@@_yshift_dim + #2 }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\draw_transform_matrix_invert:}
+% \begin{macro}{\@@_transform_invert:n, \@@_transform_invert:f}
+% \begin{macro}{\draw_transform_shift_invert:}
+% Standard mathematics: calculate the inverse matrix and use that, then
+% undo the shifts.
+% \begin{macrocode}
+\cs_new_protected:Npn \draw_transform_matrix_invert:
+ {
+ \bool_if:NT \l_@@_matrix_active_bool
+ {
+ \@@_transform_invert:f
+ {
+ \fp_eval:n
+ {
+ 1 /
+ (
+ \l_@@_matrix_a_fp * \l_@@_matrix_d_fp
+ - \l_@@_matrix_b_fp * \l_@@_matrix_c_fp
+ )
+ }
+ }
+ }
+ }
+\cs_new_protected:Npn \@@_transform_invert:n #1
+ {
+ \fp_set:Nn \l_@@_matrix_a_fp
+ { \l_@@_matrix_d_fp * #1 }
+ \fp_set:Nn \l_@@_matrix_b_fp
+ { -\l_@@_matrix_b_fp * #1 }
+ \fp_set:Nn \l_@@_matrix_c_fp
+ { -\l_@@_matrix_c_fp * #1 }
+ \fp_set:Nn \l_@@_matrix_d_fp
+ { \l_@@_matrix_a_fp * #1 }
+ }
+\cs_generate_variant:Nn \@@_transform_invert:n { f }
+\cs_new_protected:Npn \draw_transform_shift_invert:
+ {
+ \dim_set:Nn \l_@@_xshift_dim { -\l_@@_xshift_dim }
+ \dim_set:Nn \l_@@_yshift_dim { -\l_@@_yshift_dim }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\draw_transform_triangle:nnn}
+% Simple maths to move the canvas origin to |#1| and the two axes to
+% |#2| and |#3|.
+% \begin{macrocode}
+\cs_new_protected:Npn \draw_transform_triangle:nnn #1#2#3
+ {
+ \@@_point_process:nnn
+ {
+ \@@_point_process:nn
+ { \@@_tranform_triangle:nnnnnn }
+ {#1}
+ }
+ {#2} {#3}
+ }
+\cs_new_protected:Npn \@@_tranform_triangle:nnnnnn #1#2#3#4#5#6
+ {
+ \use:x
+ {
+ \draw_transform_matrix_absolute:nnnn
+ { #3 - #1 }
+ { #4 - #2 }
+ { #5 - #1 }
+ { #6 - #2 }
+ \draw_transform_shift_absolute:n { #1 , #2 }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {\draw_transform_scale:n, \draw_transform_xscale:n, \draw_transform_yscale:n}
+% \begin{macro}
+% {\draw_transform_xshift:n, \draw_transform_yshift:n}
+% \begin{macro}
+% {\draw_transform_xslant:n, \draw_transform_yslant:n}
+% Lots of shortcuts.
+% \begin{macrocode}
+\cs_new_protected:Npn \draw_transform_scale:n #1
+ { \draw_transform_matrix:nnnn { #1 } { 0 } { 0 } { #1 } }
+\cs_new_protected:Npn \draw_transform_xscale:n #1
+ { \draw_transform_matrix:nnnn { #1 } { 0 } { 0 } { 1 } }
+\cs_new_protected:Npn \draw_transform_yscale:n #1
+ { \draw_transform_matrix:nnnn { 1 } { 0 } { 0 } { #1 } }
+\cs_new_protected:Npn \draw_transform_xshift:n #1
+ { \draw_transform_shift:n { #1 , 0pt } }
+\cs_new_protected:Npn \draw_transform_yshift:n #1
+ { \draw_transform_shift:n { 0pt , #1 } }
+\cs_new_protected:Npn \draw_transform_xslant:n #1
+ { \draw_transform_matrix:nnnn { 1 } { 0 } { #1 } { 1 } }
+\cs_new_protected:Npn \draw_transform_yslant:n #1
+ { \draw_transform_matrix:nnnn { 1 } { #1 } { 0 } { 1 } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\draw_transform_rotate:n}
+% \begin{macro}
+% {
+% \@@_transform_rotate:n, \@@_transform_rotate:f,
+% \@@_transform_rotate:nn, \@@_transform_rotate:ff
+% }
+% Slightly more involved: evaluate the angle only once, and the sine and
+% cosine only once.
+% \begin{macrocode}
+\cs_new_protected:Npn \draw_transform_rotate:n #1
+ { \@@_transform_rotate:f { \fp_eval:n {#1} } }
+\cs_new_protected:Npn \@@_transform_rotate:n #1
+ {
+ \@@_transform_rotate:ff
+ { \fp_eval:n { cosd(#1) } }
+ { \fp_eval:n { sind(#1) } }
+ }
+\cs_generate_variant:Nn \@@_transform_rotate:n { f }
+\cs_new_protected:Npn \@@_transform_rotate:nn #1#2
+ { \draw_transform_matrix:nnnn {#1} {#2} { -#2 } { #1 } }
+\cs_generate_variant:Nn \@@_transform_rotate:nn { ff }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex