¿Se puede acumular la transformación de tikz-3dplot?

¿Se puede acumular la transformación de tikz-3dplot?

Es bien sabido que las transformaciones en TikZ se puede acumular. Por ejemplo

\documentclass{article}
\usepackage{tikz,tikz-3dplot}
\usetikzlibrary{}
\begin{document}

\tikz{
    \path                         node{1}
        [shift={(1,0)}]           node{2}
        [rotate=30][shift={(1,0)}]node{3}
        [rotate=30][shift={(1,0)}]node{5}
        [rotate=30][shift={(1,0)}]node{6}
        [rotate=30][shift={(1,0)}]node{7}
        [rotate=30][shift={(1,0)}]node{8};
}

\end{document}

Por otro lado, para tikz-3dplot, la segunda transformación simplemente sobrescribe la primera. Por ejemplo

\documentclass{article}
\usepackage{tikz,tikz-3dplot}
\usetikzlibrary{}
\begin{document}

\tdplotsetmaincoords{70}{110}
\begin{tikzpicture}[tdplot_main_coords]
    \draw[thick,->] (0,0,0) -- (1,0,0) node[anchor=north east]{$x$};
    \draw[thick,->] (0,0,0) -- (0,1,0) node[anchor=north west]{$y$};
    \draw[thick,->] (0,0,0) -- (0,0,1) node[anchor=south]{$z$};
    \tdplotsetrotatedcoords{30}{0}{0}
    \path[tdplot_rotated_coords](2,0,0)node{1};
    \tdplotsetrotatedcoords{30}{0}{0}
    \path[tdplot_rotated_coords](2,0,0)node{2};
    \tdplotsetrotatedcoords{30}{0}{0}
    \path[tdplot_rotated_coords](2,0,0)node{3};
    \tdplotsetrotatedcoords{30}{0}{0}
    \path[tdplot_rotated_coords](2,0,0)node{4};
\end{tikzpicture}

\end{document}

¿Cómo podemos hacer que esto funcione?

En general, me gustaría rotar y cambiar aún más el sistema de coordenadas.

Respuesta1

Más o menos descubrí cómo funciona tikz-3dplot y cómo mejorarlo.

\documentclass{beamer}
\usepackage{tikz,tikz-3dplot}
\begin{document}

\makeatletter

% enhance \tdplotsetmaincoords
\def\setMain#1#2{
    % disable \tikzset
    \let\tikzset\pgfutil@gobble
    % \tikzset is used here
    \tdplotsetmaincoords{#1}{#2}
    % repair \tikzset
    \def\tikzset{\pgfqkeys{/tikz}}
    \tikzset{Main/.style={x={(\raarot cm,\rbarot cm)},y={(\rabrot cm, \rbbrot cm)},z={(\racrot cm, \rbcrot cm)}}}
    % also setup Rotated coordinate
    \reRotate{0}{0}{0}
}

% enhance \tdplotsetrotatedcoords by appending the commented lines
% \resRotated means that the rotation is not accumulated.
\def\reRotate#1#2#3{
    % disable \tikzset
    \let\tikzset\pgfutil@gobble
    % \tikzset is used here
    \tdplotsetrotatedcoords{#1}{#2}{#3}
    % append the commented lines
    % see the source code tikz-3dplot.sty line 312-323
    \tdplotmult{\rcaeaa}{\rcarot}{\raaeul}
    \tdplotmult{\rcbeba}{\rcbrot}{\rbaeul}
    \tdplotmult{\rcceca}{\rccrot}{\rcaeul}
    \tdplotmult{\rcaeab}{\rcarot}{\rabeul}
    \tdplotmult{\rcbebb}{\rcbrot}{\rbbeul}
    \tdplotmult{\rccecb}{\rccrot}{\rcbeul}
    \tdplotmult{\rcaeac}{\rcarot}{\raceul}
    \tdplotmult{\rcbebc}{\rcbrot}{\rbceul}
    \tdplotmult{\rccecc}{\rccrot}{\rcceul}
    % see the source code tikz-3dplot.sty line 332-335
    \pgfmathsetmacro{\rcarc}{\rcaeaa+\rcbeba+\rcceca}
    \pgfmathsetmacro{\rcbrc}{\rcaeab+\rcbebb+\rccecb}
    \pgfmathsetmacro{\rccrc}{\rcaeac+\rcbebc+\rccecc}
    % repair \tikzset
    \def\tikzset{\pgfqkeys{/tikz}}
    \tikzset{Rotated/.style={x={(\raarc cm,\rbarc cm)},y={(\rabrc cm, \rbbrc cm)},z={(\racrc cm, \rbcrc cm)}}}%
}

