Estou pesquisando isso há horas, mas não encontrei um motivo para esse comportamento:
Aqui está meu exemplo:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{3d}
\begin{document}
\begin{tikzpicture}[x={(0.866cm,0.5cm)},y={(-0.866cm,0.5cm)},z={(0cm,1cm)}]
\fill[blue!50,opacity=0.6] (0,0,0) rectangle (2,1,0);
\fill[green!50,opacity=0.6] (0,0,0) -- (2,0,0) -- (2,1,0) -- (0,1,0) -- (0,0,0);
\draw[->] (0,0,0) -- (1,0,0);
\draw[->] (0,0,0) -- (0,1,0);
\draw[->] (0,0,0) -- (0,0,1);
\begin{scope}[xshift=3cm]
\fill[blue!50,opacity=0.6] (0,0,0) circle (1);
\draw[->] (0,0,0) -- (1,0,0);
\draw[->] (0,0,0) -- (0,1,0);
\draw[->] (0,0,0) -- (0,0,1);
\end{scope}
\end{tikzpicture}
\end{document}
Eu esperaria que ambos os retângulos fossem pintados da mesma forma. Para ser mais preciso, ambos deveriam aparecer como o verde, mas não.
Obviamente, a coordenada do canto superior direito (2,1,0) está correta para ambos os retângulos, mas apenas o verde se alinha corretamente com os eixos do sistema de coordenadas.
Em comparação a isso, o círculo utiliza corretamente os vetores modificados, pois é desenhado como uma elipse.
O que devo fazer para que o retângulo azul seja pintado como o verde?
Editar: Eu encontrei algo interessante emesseresponder. Aparentemente o código a seguir funciona, mas acho um pouco inconveniente colocar todos os meus retângulos em escopos.
Além disso, écanvas é o plano xy em zrealmente implementado da maneira errada? Por que isso não foi corrigido, então?
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{3d}
\makeatletter
\tikzoption{canvas is xy plane at z}[]{%
\def\tikz@plane@origin{\pgfpointxyz{0}{0}{#1}}%
\def\tikz@plane@x{\pgfpointxyz{1}{0}{#1}}%
\def\tikz@plane@y{\pgfpointxyz{0}{1}{#1}}%
\tikz@canvas@is@plane
}
\makeatother
\begin{document}
\begin{tikzpicture}[x={(0.866cm,0.5cm)},y={(-0.866cm,0.5cm)},z={(0cm,1cm)}]
\begin{scope}[canvas is xy plane at z=0,transform shape]
\fill[blue!50,opacity=0.6] (0,0,0) rectangle (2,1,0);
\end{scope}
\fill[green!50,opacity=0.6] (0,0,0) -- (2,0,0) -- (2,1,0) -- (0,1,0) -- (0,0,0);
\draw[->] (0,0,0) -- (1,0,0);
\draw[->] (0,0,0) -- (0,1,0);
\draw[->] (0,0,0) -- (0,0,1);
\begin{scope}[xshift=3cm]
\fill[blue!50,opacity=0.6] (0,0,0) circle (1);
\draw[->] (0,0,0) -- (1,0,0);
\draw[->] (0,0,0) -- (0,1,0);
\draw[->] (0,0,0) -- (0,0,1);
\end{scope}
\end{tikzpicture}
\end{document}
Responder1
Você não precisa colocar os comandos em um escopo, você pode passar as opções diretamente para os comandos:
\draw[canvas is xy plane at z=0] ...;
,
mas isso aumenta muito o comprimento da linha. Em vez disso, você pode definir estilos com um parâmetro para usá-los:
\tikzset{my style name/.style={canvas is xy plane at z=#1}}
E como uma pequena observação: em vez de fornecer os vetores unitários na forma cartesiana (o que é muito inconveniente se você quiser alterá-los), você pode usar a notação polar:
[x={(0.866cm,0.5cm)}]
[x={(-30:1cm)}
Código
\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{3d}
\makeatletter
\tikzoption{canvas is xy plane at z}[]{%
\def\tikz@plane@origin{\pgfpointxyz{0}{0}{#1}}%
\def\tikz@plane@x{\pgfpointxyz{1}{0}{#1}}%
\def\tikz@plane@y{\pgfpointxyz{0}{1}{#1}}%
\tikz@canvas@is@plane
}
\makeatother
\tikzset{xyp/.style={canvas is xy plane at z=#1}}
\tikzset{xzp/.style={canvas is xz plane at y=#1}}
\tikzset{yzp/.style={canvas is yz plane at x=#1}}
\begin{document}
\begin{tikzpicture}[x={(-30:1cm)},y={(210:1cm)},z={(90:1cm)}]
\draw[->] (0,0,0) -- node[pos=1.2] {x} (1,0,0);
\draw[->] (0,0,0) -- node[pos=1.2] {y} (0,1,0);
\draw[->] (0,0,0) -- node[pos=1.2] {z} (0,0,1);
\foreach \n in {-0.1,-0.2,...,-2}
{ \fill[opacity=0.3,yellow,draw=black,xyp=\n] (0-\n/5,0-\n/5) rectangle (2+\n/5,2+\n/5);
\fill[opacity=0.3,red,draw=black,xzp=\n] (0,0) (0-\n/5,0-\n/5) rectangle (2+\n/5,2+\n/5);
\fill[opacity=0.3,blue,draw=black,yzp=\n] (0,0) (0-\n/5,0-\n/5) rectangle (2+\n/5,2+\n/5);
}
\end{tikzpicture}
\end{document}
Saída
Responder2
Lendo a fonte, descobri que você só precisa substituir
canvas is xy plane at z
por
canvas is yx plane at z
Sua definição em tikzlibrary3d.code.tex
são
\tikzoption{canvas is xy plane at z}{% \tikz@addtransform{\pgftransformshift{\pgfpointxyz{0}{0}{#1}}}% } \tikzoption{canvas is yx plane at z}[]{% \def\tikz@plane@origin{\pgfpointxyz{0}{0}{#1}}% \def\tikz@plane@x{\pgfpointxyz{0}{1}{#1}}% \def\tikz@plane@y{\pgfpointxyz{1}{0}{#1}}% \tikz@canvas@is@plane }
Por exemplo, a resposta de @Tom Bombadil pode ser modificada para
\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{3d}
\tikzset{xyp/.style={canvas is yx plane at z=#1}}
\tikzset{xzp/.style={canvas is xz plane at y=#1}}
\tikzset{yzp/.style={canvas is yz plane at x=#1}}
\begin{document}
\begin{tikzpicture}[x={(-30:1cm)},y={(210:1cm)},z={(90:1cm)}]
\draw[->] (0,0,0) -- node[pos=1.2] {x} (1,0,0);
\draw[->] (0,0,0) -- node[pos=1.2] {y} (0,1,0);
\draw[->] (0,0,0) -- node[pos=1.2] {z} (0,0,1);
\foreach \n in {-0.1,-0.2,...,-2}
{ \fill[opacity=0.3,yellow,draw=black,xyp=\n] (0-\n/5,0-\n/5) rectangle (2+\n/5,2+\n/5);
\fill[opacity=0.3,red,draw=black,xzp=\n] (0,0) (0-\n/5,0-\n/5) rectangle (2+\n/5,2+\n/5);
\fill[opacity=0.3,blue,draw=black,yzp=\n] (0,0) (0-\n/5,0-\n/5) rectangle (2+\n/5,2+\n/5);
}
\end{tikzpicture}
\end{document}
E a saída é exatamente a mesma.
Aparentemente, @Alain Matthes na pergunta vinculada também descobriu isso.