答案1
一种方法是使用球面坐标来定义球体上的两个点 A 和 B,然后在它们之间画一条虚线并使用计算将这条线延伸到球体之外。
\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz-3dplot}
\usetikzlibrary{backgrounds,calc,positioning}
\makeatletter
%from https://tex.stackexchange.com/a/375604/121799
% spherical coordinates
\define@key{z sphericalkeys}{radius}{\def\myradius{#1}}
\define@key{z sphericalkeys}{theta}{\def\mytheta{#1}}
\define@key{z sphericalkeys}{phi}{\def\myphi{#1}}
\tikzdeclarecoordinatesystem{z spherical}{% %%%rotation around x
\setkeys{z sphericalkeys}{#1}%
\pgfpointxyz{\myradius*sin(\mytheta)*cos(\myphi)}{\myradius*sin(\mytheta)*sin(\myphi)}{\myradius*cos(\mytheta)}}
\makeatother
\begin{document}
\tdplotsetmaincoords{110}{00}
\begin{tikzpicture}[font=\sffamily]
\node[circle,fill,inner sep=1.5pt,label=below right:O] (O) at (0,0,0){};
\shade[ball color=blue,opacity=0.3] (O) circle (4);
\begin{scope}[tdplot_main_coords]
\begin{scope}[on background layer]
\draw[thick,dashed] (z spherical cs:radius=4,theta=120,phi=140)
coordinate (p1) -- (z spherical cs:radius=4,theta=50,phi=240) coordinate (p2);
\draw[thick,dashed] plot[variable=\x,domain=\tdplotmainphi+180:\tdplotmainphi+360,smooth,samples=60] (z spherical cs:radius=4,theta=90,phi=\x);
\end{scope}
\draw[thick] plot[variable=\x,domain=\tdplotmainphi:\tdplotmainphi+180,smooth,samples=60] (z spherical cs:radius=4,theta=90,phi=\x);
\end{scope}
\node[circle,fill,inner sep=1.5pt,label=below right:B] at (p2){};
\node[circle,fill,inner sep=1.5pt,label=below right:A] at (p1){};
\draw[thick] let \p1=($(p2)-(p1)$),\n1={atan2(\y1,\x1)} in (p2) -- ++(\n1:2.5)
(p1) -- ++(\n1+180:2.5);
\end{tikzpicture}
\end{document}
差点忘记动画了。
\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz-3dplot}
\usetikzlibrary{backgrounds,calc,positioning}
\makeatletter
%from https://tex.stackexchange.com/a/375604/121799
% spherical coordinates
\define@key{z sphericalkeys}{radius}{\def\myradius{#1}}
\define@key{z sphericalkeys}{theta}{\def\mytheta{#1}}
\define@key{z sphericalkeys}{phi}{\def\myphi{#1}}
\tikzdeclarecoordinatesystem{z spherical}{% %%%rotation around x
\setkeys{z sphericalkeys}{#1}%
\pgfpointxyz{\myradius*sin(\mytheta)*cos(\myphi)}{\myradius*sin(\mytheta)*sin(\myphi)}{\myradius*cos(\mytheta)}}
\makeatother
\begin{document}
\foreach \X in {0,9,...,354}
{\tdplotsetmaincoords{120}{0}
\begin{tikzpicture}[font=\sffamily]
\path (-5,-6) rectangle (5,7);
\node[circle,fill,inner sep=1.5pt,label=below right:O] (O) at (0,0,0){};
\shade[ball color=blue,opacity=0.3] (O) circle (4);
\begin{scope}[tdplot_main_coords]
\begin{scope}[on background layer]
\draw[thick,dashed] (z spherical cs:radius=4,theta=120,phi=140)
coordinate (p1) -- (z spherical cs:radius=4,theta=20,phi=240+\X) coordinate (p2);
\draw[thick,dashed] plot[variable=\x,domain=\tdplotmainphi+180:\tdplotmainphi+360,smooth,samples=60]
(z spherical cs:radius=4,theta=90,phi=\x);
\end{scope}
\draw[thick] plot[variable=\x,domain=\tdplotmainphi:\tdplotmainphi+180,smooth,samples=60]
(z spherical cs:radius=4,theta=90,phi=\x);
\draw[thin,gray] plot[variable=\x,domain=0:360,smooth,samples=60]
(z spherical cs:radius=4,theta=20,phi=\x);
\end{scope}
\node[circle,fill,inner sep=1.5pt,label=below right:B] at (p2){};
\node[circle,fill,inner sep=1.5pt,label=below right:A] at (p1){};
\draw[thick] let \p1=($(p2)-(p1)$),\n1={atan2(\y1,\x1)} in (p2) -- ++(\n1:2.5)
(p1) -- ++(\n1+180:2.5);
\end{tikzpicture}}
\end{document}
(请注意,pdf 上不存在虚假线条,它们只是在转换为 gif 后才出现,我不知道为什么也不知道如何摆脱它们。)
附录
上面动画 gif 中的虚假线条来自 ghostscript(带有阴影的错误?)。
通过使用pdftopnm
then convert
,虚假线条就会消失:
pdftoppm -r 100 tikz-3d-sphere.pdf temp -png
convert -delay 4 temp-* tikz-3d-sphere.gif
rm temp-*
答案2
考虑球心在,O(0,0,0)
半径为R = 5
。我们知道球面上 有两个点A(0,-4,-3)
和。我在这里复制了一些行B(-3,0,4)
我怎样才能用 3D 方式绘制这个圆柱体?
\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz-3dplot}
\usetikzlibrary{backgrounds,calc,positioning}
\begin{document}
\def\myr{5}
\tdplotsetmaincoords{70}{120}
\begin{tikzpicture}[tdplot_main_coords]
\coordinate (O) at (0,0,0);
\coordinate (A) at (0,-4,-3);
\coordinate (B) at (-3,0,4);
\coordinate (C) at ($(B)!1.3!(A)$);
\coordinate (D) at ($(A)!1.3!(B)$);
\begin{scope}[canvas is xy plane at z=0]
\draw[dashed] (\tdplotmainphi:\myr) arc(\tdplotmainphi:\tdplotmainphi+180:\myr);
\draw[thick] (\tdplotmainphi:\myr) coordinate(BR) arc(\tdplotmainphi:\tdplotmainphi-180:\myr)
coordinate(BL);
\end{scope}
\begin{scope}[tdplot_screen_coords, on background layer]
\fill[ball color=orange,opacity=1] (O) circle (\myr);
\end{scope}
\draw[dashed] (A) -- (B);
\draw[thick] (A) -- (C) (B) -- (D);
\foreach \point/\position in {A/below,B/left,O/below} {\fill (\point) circle (1.5pt); \node[\position=1pt] at (\point) {$\point$};
}
\end{tikzpicture}
\end{document}