我正在尝试按以下方式绘制立体投影:
\documentclass{article}
\usepackage{mathtools}
\usepackage{wrapfig}
\usepackage{pgf,tikz,pgfplots}
\usetikzlibrary{decorations.pathreplacing, calligraphy}
\usetikzlibrary{decorations.markings}
\usetikzlibrary{patterns}
\usetikzlibrary{calc}
\begin{document}
\begin{figure}
\centering
\begin{tikzpicture}
\coordinate (A) at (3,-0.25);
\coordinate (P) at (0,2);
\draw (0,0) circle (2);
\draw (0,0) ellipse (2 and 0.5);
\draw (-4.5,-1) -- (3.5,-1) -- (4.5,1) node[anchor=south east] {\scriptsize$ z=0 $} -- (-3.5,1) -- cycle;
\draw (A) -- (P) coordinate[pos=0.47](B);
\path (A) node[circle, fill, inner sep=1pt, label=below:{\scriptsize$ P(x,y,0) $}]{};
\path (B) node[circle, fill, inner sep=1pt, label=left:{\scriptsize$ (\xi,\eta,\zeta) $}]{};
\path (P) node[circle, fill, inner sep=1pt, label=above:{\scriptsize$ (0,0,1) $}]{};
\draw [dashed] (-2,0) -- (2,0);
\end{tikzpicture}
\end{figure}
\end{document}
另外,我想沿着蓝线添加另一条 MWE 中没有的虚线。
答案1
您只需要在不同的路径中绘制虚线和实线部分,因此对于弧形路径使用arc
s 而不是s。circle
30 度角是通过反复试验找到的,但如果有需要也可以计算出来。
\documentclass[border=5mm]{standalone}
\usepackage{pgfplots} % loads tikz which loads pgf
\begin{document}
\begin{tikzpicture}
\coordinate (A) at (3,-0.25);
\coordinate (P) at (0,2);
\draw (0:2cm) arc[radius=2cm,start angle=0,end angle=180]
(210:2cm) arc[radius=2cm,start angle=210,end angle=330];
\draw (180:2cm) arc[x radius=2cm, y radius=0.5cm, start angle=180,end angle=360];
\draw [dashed] (210:2cm)
arc[start angle=210,delta angle=-30,radius=2cm]
arc[start angle=180,delta angle=-180,x radius=2cm,y radius=0.5cm]
arc[start angle=0,delta angle=-30,radius=2cm];
\draw [dashed] (80:2cm and 0.5cm) -- (260:2cm and 0.5cm);
\draw [dashed] (150:2cm) coordinate(ul) -- (30:2cm) coordinate(ur);
\draw (-4.5,-1) -- (3.5,-1) -- (4.5,1) node[anchor=south east] {\scriptsize$ z=0 $} -- (ur) (ul) -- (-3.5,1) -- (-4.5,-1);
\draw (A) -- (P) coordinate[pos=0.47](B);
\path (A) node[circle, fill, inner sep=1pt, label=below:{\scriptsize$ P(x,y,0) $}]{};
\path (B) node[circle, fill, inner sep=1pt, label=left:{\scriptsize$ (\xi,\eta,\zeta) $}]{};
\path (P) node[circle, fill, inner sep=1pt, label=above:{\scriptsize$ (0,0,1) $}]{};
\draw [dashed] (-2,0) -- (2,0);
\end{tikzpicture}
\end{document}
答案2
这是立体投影的正交投影。即使用具有实际立体投影的 3d 坐标并通过正交投影投影到屏幕上。虚线是通过一系列剪辑和反向剪辑实现的。
\documentclass{article}
\usepackage{tikz}
% based on
% https://tex.stackexchange.com/a/38995/121799
% https://tex.stackexchange.com/a/76216
% https://tex.stackexchange.com/a/59168/194703
% https://tex.stackexchange.com/q/448920/194703
\makeatletter
\tikzset{
reuse path/.code={\pgfsyssoftpath@setcurrentpath{#1}}
}
\tikzset{even odd clip/.code={\pgfseteorule},
protect/.code={
\clip[overlay,even odd clip,reuse path=#1]
(current bounding box.south west) rectangle (current bounding box.north east)
%(-16383.99999pt,-16383.99999pt) rectangle (16383.99999pt,16383.99999pt)
;
}}
\makeatother
\usetikzlibrary{3d,perspective}
\begin{document}
\pgfmathsetmacro{\myaz}{10}
\begin{tikzpicture}[declare function={%
stereox(\x,\y)=2*\x/(1+\x*\x+\y*\y);%
stereoy(\x,\y)=2*\y/(1+\x*\x+\y*\y);%
stereoz(\x,\y)=(-1+\x*\x+\y*\y)/(1+\x*\x+\y*\y);},scale=2.5,
line join=round,line cap=round,
dot/.style={circle,fill,inner sep=1pt}]
\path[save path=\pathSphere] (0,0) circle[radius=1];
\begin{scope}[3d view={\myaz}{15}]
\draw (-2,2) -- (-2,-2) coordinate (bl) -- (2,-2) coordinate (br)-- (2,2)
node[above left]{$z=0$};
\begin{scope}
\tikzset{protect=\pathSphere}
\draw (-2,2) -- (2,2);
\end{scope}
\begin{scope}
\clip[reuse path=\pathSphere];
\draw[dashed] (-2,2) -- (2,2);
\end{scope}
\begin{scope}[canvas is xy plane at z=0]
\draw[dashed] (\myaz:1) arc[start angle=\myaz,end angle=\myaz+180,radius=1];
\draw (\myaz:1) arc[start angle=\myaz,end angle=\myaz-180,radius=1];
\path[save path=\pathPlane] (\myaz:2) -- (\myaz+180:2) --(bl) -- (br) -- cycle;
\begin{scope}
\clip[use path=\pathPlane];
\draw[dashed,use path=\pathSphere];
\end{scope}
\begin{scope}
\tikzset{protect=\pathPlane}
\draw[use path=\pathSphere];
\end{scope}
\end{scope}
\draw (1.5,-1,0) node[dot,label=below:{$P(x,y,0)$}]{}
-- ({stereox(1.5,-1)},{stereoy(1.5,-1)},{stereoz(1.5,-1)})
node[dot,label=below left:{$(\xi,\eta,\zeta)$}](I){};
\draw[dashed] (I) -- (0,0,1) node[dot,label=above:{$(0,0,1)$}]{};
\end{scope}
\end{tikzpicture}
\end{document}
可以改变平面上点的视图参数和坐标。(这些都包含在一个动画中,但参数可以单独改变。)
\documentclass[tikz,border=3mm]{standalone}
% based on
% https://tex.stackexchange.com/a/38995/121799
% https://tex.stackexchange.com/a/76216
% https://tex.stackexchange.com/a/59168/194703
% https://tex.stackexchange.com/q/448920/194703
\makeatletter
\tikzset{
reuse path/.code={\pgfsyssoftpath@setcurrentpath{#1}}
}
\tikzset{even odd clip/.code={\pgfseteorule},
protect/.code={
\clip[overlay,even odd clip,reuse path=#1]
(current bounding box.south west) rectangle (current bounding box.north east)
;
}}
\makeatother
\usetikzlibrary{3d,perspective}
\begin{document}
\foreach \X in {5,15,...,355}
{\pgfmathsetmacro{\myaz}{10+10*sin(\X)}
\begin{tikzpicture}[declare function={%
stereox(\x,\y)=2*\x/(1+\x*\x+\y*\y);%
stereoy(\x,\y)=2*\y/(1+\x*\x+\y*\y);%
stereoz(\x,\y)=(-1+\x*\x+\y*\y)/(1+\x*\x+\y*\y);
Px=1.75+0.5*sin(2*\X);Py=-1.5+0.5*cos(2*\X);amax=2.5;},scale=2.5,
line join=round,line cap=round,
dot/.style={circle,fill,inner sep=1pt}]
\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground}
\path[use as bounding box] (-3.5,-2) rectangle (3.5,2);
\path[save path=\pathSphere,ball color=gray,fill opacity=0.6]
(0,0) circle[radius=1];
\begin{scope}[3d view={\myaz}{15}]
\draw (-amax,amax) -- (-amax,-amax) coordinate (bl) -- (amax,-amax)
coordinate (br)-- (amax,amax)
node[above left]{$z=0$};
\begin{scope}
\tikzset{protect=\pathSphere}
\draw (-amax,amax) -- (amax,amax);
\end{scope}
\begin{scope}
\clip[reuse path=\pathSphere];
\draw[dashed] (-amax,amax) -- (amax,amax);
\end{scope}
\begin{scope}[canvas is xy plane at z=0]
\draw[dashed] (\myaz:1) arc[start angle=\myaz,end angle=\myaz+180,radius=1];
\draw (\myaz:1) arc[start angle=\myaz,end angle=\myaz-180,radius=1];
\path[save path=\pathPlane] (\myaz:amax) -- (\myaz+180:amax) --(bl) -- (br) -- cycle;
\begin{scope}
%\begin{pgfonlayer}{background}
\clip[use path=\pathPlane];
\draw[dashed,use path=\pathSphere];
%\end{pgfonlayer}
\end{scope}
\begin{scope}
\tikzset{protect=\pathPlane}
\draw[use path=\pathSphere];
\end{scope}
\begin{pgfonlayer}{background}
\fill[blue!30,fill opacity=0.6]
(\myaz:1) arc[start angle=\myaz,end angle=\myaz-180,radius=1]
-- (-amax,0) -- (-amax,amax) -- (amax,amax) -- (amax,0) -- cycle;
\end{pgfonlayer}
\fill[blue!30,fill opacity=0.6]
(\myaz:1) arc[start angle=\myaz,end angle=\myaz-180,radius=1]
-- (-amax,0) -- (-amax,-amax) -- (amax,-amax) -- (amax,0) -- cycle;
\end{scope}
\draw (Px,Py,0) node[dot,label=below:{$P(x,y,0)$}]{}
-- ({stereox(Px,Py)},{stereoy(Px,-1)},{stereoz(Px,Py)})
node[dot,label=below left:{$(\xi,\eta,\zeta)$}](I){};
\begin{pgfonlayer}{background}
\draw[dashed] (I) -- (0,0,1) node[dot,label=above:{$(0,0,1)$}]{};
\end{pgfonlayer}
\end{scope}
\end{tikzpicture}}
\end{document}