
Gostaria de traduzir (Tx,Ty,Tz)
e girar (roll,pitch,yaw)
no espaço 3D um objeto definido de maneira scope
semelhante à que podemos fazer no espaço 2D abaixo:
\begin{scope}[shift={(7,9)},rotate=30]
% draw some object
\end{scope}
Existe alguma maneira simples de rotação e translação 3D?
Responder1
Aqui está uma solução, mas apenas para tradução (até agora). Ele usa o fato de que internamente TikZ
trata pontos 3D como 2D. Portanto, seu vetor de deslocamento 3D é salvo na coordenada mytranslation
que é um ponto 2D e, portanto, pode ser passado para shift
. As linhas grossas servem apenas para ilustrar que a tradução foi feita corretamente:
\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}
Editar 1:Finalmente consegui fazer a rotação, mas isso foi uma merda. Coloquei primeiro a base matemática para as rotações RPY, umamuito legalmatriz. Então peguei emprestada uma ideia deAndrew Staceydeessa questão: descobrir para onde os vetores unitários (cartesianos) apontam \pgfgetlastxy
. Aí foi só escrever a matriz em Tikz
notação, usar \pgfgetlastxy
mais uma vez e pronto!
\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}
Editar 2:Agora você pode passar um ponto para o comando e determinar para quais novas coordenadas xyz ele será mapeado. Além disso, inspirado emHerbertosolução, agora há um exemplo melhor com cubos e setas:
\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}
Responder2
um exemplo com PStricks. Execute-o comxelatex
\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º cubo: girado nos eixos x e y (centro da caixa em (-2,0,0))
- 2º: dimensionado por x = 0,75, y = 3, z = 0,5 (centro em (2,0,1))
- 3º: girado no eixo z e movido por (3,-2,0) (centro em (-2,0,0) )