tikz-3dplot 的变换可以累积吗?

tikz-3dplot 的变换可以累积吗?

众所周知,Ti 中的转变Z 可以累积。例如

\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}

另一方面,对于 tikz-3dplot,第二个转换只会覆盖第一个转换。例如

\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}

我们怎样才能实现这一点?

总的来说,我想进一步旋转和移动坐标系。

答案1

我大概弄清楚了 tikz-3dplot 的工作原理以及如何增强它

\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}

答案2

我尝试遵循与 相同的数学运算\tdplotsetrotatedcoords,但为了获得相同的结果,我不得不使用负角度。在我看来,算法中的数学运算实际上与手册第 7 页上显示的内容不符。

\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}

演示

相关内容