绘制三维锥体

绘制三维锥体

我正在尝试绘制 3D 中的圆锥体,但有点卡住了。

我绘制了密集的虚线,然后尝试绘制圆锥的边界,分为 3 个部分:

  • 绿色部分是静态的
  • 蓝色部分根据锥体的高度而变化
  • 红色部分只是一个点“h”和蓝色部分之间的连接。

在此处输入图片描述

我无法绘制圆锥体的红色左侧部分,并且当“高度=0”时会出现一条黑线

在此处输入图片描述

%%%%%%%%%%%%%%%%%% 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{preamble}
%\input{parameters}
%\input{types/f3d_fig}
%%%%%%%%%%%%%%%%%% SETUP %%%%%%%%%%%%%%%%%%
\tikzset{volum3D/.style={font={\sansmath\sffamily\large}, line width=0.4mm, line cap=round, line join=round, >=latex,}} 

%%%%%%%%%%%%%%%%%%%%%%%% CONE %%%%%%%%%%%%%%%%%%%%%%%%
\makeatletter
\tikzset{pics/cone/.style={code={%
    \tikzset{cone/.cd,#1}%
    \def\pv##1{\pgfkeysvalueof{/tikz/cone/##1}}%
    \pgfmathsetmacro{\myan}{atan2(\pgf@zx,\pgf@xx)}%
    \begin{scope}[local bounding box=sph]%
        %%%     Compute the angle
        \pgfmathsetmacro\angle{acos(1/\pv{height})}
        \path[cone/corps]
        %%%     Patrie supérieur
        (0,
        \pv{height}*\pv{scale},
        0) coordinate (h) 
        node[above] {\angle}
        node[below] {\myan}
        %%%     Patrie droite
        (h) -- 
        plot[smooth,variable=\t,samples=19,domain={(sign(\myan)*90+\myan)-\angle}:\myan]
        ({\pv{ray}*\pv{scale}*cos(\t)},
        0,
        {\pv{ray}*\pv{scale}*sin(\t)})
        %%%     Patrie Inférieur
        -- plot[smooth,variable=\t,samples=19,domain=\myan:{-1*sign(\myan)*180+\myan}]
        ({\pv{ray}*\pv{scale}*cos(\t)},
        0,
        {\pv{ray}*\pv{scale}*sin(\t)})
        %%%     Patrie gauche
        %-- plot[smooth,variable=\t,samples=19,domain={180*\myan-\myan}:\myan]
        %({\pv{ray}*\pv{scale}*cos(\t)},
        %0,
        %{\pv{ray}*\pv{scale}*sin(\t)})
        -- cycle
        ;
        %%%     CERCLE EN POINTILLÉ
        \draw[thick, densely dashed]
        %%%       Arc Avant
        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)})
        %%%       Arc Arrière
        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}
    %%  Dot (0,0)
    \draw 
    (0,0,0) node[circle, fill=black, inner sep=1pt] {} coordinate (o)
    ;
  }},
  cone/.cd,
  ray/.initial=5,
  height/.initial=3,
  scale/.initial=1,
  corps/.style={draw,fill=black!15},
}
\makeatother
%%%%%%%%%%%%%%%%%% DOCUMENT %%%%%%%%%%%%%%%%%%
\begin{document}
\begin{tikzpicture}[volum3D, x={(0:1cm)}, y={(90:1cm)}, z={(89:0.4cm), scale=0.5}]

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

%   Figures
\foreach \h in {0.5,1,...,8}{
    \begin{scope}[shift={(6.2*\h,0)}]
        \pic{cone={ray=3, height=\h, scale=0.5}};
    \end{scope}
  }

\end{tikzpicture}
\end{document}

答案1

不幸的是,我不明白你的构造,但你取了 0.5 的反余弦值。我也不明白

x={(0:1cm)}, y={(90:1cm)}, z={(89:0.4cm), scale=0.5}

除了我从未见过之外z={(89:0.4cm), scale=0.5}我认为如果使用这些向量投射圆锥体,它看起来会很尴尬。

我在这里所能提供的只是一些可以为您提供圆锥体正交投影的东西。我之前关于这个的帖子并不完全正确。请注意,即使我tikz-3dplot在这里使用,这也不依赖于它的特定参数化。只要您加载calc库并安装正交投影,您就会没事。(阴影没有无限调整。基本上有四种情况,尖端的投影在底部投影的内部或外部,尖端可以指向“屏幕外”或屏幕内。这些情况是自动区分的,但每种情况对阴影的规定都略有不同。)

