使用tikz在三维空间中绘制圆柱体

使用tikz在三维空间中绘制圆柱体

我想知道是否可以在 tikz 中在三维空间中绘制一个圆柱体,这样我就可以转动/改变视点?(参见\begin{tikzpicture}[>=latex, x={(0:1cm)}, y={(90:1cm)}, z={(30:0.4cm)}]

我读了几篇帖子,都说这很难。

我已经有一个平面图了,

%%%%%%%%%%%%%%%%%% INTRODUCTION %%%%%%%%%%%%%%%%%%
\documentclass[border=10pt]{standalone}

%%%%%%%%%%%%%%%%%% PACKAGE %%%%%%%%%%%%%%%%%%
\usepackage{tikz, tkz-euclide}%  permet de dessiner des figures, des graphiques
\usepackage{adjustbox}% permet de déterminer une taille de fenêtre

%%  FONT
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}

\usepackage{tgadventor}% paquet de police de caractère TGadventor
\usepackage{sansmath}%  Copie-colle la police active dans 
%                       \sfdefault (/!\ N'EST PAS UNE POLICE DE CARACTÈRES)

\usepackage{xcolor}

%%%%%%%%%%%%%%%%%% INPUT %%%%%%%%%%%%%%%%%%
%\input{types/f3d_figlab}

%%%%%%%%%%%%%%%%%%%% Cylinder %%%%%%%%%%%%%%%%%%%%%
    \tikzset{pics/cylinder/.style={code={%
        \tikzset{cylinder/.cd,#1}%
        \def\pv##1{\pgfkeysvalueof{/tikz/cylinder/##1}}
        % depth of the cylinder
        \newcommand{\depth}{\pv{ray}*\pv{scale}*0.25}
        \fill[baseinf] (0,0) circle (\pv{ray}*\pv{scale} cm and \depth cm);
        \fill[corps] (\pv{ray}*\pv{scale},0) -- (\pv{ray}*\pv{scale},\pv{height}*\pv{scale}) arc (360:180:\pv{ray}*\pv{scale} cm and \depth cm) -- (-\pv{ray}*\pv{scale},0) arc (180:360:\pv{ray}*\pv{scale} cm and \depth cm);
        \fill[basesup] (0,\pv{height}*\pv{scale}) circle (\pv{ray}*\pv{scale} cm and \depth cm);
        \draw[thick] (-\pv{ray}*\pv{scale},\pv{height}*\pv{scale}) -- (-\pv{ray}*\pv{scale},0) arc (180:360:\pv{ray}*\pv{scale} cm and \depth cm) -- (\pv{ray}*\pv{scale},\pv{height}*\pv{scale}) ++ (-\pv{ray}*\pv{scale},0) circle (\pv{ray}*\pv{scale} cm and \depth cm)
        ;
        \draw[thick, densely dashed] (-\pv{ray}*\pv{scale},0) arc (180:0:\pv{ray}*\pv{scale} cm and \depth cm);
        % Mesure de la hauteur
        \draw[thick,<->] 
            (\pv{ray}*\pv{scale}+0.4,0) -- (\pv{ray}*\pv{scale}+0.4,\pv{height}*\pv{scale}) node[midway, right] {\pv{height}~\pv{unit}};
        % Mesure du rayon
        \draw[thick,<->]
            (0,-\depth-0.4) -- (\pv{ray}*\pv{scale},-\depth-0.4) node[midway, below] {\pv{ray}~\pv{unit}};
        \draw (0,0) node[circle, fill=black, opacity=.8, scale=.3] {};

      }},
      cylinder/.cd,
      ray/.initial=5,
      height/.initial=5,
      fill/.initial=gray,
      unit/.initial=cm,
      scale/.initial=1,
    }

%%%%%%%%%%%%%%%%%% DOCUMENT %%%%%%%%%%%%%%%%%%
\begin{document}
\begin{tikzpicture}[font={\sansmath\sffamily},line width=0.4mm , line cap=round, line join=round, >=latex, x={(0:1cm)}, y={(90:1cm)}, z={(75:0.6cm)}]

% calibration cross
%\pic at (5,0,0) {calcross};

%   Figures
\pic{cylinder={ray=63, height=50, scale=.07, corps/.style={draw,fill=orange!20}, basesup/.style={draw,fill=orange!20},}};

\end{tikzpicture}
\end{document}

答案1

好消息是,您可以直接执行您的要求。从您的代码片段中,我推断您想要一个指向 y 方向的圆柱体,并且我假设该方向在屏幕的 y 方向上具有正投影(但如果需要,很容易放弃此假设)。然后我们需要做的就是计算临界可见角,简单的计算得出临界可见角由以下公式给出

\pgfmathsetmacro{\myan}{atan2(\pgf@zx,\pgf@xx)}

其中\pgf@zx\pgf@xx是安装的 z 和 x 单位向量在屏幕 x 方向上的投影。到目前为止一切顺利……问题是你提供的坐标系不是正交的,也不是 Ti 预定义的坐标系Z. 这是圆柱体在这些坐标下的样子。

\documentclass[tikz,border=3mm]{standalone}
\makeatletter
\tikzset{pics/cylinder/.style={code={%
    \tikzset{cylinder/.cd,#1}%
    \def\pv##1{\pgfkeysvalueof{/tikz/cylinder/##1}}
    \pgfmathsetmacro{\myan}{atan2(\pgf@zx,\pgf@xx)}
    \begin{scope}[local bounding box=cyl]
      \path[cylinder/corps]
       plot[smooth,variable=\t,samples=19,domain=\myan:{-1*sign(\myan)*180+\myan}]
      ({\pv{ray}*\pv{scale}*cos(\t)},
      {\pv{height}*\pv{scale}},{\pv{ray}*\pv{scale}*sin(\t)})
      -- 
      plot[smooth,variable=\t,samples=19,domain={-1*sign(\myan)*180+\myan}:\myan]
      ({\pv{ray}*\pv{scale}*cos(\t)},0,
      {\pv{ray}*\pv{scale}*sin(\t)})
      -- cycle;
      \path[cylinder/basesup] plot[smooth cycle,variable=\t,samples=37,domain=0:360]
      ({\pv{ray}*\pv{scale}*cos(\t)},
      {\pv{height}*\pv{scale}},
      {\pv{ray}*\pv{scale}*sin(\t)});
      \draw[thick, densely dashed] 
      plot[smooth,variable=\t,samples=19,domain={sign(\myan)*180+\myan}:\myan]
      ({\pv{ray}*\pv{scale}*cos(\t)},0,
          {\pv{ray}*\pv{scale}*sin(\t)});
    \end{scope}   
    \draw[|<->|] ([yshift=-4mm]cyl.south west) -- 
    ([yshift=-4mm]cyl.south east) node[midway, below] {\pv{ray}~\pv{unit}};
    \draw[|<->|,xshift=4mm] 
    ({\pv{ray}*\pv{scale}*cos(\myan)},
     {\pv{height}*\pv{scale}},{\pv{ray}*\pv{scale}*sin(\myan)})
    --
    ({\pv{ray}*\pv{scale}*cos(\myan)},
      0,{\pv{ray}*\pv{scale}*sin(\myan)})
     node[midway, right] {\pv{height}~\pv{unit}}; 
  }},
  cylinder/.cd,
  ray/.initial=5,
  height/.initial=5,
  fill/.initial=gray,
  unit/.initial=cm,
  scale/.initial=1,
  corps/.style={draw,fill=gray},
  basesup/.style={draw,fill=red}
}
\makeatother
\begin{document}
\begin{tikzpicture}
 \pic{cylinder};
\end{tikzpicture}

\begin{tikzpicture}[>=latex, x={(0:1cm)}, y={(90:1cm)}, z={(30:0.4cm)}]
 \pic{cylinder};
\end{tikzpicture}
\end{document}

在此处输入图片描述

它们看起来是歪的。为什么?很简单,因为这些不是正交投影。如果您想要正交投影,请使用库3d view附带的密钥perspectivetikz-3dplot。前者的巨大优势在于还允许使用透视投影,在我看来,绘制透视圆柱体是一个非常好的(但又是独立的!)问题(好消息是上面的内容可以修改为这样做)。因为tikz-3dplot已经有了各种例子,我毫不掩饰地强调我自己的例子:这里这里因为你好像喜欢pics。

因此,底线是,为您提供您所要求的东西并不难,但很可能您并不真正想要那样的东西。

相关内容