Tikz:: сдвиг и вращение в 3D?

Tikz:: сдвиг и вращение в 3D?

Я хотел бы переместить (Tx,Ty,Tz)и повернуть (roll,pitch,yaw)в трехмерном пространстве объект, определенный scopeаналогично тому, как мы можем это сделать в двухмерном пространстве, как показано ниже:

\begin{scope}[shift={(7,9)},rotate=30]
% draw some object
\end{scope}

Есть ли простой способ 3D-вращения и перемещения?

решение1

Вот решение, но только для переноса (пока). Оно использует тот факт, что внутренне TikZобрабатывает 3D-точки как 2D-точки. Таким образом, ваш вектор 3D-сдвига сохраняется в координате mytranslation, которая затем становится 2D-точкой и, таким образом, может быть передана в shift. Толстые линии просто иллюстрируют, что перенос выполнен правильно:

\documentclass{standalone}
\usepackage{tikz}

\newcommand{\translatepoint}[1]%
{   \coordinate (mytranslation) at (#1);
}

\newcommand{\somedrawing}%
{   \coordinate (a) at (0,0,0);
    \coordinate (b) at (5,1,0);
    \coordinate (c) at (2,4,0);
    \coordinate (d) at (1,-1,-4);
    \draw (a) -- (b) (a) -- (c) (a) -- (d) (b) -- (c) (b) -- (d) (c) -- (d);
}

\begin{document}

\begin{tikzpicture}[x={(0.866cm,0.5cm)},y={(-0.866cm,0.5cm)},z={(0cm,1cm)}]
    \somedrawing    

    \translatepoint{5,0,0}
    \draw[very thick,red] (0,0,0) -- (5,0,0);
    \begin{scope}[shift=(mytranslation),draw=red]
        \somedrawing
    \end{scope}

    \translatepoint{0,6,0}
    \draw[very thick,blue] (0,0,0) -- (0,6,0);
    \begin{scope}[shift=(mytranslation),draw=blue]
        \somedrawing
    \end{scope}

    \translatepoint{0,0,8}
    \draw[very thick,green!50!gray] (0,0,0) -- (0,0,8);
    \begin{scope}[shift=(mytranslation),draw=green!50!gray]
        \somedrawing
    \end{scope}

    \translatepoint{-5,0,-2}
    \draw[very thick,orange] (0,0,0) -- (-5,0,-2);
    \begin{scope}[shift=(mytranslation),draw=orange]
        \somedrawing
    \end{scope}
\end{tikzpicture}

\end{document}

введите описание изображения здесь


Редактировать 1:Я, наконец, справился с вращением, но это было ужасно. Я сначала поставил математическую основу для вращений RPY,действительно миломатрица. Тогда я позаимствовал идею изЭндрю Стейсиотэтот вопрос: нахождение того, куда указывают (декартовы) единичные векторы с помощью \pgfgetlastxy. Затем оставалось только записать матрицу в Tikzнотации, \pgfgetlastxyснова используя , и вот вам!

\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}
\usetikzlibrary{arrows}
\usepackage{amsmath}