\documentclass[tikz,border=3mm]{standalone}
\usepackage{tikz-3dplot}
\usetikzlibrary{fpu}
\makeatletter
\pgfmathdeclarefunction{screendepth}{3}{%
\begingroup%
\pgfkeys{/pgf/fpu,/pgf/fpu/output format=fixed}%
\pgfmathparse{%
((\the\pgf@yx/1cm)*(\the\pgf@zy/1cm)-(\the\pgf@yy/1cm)*(\the\pgf@zx/1cm))*(#1)+
((\the\pgf@zx/1cm)*(\the\pgf@xy/1cm)-(\the\pgf@xx/1cm)*(\the\pgf@zy/1cm))*(#2)+
((\the\pgf@xx/1cm)*(\the\pgf@yy/1cm)-(\the\pgf@yx/1cm)*(\the\pgf@xy/1cm))*(#3)}%
\pgfmathsmuggle\pgfmathresult\endgroup%
}%
\makeatother
\tikzset{pics/3d cone/.style={code={
    \tikzset{3d cone/.cd,#1}
    \def\pv##1{\pgfkeysvalueof{/tikz/3d cone/##1}}%
    \pgfmathsetmacro{\sdtip}{screendepth(0,0,\pv{h})}
    \pgfmathsetmacro{\aspectangle}{atan2(\sdtip,sqrt(\pv{h}*\pv{h}-\sdtip*\sdtip))}
    \path (0,0,\pv{h}) coordinate (-tip);
    \begin{scope}[x={(0,0,tan(\aspectangle))},y={($(0,0,0)!1cm!90:(0,0,\pv{h})$)}]
     \pgfmathtruncatemacro{\itest}{abs(tan(\aspectangle)*\pv{r}/\pv{h})<1}
     \ifnum\itest=1
      \pgfmathsetmacro{\alphacrit}{acos(tan(\aspectangle)*\pv{r}/\pv{h})}
      \ifdim\sdtip pt>0pt
       \path[/tikz/3d cone/base] circle[radius=\pv{r}];
       \path[/tikz/3d cone/hidden] (\alphacrit:\pv{r}) arc[start angle=\alphacrit,end
       angle=-\alphacrit,radius=\pv{r}];
       \path let \p1=(1,0),\n1={atan2(\y1,\x1)} in 
       [/tikz/3d cone/mantle,shading angle=\n1] (\alphacrit:\pv{r}) 
       arc[start angle=\alphacrit,end
       angle=360-\alphacrit,radius=\pv{r}] -- (-tip) -- cycle;
       \foreach \XX in {0,2,...,42}
        {\path[fill opacity=0.05,fill=white] (\XX:\pv{r}) 
        arc[start angle=\XX,end angle=-\XX,radius=\pv{r}] -- (-tip) -- 
        cycle;}
      \else
       \path[/tikz/3d cone/base,/tikz/3d cone/visible] circle[radius=\pv{r}];
       \path let \p1=(1,0),\n1={atan2(\y1,\x1)} in 
       [/tikz/3d cone/mantle,shading angle=\n1] (\alphacrit:\pv{r}) arc[start angle=\alphacrit,end
       angle=360-\alphacrit,radius=\pv{r}] -- (-tip) -- cycle;
       \foreach \XX in {0,2,...,42}
        {\path[fill opacity=0.05,fill=white] (180+\XX:\pv{r}) 
        arc[start angle=180+\XX,end angle=180-\XX,radius=\pv{r}] -- (-tip) -- 
        cycle;}
      \fi
     \else 
      \ifdim\sdtip pt>0pt
       \path[/tikz/3d cone/base,/tikz/3d cone/visible] circle[radius=\pv{r}];
       \foreach \YY in {0,180}
       {\foreach \XX in {0,2,...,42}
       {\path[fill opacity=0.05,fill=white] (\YY+\XX:\pv{r}) 
        arc[start angle=\YY+\XX,end angle=\YY-\XX,radius=\pv{r}] -- (-tip) -- 
        cycle;
        \path[fill opacity=0.05,fill=black] (90+\YY+\XX:\pv{r}) 
        arc[start angle=90+\YY+\XX,end angle=90+\YY-\XX,radius=\pv{r}] -- (-tip) -- 
        cycle;}}
      \else
       \foreach \YY in {0,180}
       {\foreach \XX in {0,2,...,42}
       {\path[fill opacity=0.05,fill=white] (\YY+\XX:\pv{r}) 
        arc[start angle=\YY+\XX,end angle=\YY-\XX,radius=\pv{r}] -- (-tip) -- 
        cycle;
        \path[fill opacity=0.05,fill=black] (90+\YY+\XX:\pv{r}) 
        arc[start angle=90+\YY+\XX,end angle=90+\YY-\XX,radius=\pv{r}] -- (-tip) -- 
        cycle;}}
       \path[/tikz/3d cone/base] circle[radius=\pv{r}];
      \fi
     \fi
    \end{scope}
    }},
    3d cone/.cd,r/.initial=1,h/.initial=1,
    base/.style={fill=gray},mantle/.style={left color=black,right
    color=black,middle color=gray!20,fill opacity=0.7},
    hidden/.style={draw,very thin,densely dashed},
    visible/.style=draw}
\begin{document}
\foreach \Angle in {5,15,...,355}
{\begin{tikzpicture}
 \path[use as bounding box] (-2.5,-2.5) rectangle (2.5,2.5);
 \tdplotsetmaincoords{70}{110}
 \tdplotsetrotatedcoords{2*\Angle+45}{\Angle}{0}
 \begin{scope}[tdplot_rotated_coords,fill opacity=0.6,text opacity=1]
 \pic{3d cone={r=1.5,h=2}};
 \end{scope}
\end{tikzpicture}}
\end{document}

在此处输入图片描述

相关内容