% define a further-rotate version of \tdplotsetrotatedcoords
% \furtherRotate means that the rotation can be accumulated.
\def\furtherRotate#1#2#3{
    % before everything, deceive tikz-3dplot by letting main-coordinate to be rotated coordinate
    % in other words:
    %    \let\oldMain=\Main
    %    \let\Main=\Rotated
    %    \tdplotsetrotatedcoords{...}
    %    \let\Main=\oldMain
    \let\oldraarot\raarot\let\oldrabrot\rabrot\let\oldracrot\racrot
    \let\oldrbarot\rbarot\let\oldrbbrot\rbbrot\let\oldrbcrot\rbcrot
    \let\oldrcarot\rcarot\let\oldrcbrot\rcbrot\let\oldrccrot\rccrot
    \let\raarot\raarc    \let\rabrot\rabrc    \let\racrot\racrc
    \let\rbarot\rbarc    \let\rbbrot\rbbrc    \let\rbcrot\rbcrc
    \let\rcarot\rcarc    \let\rcbrot\rcbrc    \let\rccrot\rccrc
    %
    %
    % the following is like \tdplotsetrotatedcoords
    %
    %
    \reRotate{#1}{#2}{#3}
    %
    %
    % do not forget the \let\M=\oldM part
    %
    %
    \let\raarot\oldraarot\let\rabrot\oldrabrot\let\racrot\oldracrot
    \let\rbarot\oldrbarot\let\rbbrot\oldrbbrot\let\rbcrot\oldrbcrot
    \let\rcarot\oldrcarot\let\rcbrot\oldrcbrot\let\rccrot\oldrccrot
}

\def\Shift#1#2#3{
    \tikzset{Rotated}
    \pgfpointxyz{#1}{#2}{#3}
    \edef\temp@shift@vector{\noexpand\pgf@x\the\pgf@x\noexpand\pgf@y\the\pgf@y}
    \pgftransformshift{\temp@shift@vector}
}

\frame{
    $$
        \tikz[shorten >=.5em]{
            \setMain{70}{110}
            \draw[Main,thick,->](0,0,0)--(5,0,0)node{$X$};
            \draw[Main,thick,->](0,0,0)--(0,5,0)node{$Y$};
            \draw[Main,thick,->](0,0,0)--(0,0,5)node{$Z$};
            \only<+->{\reRotate{0}{0}{0}}
            \only<+->{\Shift{-1}{0}{0}}
            \only<+->{\Shift{-1}{0}{0}}
            \only<+->{\Shift{-1}{0}{0}}
            \only<+->{\furtherRotate{30}{0}{0}}
            \only<+->{\furtherRotate{30}{0}{0}}
            \only<+->{\furtherRotate{30}{0}{0}}
            \only<+->{\Shift{1}{0}{0}}
            \only<+->{\Shift{1}{0}{0}}
            \only<+->{\Shift{1}{0}{0}}
            \only<+->{\furtherRotate{0}{30}{0}}
            \only<+->{\furtherRotate{0}{30}{0}}
            \only<+->{\furtherRotate{0}{30}{0}}
            \only<+->{\Shift{-1}{0}{0}}
            \only<+->{\Shift{-1}{0}{0}}
            \only<+->{\Shift{-1}{0}{0}}
            \draw[Rotated,->](0,0,0)--(1,0,0)node{$x$};
            \draw[Rotated,->](0,0,0)--(0,1,0)node{$y$};
            \draw[Rotated,->](0,0,0)--(0,0,1)node{$z$};
        }
    $$
}

\end{document}

Respuesta2

Intenté seguir los mismos cálculos que \tdplotsetrotatedcoords, pero para obtener los mismos resultados tuve que usar ángulos negativos. No me parece que las matemáticas del algoritmo coincidan realmente con lo que se muestra en la página 7 del manual.

\documentclass{standalone}
\usepackage{tikz,tikz-3dplot}
\usetikzlibrary{}

\newif\iftdplotfirstrot
\tdplotfirstrottrue

