我有以下轨迹,它应该描绘刚体上 2 个点的某条路径。每个点都由一个坐标系来表示。现在我想在点周围使用椭圆而不是长方体。这样点出现在椭圆/主体内部。这个椭圆应该只是表示身体的位置和方向,并且应该位于与立方体当前相同的平面上(下方 xy 平面)。
目前我对长方体不满意,因为例如最右边立方体的顶面显示不正确(中间立方体也是如此)。此外,长方体位于框架顶部,而我希望框架位于内部。
我认为需要为顶部轨迹找到不同的参数化,因为顶部轨迹与底部轨迹之间的距离应为固定距离(小于立方体长度),并且其运动不是随机的,而是由物体的距离和角度决定的。此外,两个点都固定在物体上,并经历相同的运动,但顶部框架应相对于底部框架具有固定的相对旋转。
我认为省略号更简单,但我对这两种方式都很满意。谢谢!
@Schrödinger 的猫: 请提供一些见解/解释,说明如何获得旋转并参数化点 P 和 Q。此外,P\Y 和 Q\Y 是什么?谢谢!
\documentclass[border=2mm,tikz]{standalone}
\usepackage{tikz-3dplot}
\usetikzlibrary{backgrounds}
\begin{document}
\tdplotsetmaincoords{60}{-15}
\begin{tikzpicture}[tdplot_main_coords,scale=1.5,line join=round,>=latex,
line cap=round,declare function={fA(\t)=-sin(\t*144/(1+\t/5));
fAprime(\t)=pow(60/(5+\t),2)*cos(\t*144/(1+\t/5))*pi/180;
fB(\t)=-sin(\t*216/(1+\t*4/15));
fBprime(\t)=6*pow(90/(15+\t*4),2)*cos(\t*216/(1+\t*4/15))*pi/180;},
pics/coordsys/.style = {
code = {\tikzset{coordsys/.cd,#1}
\draw [->,pic actions] (0,0,0) -- +(1,0,0)[red] node[pos=1.1]
{$\pgfkeysvalueof{/tikz/coordsys/x}$};
\begin{scope}[on background layer]
\draw [->,pic actions] (0,0,0) -- +(0,1,0)[green!60!black] node[pos=1.1]
{$\pgfkeysvalueof{/tikz/coordsys/y}$};
\end{scope}
\draw [->,pic actions] (0,0,0) -- +(0,0,1)[blue] node[pos=1.1]
{$\pgfkeysvalueof{/tikz/coordsys/z}$};
}
},coordsys/.cd,x/.initial=x,y/.initial=y,z/.initial=z]
\draw[dashed] plot[variable=\t,domain=0:5] ({\t},3,{fA(\t)});
\draw[dashed] plot[variable=\t,domain=0:3.25] ({\t},0,{fB(\t)});
\foreach \X [count=\Y] in {1,...,3}
{\draw ({\X*5/3},3,{fA(\X*5/3)}) coordinate (P\Y)
-- ({\X*3.25/3},0,{fB(\X*3.25/3)}) coordinate (Q\Y);
\tdplotsetrotatedcoords{0}{atan2(fBprime(\X*3.25/3),1)}{0}
\begin{scope}[tdplot_rotated_coords]
\path (Q\Y) pic{coordsys};
\pgfmathsetmacro{\myang}{atan2(fBprime(\X*3.25/3),1))}
\pgfmathtruncatemacro{\itest}{sign(\myang)}
\pgfmathsetmacro{\cuboiddimx}{2/3}% 2/3 = 1/scale where scale=1.5
\pgfmathsetmacro{\cuboiddimz}{1/3}% 2/3 = 1/scale where scale=1.5
\draw[fill opacity=0.5,fill=gray!70] ($(Q\Y)+(0,0,0)$)
-- ($(Q\Y)+(\cuboiddimx,0,0)$) -- ($(Q\Y)+(\cuboiddimx,0,\cuboiddimz)$)
-- ($(Q\Y)+(0,0,\cuboiddimz)$) -- cycle;
\ifnum\itest=-1
\draw[fill opacity=0.5,fill=gray] ($(Q\Y)+(\cuboiddimx,0,0)$)
-- ($(Q\Y)+(\cuboiddimx,0,\cuboiddimz)$) -- ($(P\Y)+(\cuboiddimx,0,\cuboiddimz)$)
-- ($(P\Y)+(\cuboiddimx,0,0)$) -- cycle;
\else
\draw[fill opacity=0.5,fill=gray] ($(Q\Y)+(0,0,0)$)
-- ($(Q\Y)+(0,0,\cuboiddimz)$) -- ($(P\Y)+(0,0,\cuboiddimz)$)
-- ($(P\Y)+(0,0,0)$) -- cycle;
\fi
\draw[fill opacity=0.5,fill=gray!70] ($(Q\Y)+(0,0,\cuboiddimz)$)
-- ($(Q\Y)+(\cuboiddimx,0,\cuboiddimz)$) -- ($(P\Y)+(\cuboiddimx,0,\cuboiddimz)$)
-- ($(P\Y)+(0,0,\cuboiddimz)$) -- cycle;
\draw[fill opacity=0.5,fill=gray!50] ($(P\Y)+(0,0,0)$)
-- ($(P\Y)+(\cuboiddimx,0,0)$) -- ($(P\Y)+(\cuboiddimx,0,\cuboiddimz)$)
-- ($(P\Y)+(0,0,\cuboiddimz)$) -- cycle;
\end{scope}
\tdplotsetrotatedcoords{0}{atan2(fAprime(\X*1.25),1)}{0}
\begin{scope}[tdplot_rotated_coords]
\path (P\Y) pic{coordsys={x=x',y=y',z=z'}};
\end{scope}
}
\end{tikzpicture}
\end{document}
答案1
问题是 Ti钾Z 没有 3D 引擎,因此您需要自己进行 3D 排序。什么是 3D 排序?如果您有两个元素 A 和 B,并且您在 B 之后绘制 A,则 A 将显示在 B 之前。也就是说,您需要稍后绘制更近的物体。哪个更近通常取决于视角,您可以使用 设置视角。如果我没记错的话,与原始代码相比,您已经交换了代码中和\tdplotsetmaincoords{60}{-15}
的角色。但是,您并没有改变绘制事物的顺序,因此看起来是错误的。特别是,平面的绘制顺序不正确。我相应地调整了绘制顺序,并在后面添加了一些平面。我还调整了坐标系的绘制顺序。P
Q
xz
\documentclass[border=2mm,tikz]{standalone}
\usepackage{tikz-3dplot}
\usetikzlibrary{backgrounds}
\begin{document}
\tdplotsetmaincoords{60}{-15}
\begin{tikzpicture}[tdplot_main_coords,scale=1.5,line join=round,>=latex,
line cap=round,declare function={fA(\t)=-sin(\t*144/(1+\t/5));
fAprime(\t)=pow(60/(5+\t),2)*cos(\t*144/(1+\t/5))*pi/180;
fB(\t)=-sin(\t*216/(1+\t*4/15));
fBprime(\t)=6*pow(90/(15+\t*4),2)*cos(\t*216/(1+\t*4/15))*pi/180;},
pics/coordsys/.style = {
code = {\tikzset{coordsys/.cd,#1}
\draw [->,pic actions] (0,0,0) -- +(1,0,0)[red] node[pos=1.1]
{$\pgfkeysvalueof{/tikz/coordsys/x}$};
\begin{scope}[on background layer]
\draw [->,pic actions] (0,0,0) -- +(0,1,0)[green!60!black] node[pos=1.1]
{$\pgfkeysvalueof{/tikz/coordsys/y}$};
\end{scope}
\draw [->,pic actions] (0,0,0) -- +(0,0,1)[blue] node[pos=1.1]
{$\pgfkeysvalueof{/tikz/coordsys/z}$};
}
},coordsys/.cd,x/.initial=x,y/.initial=y,z/.initial=z]
\draw[dashed] plot[variable=\t,domain=0:5] ({\t},3,{fA(\t)});
\draw[dashed] plot[variable=\t,domain=0:3.25] ({\t},0,{fB(\t)});
\foreach \X [count=\Y] in {1,...,3}
{\draw ({\X*5/3},3,{fA(\X*5/3)}) coordinate (P\Y)
-- ({\X*3.25/3},0,{fB(\X*3.25/3)}) coordinate (Q\Y);
\tdplotsetrotatedcoords{0}{atan2(fAprime(\X*5/3),1)}{0}
\begin{scope}[tdplot_rotated_coords]
\path (P\Y) pic{coordsys={x=x',y=y',z=z'}};
\pgfmathsetmacro{\cuboiddimx}{2/3}% 2/3 = 1/scale where scale=1.5
\pgfmathsetmacro{\cuboiddimz}{1/3}% 2/3 = 1/scale where scale=1.5
\pgfmathsetmacro{\myopa}{0.6}
% xz face at y=3 (back of the cuboid)
\draw[fill opacity=\myopa,fill=gray!50] ($(P\Y)+(0,0,0)$)
-- ($(P\Y)+(\cuboiddimx,0,0)$) -- ($(P\Y)+(\cuboiddimx,0,\cuboiddimz)$)
-- ($(P\Y)+(0,0,\cuboiddimz)$) -- cycle;
% xy face at bottom
\draw[fill opacity=\myopa,fill=gray!70] ($(Q\Y)+(0,0,0)$)
-- ($(Q\Y)+(\cuboiddimx,0,0)$) -- ($(P\Y)+(\cuboiddimx,0,0)$)
-- ($(P\Y)+(0,0,0)$) -- cycle;
% in order to find out which yz face is to be drawn first,
% we need to look at an appropriate rotation angle
\pgfmathsetmacro{\myang}{atan2(fBprime(\X*3.25/3),1))}
% the sign of the angle determines the ordering
\pgfmathtruncatemacro{\itest}{sign(\myang)}
\ifnum\itest=-1
% the "left" yz face is "hidden"
\draw[fill opacity=\myopa,fill=gray] ($(Q\Y)+(0,0,0)$)
-- ($(Q\Y)+(0,0,\cuboiddimz)$) -- ($(P\Y)+(0,0,\cuboiddimz)$)
-- ($(P\Y)+(0,0,0)$) -- cycle;
% the "right" yz face is "visible"
\draw[fill opacity=\myopa,fill=gray] ($(Q\Y)+(\cuboiddimx,0,0)$)
-- ($(Q\Y)+(\cuboiddimx,0,\cuboiddimz)$) -- ($(P\Y)+(\cuboiddimx,0,\cuboiddimz)$)
-- ($(P\Y)+(\cuboiddimx,0,0)$) -- cycle;
\else
% the "right" yz face is "hidden"
\draw[fill opacity=\myopa,fill=gray] ($(Q\Y)+(\cuboiddimx,0,0)$)
-- ($(Q\Y)+(\cuboiddimx,0,\cuboiddimz)$) -- ($(P\Y)+(\cuboiddimx,0,\cuboiddimz)$)
-- ($(P\Y)+(\cuboiddimx,0,0)$) -- cycle;
% the "left" yz face is "visible"
\draw[fill opacity=\myopa,fill=gray] ($(Q\Y)+(0,0,0)$)
-- ($(Q\Y)+(0,0,\cuboiddimz)$) -- ($(P\Y)+(0,0,\cuboiddimz)$)
-- ($(P\Y)+(0,0,0)$) -- cycle;
\fi
% top xy face
\draw[fill opacity=\myopa,fill=gray!70] ($(Q\Y)+(0,0,\cuboiddimz)$)
-- ($(Q\Y)+(\cuboiddimx,0,\cuboiddimz)$) -- ($(P\Y)+(\cuboiddimx,0,\cuboiddimz)$)
-- ($(P\Y)+(0,0,\cuboiddimz)$) -- cycle;
% front xz face
\draw[fill opacity=\myopa,fill=gray!70] ($(Q\Y)+(0,0,0)$)
-- ($(Q\Y)+(\cuboiddimx,0,0)$) -- ($(Q\Y)+(\cuboiddimx,0,\cuboiddimz)$)
-- ($(Q\Y)+(0,0,\cuboiddimz)$) -- cycle;
\end{scope}
\tdplotsetrotatedcoords{0}{atan2(fBprime(\X*3.25/3),1)}{0}
\begin{scope}[tdplot_rotated_coords]
\path (Q\Y) pic{coordsys};
\end{scope}
}
\end{tikzpicture}
\end{document}
为了进行交叉检查,我们设置\pgfmathsetmacro{\myopa}{1}
。
如果你不想自己进行 3D 排序,你可以考虑半自动解决方案,例如这个或完全切换到asymptote
。