我需要一些帮助来完成 3D 运动图(见附图)
我几乎知道如何绘制所有东西,但我想找到一个干净的解决方案来绘制 3 个球每侧的接触面。我为顶部球绘制了两个平面图(易于计算!),我可以计算其他的,但是否有可以自动计算的 Tikz 或 pgf 解决方案。
\documentclass[10pt,a4paper]{standalone}
\usepackage{tikz}
\usetikzlibrary{3d,calc,positioning}
\begin{document}
\begin{tikzpicture}
[z={(-0.866cm,-0.5cm)}, x={(0.866cm,-0.5cm)}, y={(0cm,1cm)}, scale=2]
\draw[->,red] (0,0,0) -- (3,0,0) node[above]{x};
\draw[->,blue] (0,0,0) -- (0,3,0) node[left]{y};
\draw[->,black] (0,0,0) -- (0,0,3) node[above]{z};
\foreach \aa/\nn in {90/1,-30/2,-150/3}{
\draw (0,0,0) coordinate(O) circle (1.5);
\node[circle,draw,fill=blue,minimum size=1.4cm] (Ca\nn) at ({1.5*cos(\aa)},{1.5*sin(\aa)},0){};
\draw[dashed] (Ca\nn) -- (O);
\draw[thick,red] (Ca\nn) --++(0,0,1.8) coordinate(B\nn)-- ($(O)+(0,0,1.8)$)-- ++(0,0,1);
\draw[thick,green] (Ca\nn) --++(0,0,-1.8) coordinate(B\nn)-- ($(O)+(0,0,-1.8)$)-- ++(0,0,-1);
}
\begin{scope}[shift={(Ca1)}]
\path[thick,red] (0,0.5,-0.5) -- ++({0.5*cos(15)},0,{-0.5*sin(15)})coordinate(a1)--++({-cos(15)},0,{+sin(15)})coordinate(a2);
\path[thick,red] (0,-0.5,-0.5) -- ++({0.5*cos(15)},0,{-0.5*sin(15)})coordinate(a3)--++({-cos(15)},0,{+sin(15)})coordinate(a4);
\draw[fill=green,opacity=0.5] (a1) -- (a3) -- (a4) -- (a2) -- cycle;
\node[circle,draw,fill=blue,minimum size=1.4cm] at (Ca1){};
\path[thick,red] (0,0.5,0.5) -- ++({0.5*cos(15)},0,{-0.5*sin(15)})coordinate(a1)--++({-cos(15)},0,{+sin(15)})coordinate(a2);
\path[thick,red] (0,-0.5,0.5) -- ++({0.5*cos(15)},0,{-0.5*sin(15)})coordinate(a3)--++({-cos(15)},0,{+sin(15)})coordinate(a4);
\draw[fill=red,opacity=0.5] (a1) -- (a3) -- (a4) -- (a2) -- cycle;
\draw[->] (Ca1) --++ ({1.5*sin(15)},0,{1.5*cos(15)})node[right]{na1};
\end{scope}
%
% \begin{scope}[canvas is xy plane at z=0]
%
%
%
% \draw[blue,shift={(1.5,0)}] (0,0) -- (1,0)--(1,1)--(0,1)--cycle;
% \draw[blue,shift={(3,0)}] (0,0) -- (1,0)--(1,1)--(0,1)--cycle;
% \end{scope}
\end{tikzpicture}
\end{document}
答案1
我不想花时间理解你的计算,所以我重新开始 - 希望你可以使用它:
\documentclass[tikz, border=1cm]{standalone}
\usetikzlibrary{3d}
\tikzset{viewport/.style 2 args={
z={({cos(-#1)*1cm},{sin(-#1)*sin(#2)*1cm})},
x={({-sin(-#1)*1cm},{cos(-#1)*sin(#2)*1cm})},
y={(0,{cos(#2)*1cm})}
}}
\begin{document}
\begin{tikzpicture}[viewport={135}{40}] %[z={(-0.866cm,-0.5cm)}, x={(0.866cm,-0.5cm)}, y={(0cm,1cm)}]
\draw[->, red] (0,0,0) -- (4,0,0) node[above]{x};
\draw[->, blue] (0,0,0) -- (0,4,0) node[left]{y};
\draw[->, black] (0,0,0) -- (0,0,4) node[above]{z};
\foreach \angle in {90,210,330}
\draw[green, thick] ([shift={(0,0,-0.5)}] \angle:2) -- ([shift={(0,0,-2.5)}] \angle:2) -- (0,0,-2.5) -- (0,0,-3.5);
\begin{scope}[canvas is xy plane at z=-0.5]
\foreach \angle in {90,210,330}
\draw[fill=green, opacity=0.5, shift={(\angle:2)}] (-0.6,-0.6) rectangle (0.6,0.6);
\end{scope}
\begin{scope}[canvas is xy plane at z=0]
\draw (0,0) circle[radius=2];
\foreach \angle in {90,210,330}{
\draw[dashed] (0,0) -- (\angle:2);
\node[circle, draw, fill=blue, minimum size=1cm] at (\angle:2) {};
}
\end{scope}
\begin{scope}[canvas is xy plane at z=0.5]
\foreach \angle in {90,210,330}
\draw[fill=red, opacity=0.5, shift={(\angle:2)}] (-0.6,-0.6) rectangle (0.6,0.6);
\end{scope}
\foreach \angle in {90,210,330}
\draw[red, thick] ([shift={(0,0,0.5)}] \angle:2) -- ([shift={(0,0,2.5)}] \angle:2) -- (0,0,2.5) -- (0,0,3.5);
\end{tikzpicture}
\end{document}
viewport={135}{40}
viewport={155}{20}
viewport
改编自此处:https://tex.stackexchange.com/a/199715/8650
在另一个上下文中出于其他原因使用它。您不需要它,并且如果您愿意,只需明确设置和x
单位向量即可。y
z
编辑:
这里我用来tikz-3dplot
将平面旋转 15 度。我必须使用标准坐标系,z 轴向上,但标签可以更改:
\documentclass[tikz, border=1cm]{standalone}
\usepackage{tikz-3dplot}
\begin{document}
\tdplotsetmaincoords{60}{130}
\begin{tikzpicture}[tdplot_main_coords]
\newcommand{\rw}{0.6}
\draw[->, red] (0,0,0) -- (4,0,0) node[above]{x};
\draw[->, blue] (0,0,0) -- (0,4,0) node[above]{y};
\draw[->, black] (0,0,0) -- (0,0,4) node[above]{z};
\begin{scope}[canvas is yz plane at x=0]
\draw (0,0) circle[radius=2];
\end{scope}
\foreach \point in {(0,{2*cos(90)},{2*sin(90)}) , (0,{2*cos(210)},{2*sin(210)}) , (0,{2*cos(330)},{2*sin(330)}) }{
\draw[dashed] (0,0,0) -- \point;
\tdplotsetrotatedcoordsorigin{\point}
\tdplotsetrotatedcoords{0}{0}{15}
\draw[fill=green, opacity=0.5, tdplot_rotated_coords] (-0.5,-\rw,-\rw) -- (-0.5,-\rw,\rw) -- (-0.5,\rw,\rw) -- (-0.5,\rw,-\rw) -- cycle;
\node[circle, draw, fill=blue, minimum size=1cm] at \point {};
\draw[->, shift={\point}] (0.5,0,0) -- (2,0,0);
\draw[->, tdplot_rotated_coords] (0.5,0,0) -- (2,0,0);
\draw[fill=red, opacity=0.5, tdplot_rotated_coords] (0.5,-\rw,-\rw) -- (0.5,-\rw,\rw) -- (0.5,\rw,\rw) -- (0.5,\rw,-\rw) -- cycle;
}
\end{tikzpicture}
\end{document}
从顶部看\tdplotsetmaincoords{0}{0}
答案2
我回答我的问题!
我参考了之前的一个问题(如何用 3d 图绘制俯仰、偏航和滚转) 来定义不同的角度。
% !TeX encoding = utf8
\documentclass[10pt,a4paper]{article}
\usepackage{tikz}
\usetikzlibrary{3d,calc,positioning}
\usepackage{tikz-3dplot}
\begin{document}
\makeatletter
%along y axis
\define@key{y sphericalkeys}{radius}{\def\myradius{#1}}
\define@key{y sphericalkeys}{theta}{\def\mytheta{#1}}
\define@key{y sphericalkeys}{phi}{\def\myphi{#1}}
\tikzdeclarecoordinatesystem{y spherical}{% %%%rotation around x
\setkeys{y sphericalkeys}{#1}%
\pgfpointxyz{\myradius*sin(\mytheta)*cos(\myphi)}{\myradius*cos(\mytheta)}{\myradius*sin(\mytheta)*sin(\myphi)}}
\makeatother
% definitions to make your life easier
\tikzset{rotate axes about y axis/.code={
\path (y spherical cs:radius=1,theta=90,phi=0+#1) coordinate(xpp)
(y spherical cs:radius=1,theta=00,phi=90+#1) coordinate(ypp)
(y spherical cs:radius=1,theta=90,phi=90+#1) coordinate(zpp);
},rotate axes about x axis/.code={
\path (x spherical cs:radius=1,theta=00,phi=90+#1) coordinate(xpp)
(x spherical cs:radius=1,theta=90,phi=00+#1) coordinate(ypp)
(x spherical cs:radius=1,theta=90,phi=90+#1) coordinate(zpp);
},
pitch/.style={rotate axes about y axis=#1,x={(xpp)},y={(ypp)},z={(zpp)}},
roll/.style={rotate axes about x axis=#1,x={(xpp)},y={(ypp)},z={(zpp)}}
}
\tdplotsetmaincoords{60}{130}
%[tangage - pitch ]
{
\begin{tikzpicture}[scale=1]
\begin{scope}[tdplot_main_coords]
%axes principaux
\begin{scope}
\draw[thick,->] (0,0,0)node[above right]{$O$} -- (8,0,0) node[left]{$z$};
\draw[thick,->] (0,0,0) -- (0,5,0) node[below]{$x$};
\draw[thick,->] (0,0,0) --(0,0,5) node[right]{$y$};
\end{scope}
\def\rr{0.5}
\newcommand{\planar}[1][]{
\draw[fill,#1] (aa) ++(0,{0.5*cos(15)},{0.5*sin(15)}) --++ (0,{\rr*cos(-75)},{\rr*sin(-75)}) coordinate(bb)--++(\rr,0,0) --++(0,{2*\rr*cos(105)},{2*\rr*sin(105)}) --++({-2*\rr},0,0) --++ (0,{2*\rr*cos(-75)},{2*\rr*sin(-75)}) -- (bb);
}
\newcommand{\planav}[1][]{
\draw[fill,#1] (aa) ++(0,{0.5*cos(-165)},{0.5*sin(-165)}) --++ (0,{\rr*cos(-75)},{\rr*sin(-75)}) coordinate(bb)--++(\rr,0,0) --++(0,{2*\rr*cos(105)},{2*\rr*sin(105)}) --++({-2*\rr},0,0) --++ (0,{2*\rr*cos(-75)},{2*\rr*sin(-75)}) -- (bb);
}
\newcommand{\plansetbille}[1][]{
\coordinate(aa) at (3,0,0);
\planar[green!50]
\node[draw,fill=red,minimum size=1cm,circle](bille) at (aa){};
\planav[blue!50,opacity=0.5]
\draw[-latex] (aa) -- ++(0,-6,0)coordinate[pos=0.35](xx\ind) node[left]{$z$};
\draw[-latex,blue] (bille) -- ++(0,{3*cos(-165)},{3*sin(-165)}) coordinate[pos=0.6](yy\ind)node[right]{${n_{a\ind}}$};
\draw[thick,blue] (bille) --++ (0,-5,0) --++(-3,0,0) --++(0,-2,0);
\draw[thick,green] (bille) --++ (0,3,0) --++(-3,0,0) --++(0,2,0);
\draw[thick,color=blue,->] (0,0,0) --(4.5,0,0)coordinate[pos=0.6](x3) node[right]{${u_{a\ind}}$};
}
\tdplotsetrotatedcoords{90}{00}{00} % kept here the yaw rotation
\begin{scope}[tdplot_rotated_coords]
\foreach \rot/\ind in {90/1,-30/2,-150/3}
{
\begin{scope}[pitch=\rot]
\plansetbille[\ind]
\end{scope}
}
\end{scope}
\end{scope}
\draw[-latex](xx1) to[bend right=8] node[below,pos=0.2]{$\theta$} (yy1) ;
\end{tikzpicture}
}
\end{document}