\newcommand{\rotateRPY}[3]% roll, pitch, yaw
{   \pgfmathsetmacro{\rollangle}{#1}
    \pgfmathsetmacro{\pitchangle}{#2}
    \pgfmathsetmacro{\yawangle}{#3}

    % to what vector is the x unit vector transformed, and which 2D vector is this?
    \pgfmathsetmacro{\newxx}{cos(\yawangle)*cos(\pitchangle)}
    \pgfmathsetmacro{\newxy}{sin(\yawangle)*cos(\pitchangle)}
    \pgfmathsetmacro{\newxz}{-sin(\pitchangle)}
    \path (\newxx,\newxy,\newxz);
    \pgfgetlastxy{\nxx}{\nxy};

    % to what vector is the y unit vector transformed, and which 2D vector is this?
    \pgfmathsetmacro{\newyx}{cos(\yawangle)*sin(\pitchangle)*sin(\rollangle)-sin(\yawangle)*cos(\rollangle)}
    \pgfmathsetmacro{\newyy}{sin(\yawangle)*sin(\pitchangle)*sin(\rollangle)+ cos(\yawangle)*cos(\rollangle)}
    \pgfmathsetmacro{\newyz}{cos(\pitchangle)*sin(\rollangle)}
    \path (\newyx,\newyy,\newyz);
    \pgfgetlastxy{\nyx}{\nyy};

    % to what vector is the z unit vector transformed, and which 2D vector is this?
    \pgfmathsetmacro{\newzx}{cos(\yawangle)*sin(\pitchangle)*cos(\rollangle)+ sin(\yawangle)*sin(\rollangle)}
    \pgfmathsetmacro{\newzy}{sin(\yawangle)*sin(\pitchangle)*cos(\rollangle)-cos(\yawangle)*sin(\rollangle)}
    \pgfmathsetmacro{\newzz}{cos(\pitchangle)*cos(\rollangle)}
    \path (\newzx,\newzy,\newzz);
    \pgfgetlastxy{\nzx}{\nzy};
}

\tikzset{RPY/.style={x={(\nxx,\nxy)},y={(\nyx,\nyy)},z={(\nzx,\nzy)}}}

\begin{document}

$R=\begin{pmatrix}
    \cos \alpha \cos \beta
&   \textcolor{red}{\cos \alpha \sin \beta \sin \gamma - \sin \alpha \cos \gamma}
&   \cos \alpha \sin \beta \cos \gamma + \sin \alpha \sin \gamma \\
    \textcolor{red}{\sin \alpha \cos \beta}
&   \sin \alpha \sin \beta \sin \gamma + \cos \alpha \cos \gamma
&   \textcolor{red}{\sin \alpha \sin \beta \cos \gamma - \cos \alpha \sin \gamma} \\
    - \sin \beta
&   \textcolor{red}{\cos \beta \sin \gamma}
&   \cos \beta \cos \gamma
\end{pmatrix}\\p'=R\cdot p$

\begin{tikzpicture}
    \draw[-latex] node at (3.5,0,0) {x} (0,0,0) -- (3,0,0);
    \draw[-latex] node at (0,3.5,0) {y} (0,0,0) -- (0,3,0);
    \draw[-latex] node at (0,0,3.5) {z} (0,0,0) -- (0,0,3);

    \rotateRPY{0}{0}{45}
    \begin{scope}[draw=red, text=red,fill=red,densely dashed,RPY]
        \draw[-latex] node at (3.5,0,0) {x} (0,0,0) -- (3,0,0);
        \draw[-latex] node at (0,3.5,0) {y} (0,0,0) -- (0,3,0);
        \draw[-latex] node at (0,0,3.5) {z} (0,0,0) -- (0,0,3);
    \end{scope}
    \node[fill=white,fill opacity=0.7,text opacity=1] {RPY: 0,0,45};
\end{tikzpicture}
\begin{tikzpicture}
    \draw[-latex] node at (3.5,0,0) {x} (0,0,0) -- (3,0,0);
    \draw[-latex] node at (0,3.5,0) {y} (0,0,0) -- (0,3,0);
    \draw[-latex] node at (0,0,3.5) {z} (0,0,0) -- (0,0,3);

    \rotateRPY{0}{30}{0}
    \begin{scope}[draw=red, text=red,fill=red,densely dashed,RPY]
        \draw[-latex] node at (3.5,0,0) {x} (0,0,0) -- (3,0,0);
        \draw[-latex] node at (0,3.5,0) {y} (0,0,0) -- (0,3,0);
        \draw[-latex] node at (0,0,3.5) {z} (0,0,0) -- (0,0,3);
    \end{scope}
    \node[fill=white,fill opacity=0.7,text opacity=1] {RPY: 0,30,0};
\end{tikzpicture}

\begin{tikzpicture}
\draw[-latex] node at (3.5,0,0) {x} (0,0,0) -- (3,0,0);
    \draw[-latex] node at (0,3.5,0) {y} (0,0,0) -- (0,3,0);
    \draw[-latex] node at (0,0,3.5) {z} (0,0,0) -- (0,0,3);

    \rotateRPY{80}{0}{0}
    \begin{scope}[draw=red, text=red,fill=red,densely dashed,RPY]
        \draw[-latex] node at (3.5,0,0) {x} (0,0,0) -- (3,0,0);
        \draw[-latex] node at (0,3.5,0) {y} (0,0,0) -- (0,3,0);
        \draw[-latex] node at (0,0,3.5) {z} (0,0,0) -- (0,0,3);
    \end{scope}
    \node[fill=white,fill opacity=0.7,text opacity=1] {RPY: 80,0,0};
\end{tikzpicture}
\begin{tikzpicture}[x={(0.866cm,-0.5cm)},y={(-0.866cm,-0.5cm)},z={(0cm,1cm)}]
\draw[-latex] node at (3.5,0,0) {x} (0,0,0) -- (3,0,0);
    \draw[-latex] node at (0,3.5,0) {y} (0,0,0) -- (0,3,0);
    \draw[-latex] node at (0,0,3.5) {z} (0,0,0) -- (0,0,3);

    \rotateRPY{13}{171}{55}
    \begin{scope}[draw=red, text=red,fill=red,densely dashed,RPY]
        \draw[-latex] node at (3.5,0,0) {x} (0,0,0) -- (3,0,0);
        \draw[-latex] node at (0,3.5,0) {y} (0,0,0) -- (0,3,0);
        \draw[-latex] node at (0,0,3.5) {z} (0,0,0) -- (0,0,3);
    \end{scope}
    \node[fill=white,fill opacity=0.7,text opacity=1] {RPY: 13,171,55};
\end{tikzpicture}

\end{document}

введите описание изображения здесь


Редактировать 2:Теперь вы можете передать точку команде и определить, к каким новым координатам xyz она привязана. Также, вдохновленныйГербертрешение, теперь есть лучший пример с кубиками и стрелками:

\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}
\usetikzlibrary{arrows,3D}

\newcommand{\savedx}{0}
\newcommand{\savedy}{0}
\newcommand{\savedz}{0}

\newcommand{\somedrawing}%
{   \coordinate (a) at (-2,-2,-2);
    \coordinate (b) at (-2,-2,2);
    \coordinate (c) at (-2,2,-2);
    \coordinate (d) at (-2,2,2);
    \coordinate (e) at (2,-2,-2);
    \coordinate (f) at (2,-2,2);
    \coordinate (g) at (2,2,-2);
    \coordinate (h) at (2,2,2);
    \draw (a)--(b) (a)--(c) (a)--(e) (b)--(d) (b)--(f) (c)--(d) (c)--(g) (d)--(h) (e)--(f) (e)--(g) (f)--(h) (g)--(h);
    \fill (a) circle (0.1cm);
    \fill (d) ++(0.1cm,0.1cm) rectangle ++(-0.2cm,-0.2cm);
}

\newcommand{\rotateRPY}[4][0/0/0]% point to be saved to \savedxyz, roll, pitch, yaw
{   \pgfmathsetmacro{\rollangle}{#2}
    \pgfmathsetmacro{\pitchangle}{#3}
    \pgfmathsetmacro{\yawangle}{#4}

    % to what vector is the x unit vector transformed, and which 2D vector is this?
    \pgfmathsetmacro{\newxx}{cos(\yawangle)*cos(\pitchangle)}% a
    \pgfmathsetmacro{\newxy}{sin(\yawangle)*cos(\pitchangle)}% d
    \pgfmathsetmacro{\newxz}{-sin(\pitchangle)}% g
    \path (\newxx,\newxy,\newxz);
    \pgfgetlastxy{\nxx}{\nxy};

    % to what vector is the y unit vector transformed, and which 2D vector is this?
    \pgfmathsetmacro{\newyx}{cos(\yawangle)*sin(\pitchangle)*sin(\rollangle)-sin(\yawangle)*cos(\rollangle)}% b
    \pgfmathsetmacro{\newyy}{sin(\yawangle)*sin(\pitchangle)*sin(\rollangle)+ cos(\yawangle)*cos(\rollangle)}% e
    \pgfmathsetmacro{\newyz}{cos(\pitchangle)*sin(\rollangle)}% h
    \path (\newyx,\newyy,\newyz);
    \pgfgetlastxy{\nyx}{\nyy};

    % to what vector is the z unit vector transformed, and which 2D vector is this?
    \pgfmathsetmacro{\newzx}{cos(\yawangle)*sin(\pitchangle)*cos(\rollangle)+ sin(\yawangle)*sin(\rollangle)}
    \pgfmathsetmacro{\newzy}{sin(\yawangle)*sin(\pitchangle)*cos(\rollangle)-cos(\yawangle)*sin(\rollangle)}
    \pgfmathsetmacro{\newzz}{cos(\pitchangle)*cos(\rollangle)}
    \path (\newzx,\newzy,\newzz);
    \pgfgetlastxy{\nzx}{\nzy};

    % transform the point given by #1
    \foreach \x/\y/\z in {#1}
    {   \pgfmathsetmacro{\transformedx}{\x*\newxx+\y*\newyx+\z*\newzx}
        \pgfmathsetmacro{\transformedy}{\x*\newxy+\y*\newyy+\z*\newzy}
        \pgfmathsetmacro{\transformedz}{\x*\newxz+\y*\newyz+\z*\newzz}
        \xdef\savedx{\transformedx}
        \xdef\savedy{\transformedy}
        \xdef\savedz{\transformedz}     
    }
}

\tikzset{RPY/.style={x={(\nxx,\nxy)},y={(\nyx,\nyy)},z={(\nzx,\nzy)}}}

\begin{document}

\begin{tikzpicture}
    \somedrawing
    \rotateRPY{0}{0}{101}
    \begin{scope}[draw=red, text=red,fill=red,densely dashed,RPY]
        \somedrawing
    \end{scope}
    \draw[canvas is xy plane at z=2,-latex,thick, blue] (-2,2) arc (135:236:2.828);
    \node[fill=white,fill opacity=0.7,text opacity=1] {RPY: 0,0,101};
\end{tikzpicture}
\begin{tikzpicture}
    \somedrawing    
    \rotateRPY{0}{55}{0}
    \begin{scope}[draw=red, text=red,fill=red,densely dashed,RPY]
        \somedrawing
    \end{scope}
    \draw[canvas is xz plane at y=2,-latex,thick, blue] (-2,2) arc (135:80:2.828);
    \node[fill=white,fill opacity=0.7,text opacity=1] {RPY: 0,55,0};
\end{tikzpicture}

\begin{tikzpicture}
    \somedrawing    
    \rotateRPY{61}{0}{0}
    \begin{scope}[draw=red, text=red,fill=red,densely dashed,RPY]
        \somedrawing
    \end{scope}
    \draw[canvas is yz plane at x=-2,-latex,thick, blue] (2,2) arc (45:106:2.828);
    \node[fill=white,fill opacity=0.7,text opacity=1] {RPY: 71,0,0};
\end{tikzpicture}
\begin{tikzpicture}%[x={(1cm,1cm)},y={(-1cm,1cm)},z={(-2cm,-1cm)}]
    \somedrawing    
    \rotateRPY[-2/2/2]{13}{171}{55}
    \node[fill=white,fill opacity=0.7,text opacity=1,align=left,text=blue] at (5,2)  {-2 $\longrightarrow$ \savedx \\ 2 $\longrightarrow$ \savedy \\ 2 $\longrightarrow$ \savedz};  
    \begin{scope}[draw=red, text=red,fill=red,densely dashed,RPY]
        \somedrawing
    \end{scope}
    \draw[blue,ultra thick] (-2,2,2) -- (\savedx,2,2) -- (\savedx,\savedy,2) -- (\savedx,\savedy,\savedz) circle (0.25);
    \rotateRPY[-2/-2/-2]{13}{171}{55}
    \node[fill=white,fill opacity=0.7,text opacity=1,align=left,text=green!50!gray] at (5,0)  {-2 $\longrightarrow$ \savedx \\ -2 $\longrightarrow$ \savedy \\ -2 $\longrightarrow$ \savedz};
    \draw[green!50!gray,ultra thick] (-2,-2,-2) -- (\savedx,-2,-2) -- (\savedx,\savedy,-2) -- (\savedx,\savedy,\savedz) circle (0.25);
    \node[fill=white,fill opacity=0.7,text opacity=1] {RPY: 13,171,55};
\end{tikzpicture}

\end{document}

введите описание изображения здесь

решение2

пример с PStricks. Запустите его сxelatex

\documentclass{article}
\pagestyle{empty}
\setlength\parindent{0pt}
\usepackage{pst-solides3d}
\begin{document}
\psset{viewpoint=20 60 20 rtp2xyz,lightsrc=10 15 7,Decran=20}
\begin{pspicture}(-5,-5)(6,5)
\psSolid[object=grille,base=-3 3 -3 3,fillcolor=red!50]
\axesIIID(4,4,3)
\psSolid[object=cube,a=2,ngrid=3,RotX=45,RotY=30,fillcolor=yellow!50](-2,0,0)
\psSolid[object=cube,a=2,ngrid=3,transform={.75 3 .5 scaleOpoint3d}](2,0,1)
\psSolid[object=cube,a=2,ngrid=3,RotZ=30,transform={ 3 -2 0 addv3d },action=draw](-2,0,0)
\end{pspicture}
\end{document}
  • 1-й куб: повёрнут вокруг осей x и y (центр куба в точке (-2,0,0) )
  • 2-й: масштабирован по x=0,75, y=3, z=0,5 (центр в (2,0,1) )
  • 3-й: повернутый по оси z и перемещенный на (3,-2,0) (центр в точке (-2,0,0))

введите описание изображения здесь

Связанный контент