我正在 XYZ 坐标系中绘制笛卡尔坐标系,并想通过在每个平面上绘制投影来说明 3d 空间中的点。一个简单的版本如下:使用此代码获得:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
%: isometric South West (-150): Y , East : X , North : Z
\tikzset{isometricYXZ/.style={x={(1cm,0cm)}, y={(-1.299cm,-0.75cm)}, z={(0cm,1cm)}}}
\begin{document}
\begin{tikzpicture}[inner sep=0.2cm]
\def \radi{3}
\def \x{2}
\def \y{2}
\def \z{2}
\begin{scope}[isometricYXZ]
% the grid
\begin{scope}[color=gray!50, thin]
\foreach \xi in {0,...,\radi}{ \draw (\xi,\radi,0) -- (\xi,0,0) -- (\xi,0,\radi); }%
\foreach \yi in {1,...,\radi}{ \draw (0,\yi,\radi) -- (0,\yi,0) -- (\radi,\yi,0); }%
\foreach \zi in {0,...,\radi}{ \draw (0,\radi,\zi) -- (0,0,\zi) -- (\radi,0,\zi); }%
\end{scope}
\draw[-latex, ultra thick, color=blue] (0,0,0) -- (4,0,0) node[anchor=west] {X};%
\draw[-latex, ultra thick, color=red] (0,0,0) -- (0,4,0) node[anchor=north] {Y};%
\draw[-latex, ultra thick, color=green] (0,0,0) -- (0,0,4) node[anchor=east] {Z};%
\fill[color=magenta, opacity=0.2] (0,0,0) -- (\x,0,0) -- (\x,\y,0) -- (0,\y,0) -- cycle; %
\fill[color=yellow, opacity=0.2] (0,0,0) -- (0,0,\z) -- (0,\y,\z) -- (0,\y,0) -- cycle; %
\fill[color=cyan, opacity=0.2] (0,0,0) -- (\x,0,0) -- (\x,0,\z) -- (0,0,\z) -- cycle;
\draw[color=gray, thick]%
(0,\y,\z) -- (\x,\y,\z) -- (\x,\y,0) (\x,\y,\z) -- (\x,0,\z);%
\end{scope}
\shade[ball color=yellow] ($\y*(-1.299cm,-0.75cm)+(\x,\z)$) circle (0.1);%
\end{tikzpicture}
\end{document}
为了使绘图更美观,我想为这些投影添加阴影,我对 XZ 平面做了以下操作:
这是阴影部分的代码:
\begin{scope}[isometricYXZ]
\def \h{{0.5*sqrt(\x*\x + \z*\z)}}
\clip (0,0,0) -- (\x,0,0) -- (\x,0,\z) -- (0,0,\z) -- cycle; %
\begin{scope}[transform canvas={shift={(\x/2,0,\z/2)}, rotate=45}]
\fill[top color=green!30, bottom color=blue!30]
(-\x,0,-\h) -- (\x,0,-\h) -- (\x,0,\h) -- (-\x,0,\h) -- cycle;
\end{scope}
\end{scope}
现在,当我尝试对其他平面执行相同操作时,它不起作用,因为看起来 rotate 总是像在二维情况下一样旋转(在我的情况下围绕 Y 轴,在 XZ 平面上)。这是代码:
\begin{scope}
\def \h{{0.5*sqrt(\x*\x + \y*\y)}}
\clip (0,0,0) -- (\x,0,0) -- (\x,\y,0) -- (0,\y,0) -- cycle; %
\begin{scope}[transform canvas={shift={(\x/2,\y/2,0)}, rotate=-45}]
\fill[top color=blue!30, bottom color=red!30]
(-\x,-\h,0) -- (\x,-\h,0) -- (\x,\h,0) -- (-\x,\h,0) -- cycle;
\end{scope}
\end{scope}
结果如下:
因此,我的问题是这是否可行,如果可行,那么如何告诉 Tikz 绕任意轴旋转?或者在我的情况下,在 XY 和 YZ 平面上?
不需要旋转的淡入淡出解决方案也是可以的。
最后,我想我可以将所有内容转换为二维并得到我想要的,但也许有一个更清晰的解决方案。
答案1
在我看来,你使用的工具太强大了,但任务却相对简单。画布变换根本不关心任何其他设置,例如边界框或任何其他高级约束。它们只是发生了。相反,你可以修改默认的垂直阴影,使它们遵循选项shading angle
。我随机将下面的阴影旋转了 45 度、120 度和 -45 度,希望这就是问题的原因 :)
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\makeatletter
\tikzoption{top color}{%
\pgfutil@colorlet{tikz@axis@top}{#1}%
\pgfutil@colorlet{tikz@axis@middle}{tikz@axis@top!50!tikz@axis@bottom}%
\def\tikz@shading{axis}\tikz@addmode{\tikz@mode@shadetrue}}
\tikzoption{bottom color}{%
\pgfutil@colorlet{tikz@axis@bottom}{#1}%
\pgfutil@colorlet{tikz@axis@middle}{tikz@axis@top!50!tikz@axis@bottom}%
\def\tikz@shading{axis}\tikz@addmode{\tikz@mode@shadetrue}}
\tikzoption{middle color}{%
\pgfutil@colorlet{tikz@axis@middle}{#1}%
\def\tikz@shading{axis}\tikz@addmode{\tikz@mode@shadetrue}}
\makeatother
%: isometric South West (-150): Y , East : X , North : Z
\tikzset{isometricYXZ/.style={x={(1cm,0cm)}, y={(-1.299cm,-0.75cm)}, z={(0cm,1cm)}}}
\begin{document}
\begin{tikzpicture}[inner sep=0.2cm]
\def \radi{3}
\def \x{2}
\def \y{2}
\def \z{2}
\begin{scope}[isometricYXZ]
% the grid
\begin{scope}[color=gray!50, thin]
\foreach \xi in {0,...,\radi}{ \draw (\xi,\radi,0) -- (\xi,0,0) -- (\xi,0,\radi); }%
\foreach \yi in {1,...,\radi}{ \draw (0,\yi,\radi) -- (0,\yi,0) -- (\radi,\yi,0); }%
\foreach \zi in {0,...,\radi}{ \draw (0,\radi,\zi) -- (0,0,\zi) -- (\radi,0,\zi); }%
\end{scope}
\draw[-latex, ultra thick, color=blue] (0,0,0) -- (4,0,0) node[anchor=west] {X};%
\draw[-latex, ultra thick, color=red] (0,0,0) -- (0,4,0) node[anchor=north] {Y};%
\draw[-latex, ultra thick, color=green] (0,0,0) -- (0,0,4) node[anchor=east] {Z};%
\fill[shading angle=45, top color=green!30, bottom color=blue!30] (0,0,0) -- (\x,0,0) -- (\x,\y,0) -- (0,\y,0) -- cycle; %
\fill[shading angle=-45, top color=green!30, bottom color=blue!30] (0,0,0) -- (0,0,\z) -- (0,\y,\z) -- (0,\y,0) -- cycle; %
\fill[shading angle=120, top color=green!30, bottom color=blue!30] (0,0,0) -- (\x,0,0) -- (\x,0,\z) -- (0,0,\z) -- cycle;
\draw[color=gray, thick]%
(0,\y,\z) -- (\x,\y,\z) -- (\x,\y,0) (\x,\y,\z) -- (\x,0,\z);%
\end{scope}
\shade[ball color=yellow] ($\y*(-1.299cm,-0.75cm)+(\x,\z)$) circle (0.1);%
\end{tikzpicture}
\end{document}
我猜禁用(设置为零)的原因shading angle
最初是为了在着色声明时使其他转换无效。如果您有其他使用这些选项的 TikZ 图片,则可以将这些更改设为本地更改。