% restored third row of transformation matrix
\renewcommand{\tdplotsetrotatedcoords}[3]{%
%
\tdplotfirstrotfalse
%
\pgfmathsetmacro{\tdplotalpha}{#1}
\pgfmathsetmacro{\tdplotbeta}{#2}
\pgfmathsetmacro{\tdplotgamma}{#3}
%
\tdplotcalctransformrotmain
%
%now, determine master rotation matrix to define euler-rotated coordinates within the display coordinate frame
\tdplotmult{\raaeaa}{\raarot}{\raaeul}
\tdplotmult{\rabeba}{\rabrot}{\rbaeul}
\tdplotmult{\raceca}{\racrot}{\rcaeul}
%
\tdplotmult{\raaeab}{\raarot}{\rabeul}
\tdplotmult{\rabebb}{\rabrot}{\rbbeul}
\tdplotmult{\racecb}{\racrot}{\rcbeul}
%
\tdplotmult{\raaeac}{\raarot}{\raceul}
\tdplotmult{\rabebc}{\rabrot}{\rbceul}
\tdplotmult{\racecc}{\racrot}{\rcceul}
%
\tdplotmult{\rbaeaa}{\rbarot}{\raaeul}
\tdplotmult{\rbbeba}{\rbbrot}{\rbaeul}
\tdplotmult{\rbceca}{\rbcrot}{\rcaeul}
%
\tdplotmult{\rbaeab}{\rbarot}{\rabeul}
\tdplotmult{\rbbebb}{\rbbrot}{\rbbeul}
\tdplotmult{\rbcecb}{\rbcrot}{\rcbeul}
%
\tdplotmult{\rbaeac}{\rbarot}{\raceul}
\tdplotmult{\rbbebc}{\rbbrot}{\rbceul}
\tdplotmult{\rbcecc}{\rbcrot}{\rcceul}
%
\tdplotmult{\rcaeaa}{\rcarot}{\raaeul}
\tdplotmult{\rcbeba}{\rcbrot}{\rbaeul}
\tdplotmult{\rcceca}{\rccrot}{\rcaeul}
%
\tdplotmult{\rcaeab}{\rcarot}{\rabeul}
\tdplotmult{\rcbebb}{\rcbrot}{\rbbeul}
\tdplotmult{\rccecb}{\rccrot}{\rcbeul}
%
\tdplotmult{\rcaeac}{\rcarot}{\raceul}
\tdplotmult{\rcbebc}{\rcbrot}{\rbceul}
\tdplotmult{\rccecc}{\rccrot}{\rcceul}
%
%set up the master rotation matrix elements
\pgfmathsetmacro{\raarc}{\raaeaa + \rabeba + \raceca}
\pgfmathsetmacro{\rabrc}{\raaeab + \rabebb + \racecb}
\pgfmathsetmacro{\racrc}{\raaeac + \rabebc + \racecc}
\pgfmathsetmacro{\rbarc}{\rbaeaa + \rbbeba + \rbceca}
\pgfmathsetmacro{\rbbrc}{\rbaeab + \rbbebb + \rbcecb}
\pgfmathsetmacro{\rbcrc}{\rbaeac + \rbbebc + \rbcecc}
\pgfmathsetmacro{\rcarc}{\rcaeaa + \rcbeba + \rcceca}
\pgfmathsetmacro{\rcbrc}{\rcaeab + \rcbebb + \rccecb}
\pgfmathsetmacro{\rccrc}{\rcaeac + \rcbebc + \rccecc}
%
%save global values
\global\let\tdplotraa=\raarc
\global\let\tdplotrab=\rabrc
\global\let\tdplotrac=\racrc
\global\let\tdplotrba=\rbarc
\global\let\tdplotrbb=\rbbrc
\global\let\tdplotrbc=\rbcrc
\global\let\tdplotrca=\rcarc
\global\let\tdplotrcb=\rcbrc
\global\let\tdplotrcc=\rccrc
%
\tikzset{tdplot_rotated_coords/.append style={x={(\raarc cm,\rbarc cm)},y={(\rabrc cm, \rbbrc cm)},z={(\racrc cm, \rbcrc cm)}}}%
}

%
\newcommand{\tdplotaddrotatedcoords}[3]{%
\iftdplotfirstrot
  \tdplotsetrotatedcoords{#1}{#2}{#3}%
\else
%
\pgfmathsetmacro{\tdplotalpha}{-#1}
\pgfmathsetmacro{\tdplotbeta}{-#2}
\pgfmathsetmacro{\tdplotgamma}{-#3}
%
\tdplotcalctransformmainrot
%now, apply rotation matrix to previous transormation
\tdplotmult{\raaeaa}{\tdplotraa}{\raaeul}
\tdplotmult{\rabeba}{\tdplotrab}{\rbaeul}
\tdplotmult{\raceca}{\tdplotrac}{\rcaeul}
%
\tdplotmult{\raaeab}{\tdplotraa}{\rabeul}
\tdplotmult{\rabebb}{\tdplotrab}{\rbbeul}
\tdplotmult{\racecb}{\tdplotrac}{\rcbeul}
%
\tdplotmult{\raaeac}{\tdplotraa}{\raceul}
\tdplotmult{\rabebc}{\tdplotrab}{\rbceul}
\tdplotmult{\racecc}{\tdplotrac}{\rcceul}
%
\tdplotmult{\rbaeaa}{\tdplotrba}{\raaeul}
\tdplotmult{\rbbeba}{\tdplotrbb}{\rbaeul}
\tdplotmult{\rbceca}{\tdplotrbc}{\rcaeul}
%
\tdplotmult{\rbaeab}{\tdplotrba}{\rabeul}
\tdplotmult{\rbbebb}{\tdplotrbb}{\rbbeul}
\tdplotmult{\rbcecb}{\tdplotrbc}{\rcbeul}
%
\tdplotmult{\rbaeac}{\tdplotrba}{\raceul}
\tdplotmult{\rbbebc}{\tdplotrbb}{\rbceul}
\tdplotmult{\rbcecc}{\tdplotrbc}{\rcceul}
%
\tdplotmult{\rcaeaa}{\tdplotrca}{\raaeul}
\tdplotmult{\rcbeba}{\tdplotrcb}{\rbaeul}
\tdplotmult{\rcceca}{\tdplotrcc}{\rcaeul}
%
\tdplotmult{\rcaeab}{\tdplotrca}{\rabeul}
\tdplotmult{\rcbebb}{\tdplotrcb}{\rbbeul}
\tdplotmult{\rccecb}{\tdplotrcc}{\rcbeul}
%
\tdplotmult{\rcaeac}{\tdplotrca}{\raceul}
\tdplotmult{\rcbebc}{\tdplotrcb}{\rbceul}
\tdplotmult{\rccecc}{\tdplotrcc}{\rcceul}
%
%set up the master rotation matrix elements
\pgfmathsetmacro{\raarc}{\raaeaa + \rabeba + \raceca}
\pgfmathsetmacro{\rabrc}{\raaeab + \rabebb + \racecb}
\pgfmathsetmacro{\racrc}{\raaeac + \rabebc + \racecc}
\pgfmathsetmacro{\rbarc}{\rbaeaa + \rbbeba + \rbceca}
\pgfmathsetmacro{\rbbrc}{\rbaeab + \rbbebb + \rbcecb}
\pgfmathsetmacro{\rbcrc}{\rbaeac + \rbbebc + \rbcecc}
\pgfmathsetmacro{\rcarc}{\rcaeaa + \rcbeba + \rcceca}
\pgfmathsetmacro{\rcbrc}{\rcaeab + \rcbebb + \rccecb}
\pgfmathsetmacro{\rccrc}{\rcaeac + \rcbebc + \rccecc}
%
%save global values
\global\let\tdplotraa=\raarc
\global\let\tdplotrab=\rabrc
\global\let\tdplotrac=\racrc
\global\let\tdplotrba=\rbarc
\global\let\tdplotrbb=\rbbrc
\global\let\tdplotrbc=\rbcrc
\global\let\tdplotrca=\rcarc
\global\let\tdplotrcb=\rcbrc
\global\let\tdplotrcc=\rccrc
%
\tikzset{tdplot_rotated_coords/.append style={x={(\raarc cm,\rbarc cm)},y={(\rabrc cm, \rbbrc cm)},z={(\racrc cm, \rbcrc cm)}}}%
\fi}

\begin{document}
\tdplotsetmaincoords{70}{110}
\begin{tikzpicture}[tdplot_main_coords]
    \draw[thick,->] (0,0,0) -- (1,0,0) node[anchor=north east]{$x$};
    \draw[thick,->] (0,0,0) -- (0,1,0) node[anchor=north west]{$y$};
    \draw[thick,->] (0,0,0) -- (0,0,1) node[anchor=south]{$z$};
    \tdplotsetrotatedcoords{0}{0}{0}
    \foreach \i in {1,2,3,4}{
      \tdplotaddrotatedcoords{30}{0}{0}
      \draw[red,tdplot_rotated_coords] (0,0,0) -- (2,0,0)node{\i};
    }
\end{tikzpicture}
\end{document}

manifestación

información relacionada