
Я хотел бы переместить (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))