使用 TikZ 绘制圆锥投影

使用 TikZ 绘制圆锥投影

我很难画出一个顶部有圆锥体的球体。我想得到的是这样的:

在此处输入图片描述

左锥体在一个纬度上与球体接触,右锥体在两个纬度上与球体表面相交。使用 TikZ 可以实现这一点吗?

这是我得到的结果,基本上就是这个 TikZ 示例:http://www.texample.net/tikz/examples/map-projections/

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc,fadings,decorations.pathreplacing}

\newcommand\pgfmathsinandcos[3]{%
  \pgfmathsetmacro#1{sin(#3)}%
  \pgfmathsetmacro#2{cos(#3)}%
}
\newcommand\LongitudePlane[3][current plane]{%
  \pgfmathsinandcos\sinEl\cosEl{#2} % elevation
  \pgfmathsinandcos\sint\cost{#3} % azimuth
  \tikzset{#1/.estyle={cm={\cost,\sint*\sinEl,0,\cosEl,(0,0)}}}
}
\newcommand\LatitudePlane[3][current plane]{%
  \pgfmathsinandcos\sinEl\cosEl{#2} % elevation
  \pgfmathsinandcos\sint\cost{#3} % latitude
  \pgfmathsetmacro\yshift{\cosEl*\sint}
  \tikzset{#1/.estyle={cm={\cost,0,0,\cost*\sinEl,(0,\yshift)}}} %
}
\newcommand\DrawLongitudeCircle[2][1]{
  \LongitudePlane{\angEl}{#2}
  \tikzset{current plane/.prefix style={scale=#1}}
   % angle of "visibility"
  \pgfmathsetmacro\angVis{atan(sin(#2)*cos(\angEl)/sin(\angEl))} %
  \draw[current plane] (\angVis:1) arc (\angVis:\angVis+180:1);
  \draw[current plane,dashed] (\angVis-180:1) arc (\angVis-180:\angVis:1);
}
\newcommand\DrawLatitudeCircle[2][1]{
  \LatitudePlane{\angEl}{#2}
  \tikzset{current plane/.prefix style={scale=#1}}
  \pgfmathsetmacro\sinVis{sin(#2)/cos(#2)*sin(\angEl)/cos(\angEl)}
  % angle of "visibility"
  \pgfmathsetmacro\angVis{asin(min(1,max(\sinVis,-1)))}
  \draw[current plane] (\angVis:1) arc (\angVis:-\angVis-180:1);
  \draw[current plane,dashed] (180-\angVis:1) arc (180-\angVis:\angVis:1);
}

%% document-wide tikz options and styles
\tikzset{%
  >=latex,%
  inner sep=0pt,%
  outer sep=2pt,%
  mark coordinate/.style={inner sep=0pt,outer sep=0pt,minimum size=3pt,fill=black,circle}%
}

\begin{document}

\begin{tikzpicture}

%% some definitions
\def\R{3} % sphere radius
\def\angEl{25} % elevation angle
\pgfmathsetmacro\H{\R*cos(\angEl)} % distance to north pole

%% draw background sphere
\fill[ball color=white] (0,0) circle (\R); % 3D lighting effect
\draw (0,0) circle (\R);

%% characteristic points
\coordinate[mark coordinate] (N) at (0,\H);
\coordinate[mark coordinate] (S) at (0,-\H);

%% meridians and latitude circles
\foreach \t in {-80,-60,...,80} { \DrawLatitudeCircle[\R]{\t} }
\foreach \t in {-5,-35,...,-175} { \DrawLongitudeCircle[\R]{\t} }
\foreach \t in {-5,-35,...,-175} { \DrawLongitudeCircle[\R]{\t} }

%% draw lines and put labels
\node[above=8pt] at (N) {$\mathbf{N}$};
\node[below=8pt] at (S) {$\mathbf{S}$};

\end{tikzpicture}

\end{document}

我只是想不出如何将圆锥体的侧面与某个纬度圆对齐。

答案1

弯曲物体的可见度为一个使用 Tikz 的婊子但是你可以近似地看:第一个非常好,第二个稍微差一点:

文档结构

\documentclass[tikz,border=5mm]{standalone}

\begin{document}
\pgfmathsetmacro{\R}{5}
\pgfmathsetmacro{\doubleR}{2*\R}

\newcommand{\xangle}{-30}
\newcommand{\yangle}{210}
\newcommand{\zangle}{90}

\newcommand{\xlength}{1}
\newcommand{\ylength}{1}
\newcommand{\zlength}{1}

\pgfmathsetmacro{\xx}{\xlength*cos(\xangle)}
\pgfmathsetmacro{\xy}{\xlength*sin(\xangle)}
\pgfmathsetmacro{\yx}{\ylength*cos(\yangle)}
\pgfmathsetmacro{\yy}{\ylength*sin(\yangle)}
\pgfmathsetmacro{\zx}{\zlength*cos(\zangle)}
\pgfmathsetmacro{\zy}{\zlength*sin(\zangle)}

...

\end{document}

第一张图片

\begin{tikzpicture}
[   x={(\xx cm,\xy cm)},
    y={(\yx cm,\yy cm)},
    z={(\zx cm,\zy cm)},
    scale=0.5,
]

    \pgfmathsetmacro{\cylb}{-3}
    \pgfmathsetmacro{\cylt}{6}

    \pgfmathsetmacro{\rt}{(10-\cylt)/sqrt(3)}
    \pgfmathsetmacro{\rb}{(10-\cylb)/sqrt(3)}
    \fill[red,opacity=0.4] ({cos(159)*\rb},{sin(159)*\rb},{\cylb}) arc (159:291:\rb) -- ({cos(291)*\rt},{sin(291)*\rt},{\cylt}) arc (291:159:\rt) -- cycle;

    \foreach \h in {10,20,...,180}
    {   \foreach \a in {0,10,...,170}
        {   \pgfmathsetmacro{\rt}{\R*sin(\h)}
            \pgfmathsetmacro{\rb}{\R*sin(\h-10)}
            \fill[green!50,draw=black] ({\rb*cos(\a)},{\rb*sin(\a)},{\R*cos(\h-190)}) arc (\a:\a+10:\rb) -- ({\rt*cos(\a+10)},{\rt*sin(\a+10)},{\R*cos(\h-180)}) arc (\a+10:\a:\rt) -- cycle;
            \fill[green!50,draw=black] ({\rb*cos(-\a)},{\rb*sin(-\a)},{\R*cos(\h-190)}) arc (-\a:-\a-10:\rb) -- ({\rt*cos(-\a-10)},{\rt*sin(-\a-10)},{\R*cos(\h-180)}) arc (-\a-10:-\a:\rt) -- cycle;
        }
    }

    \fill[red,opacity=0.4] ({cos(159)*\rb},{sin(159)*\rb},{\cylb}) arc (159:-69:\rb) -- ({cos(-69)*\rt},{sin(-69)*\rt},{\cylt}) arc (-69:159:\rt) -- cycle;

\end{tikzpicture}

第二张图片

\begin{tikzpicture}
[   x={(\xx cm,\xy cm)},
    y={(\yx cm,\yy cm)},
    z={(\zx cm,\zy cm)},
    scale=0.5,
]

    \pgfmathsetmacro{\cylbb}{-4}
    \pgfmathsetmacro{\cyltb}{0.36}
    \pgfmathsetmacro{\cylbt}{4.14}
    \pgfmathsetmacro{\cyltt}{6}

    \pgfmathsetmacro{\rt}{(9-\cyltb)/sqrt(3)}
    \pgfmathsetmacro{\rb}{(9-\cylbb)/sqrt(3)}
    \fill[red,opacity=0.4] ({cos(159)*\rb},{sin(159)*\rb},{\cylbb}) arc (159:291:\rb) -- ({cos(291)*\rt},{sin(291)*\rt},{\cyltb}) arc (291:159:\rt) -- cycle;

    \pgfmathsetmacro{\rt}{(9-\cyltt)/sqrt(3)}
    \pgfmathsetmacro{\rb}{(9-\cylbt)/sqrt(3)}
    \fill[red,opacity=0.4] ({cos(159)*\rb},{sin(159)*\rb},{\cylbt}) arc (159:291:\rb) -- ({cos(291)*\rt},{sin(291)*\rt},{\cyltt}) arc (291:159:\rt) -- cycle;

    \foreach \h in {10,20,...,180}
    {   \foreach \a in {0,10,...,170}
        {   \pgfmathsetmacro{\rt}{\R*sin(\h)}
            \pgfmathsetmacro{\rb}{\R*sin(\h-10)}
            \fill[green!50,draw=black] ({\rb*cos(\a)},{\rb*sin(\a)},{\R*cos(\h-190)}) arc (\a:\a+10:\rb) -- ({\rt*cos(\a+10)},{\rt*sin(\a+10)},{\R*cos(\h-180)}) arc (\a+10:\a:\rt) -- cycle;
            \fill[green!50,draw=black] ({\rb*cos(-\a)},{\rb*sin(-\a)},{\R*cos(\h-190)}) arc (-\a:-\a-10:\rb) -- ({\rt*cos(-\a-10)},{\rt*sin(-\a-10)},{\R*cos(\h-180)}) arc (-\a-10:-\a:\rt) -- cycle;
        }
    }

    \pgfmathsetmacro{\rt}{(9-\cyltb)/sqrt(3)}
    \pgfmathsetmacro{\rb}{(9-\cylbb)/sqrt(3)}
    \fill[red,opacity=0.4] ({cos(159)*\rb},{sin(159)*\rb},{\cylbb}) arc (159:-69:\rb) -- ({cos(-69)*\rt},{sin(-69)*\rt},{\cyltb}) arc (-69:159:\rt) -- cycle;

    \pgfmathsetmacro{\rt}{(9-\cyltt)/sqrt(3)}
    \pgfmathsetmacro{\rb}{(9-\cylbt)/sqrt(3)}
    \fill[red,opacity=0.4] ({cos(159)*\rb},{sin(159)*\rb},{\cylbt}) arc (159:-69:\rb) -- ({cos(-69)*\rt},{sin(-69)*\rt},{\cyltt}) arc (-69:159:\rt) -- cycle;

\end{tikzpicture}

第一个结果

在此处输入图片描述

第二个结果

在此处输入图片描述

限制

  • 图片前面的命令似乎暗示你可以自由选择轴。不。它适用于配置。
  • 在第二张图片中,一部分“前锥体”与球体的侧面重叠。
  • 纬线是圆圈,经线不是圆圈。

答案2

运行xelatex

\documentclass{article}
\usepackage[dvipsnames]{pstricks}
\usepackage{pst-solides3d}
\begin{document}

\begin{pspicture}[solidmemory](-4,-5)(-6,8)
\psset{unit=0.25cm,viewpoint=20 0 10 rtp2xyz,lightsrc=viewpoint,Decran=50}
\psSolid[object=tronccone,
      fillcolor=red!60, r0=5, r1=2, h=6,
      hollow, ngrid=36 36, name=sph2, action=none](0,0,0)
\psSolid[object=sphere, r=3, ngrid=36 36,
    fillcolor=blue, name=sph1, action=none](0,0,2.9)
\psSolid[object=fusion, base=sph1 sph2, opacity=0.6, action=draw**]
\end{pspicture}

\begin{pspicture}[solidmemory](-4,-5)(-6,8)
\psset{unit=0.25cm,viewpoint=20 0 50 rtp2xyz,lightsrc=viewpoint,Decran=50}
\psSolid[object=tronccone, fillcolor=red!60, r0=5, r1=2, h=6,
      incolor=green!40, hollow, ngrid=36 36, name=sph2, action=none](0,0,0)
\psSolid[object=sphere, r=3, ngrid=36 36, fillcolor=blue!40, name=sph1,
    action=none](0,0,2.9)
\psSolid[object=fusion, base=sph1 sph2](0,0,0)%
\end{pspicture}

\end{document}

在此处输入图片描述 在此处输入图片描述

圆锥体和球体的任意组合都是可能的:

在此处输入图片描述在此处输入图片描述

相关内容