我使用了 3D 圆的公式。但是有些错误。
有人想扫码或者有更好的解决方案吗?
\documentclass[margin=5mm, tikz]{standalone}
\usepackage{amsmath, amsfonts}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\usetikzlibrary{arrows,calc,backgrounds}
\begin{document}
\pgfmathsetmacro{\R}{3} %
\pgfmathsetmacro{\a}{1.5} %
\pgfmathsetmacro{\r}{sqrt(\R^2-\a^2)} %
%\pgfmathsetmacro{\Alpha}{atan(\r/\a)}
\pgfmathsetmacro{\Alpha}{acos(\a/\R)} %
\pgfkeys{/tikz/savevalue/.code 2 args={\global\edef#1{#2}}}
\tdplotsetmaincoords{60}{110}
\begin{tikzpicture}[
tdplot_main_coords,
>=latex, font=\footnotesize,
]
\coordinate[label=$Z$] (Z) at (0,0,0);
\pgfmathsetmacro{\Teta}{90} % measured to the z-axis
\pgfmathsetmacro{\Phi}{50} % measured to the x-axis
% Radius of Small Circle
\pgfmathsetmacro{\xA}{\R*sin(\Teta)*cos(\Phi)} %
\pgfmathsetmacro{\yA}{\R*sin(\Teta)*sin(\Phi)} %
\pgfmathsetmacro{\zA}{\R*cos(\Teta)} %
\coordinate[label=$A$] (A) at (\xA,\yA,\zA);
\draw[thick] (Z) -- (A);
% Middlepoint of Small Circle
\pgfmathsetmacro{\xM}{\a*sin(\Teta)*cos(\Phi)} %
\pgfmathsetmacro{\yM}{\a*sin(\Teta)*sin(\Phi)} %
\pgfmathsetmacro{\zM}{\a*cos(\Teta)} %
\coordinate[label=$M$] (M) at (\xM,\yM,\zM);
\draw[red, thick] (Z) -- (M);
% Point P of direction vector p
\pgfmathsetmacro{\xP}{\R*sin(\Teta-\Alpha)*cos(\Phi)} %
\pgfmathsetmacro{\yP}{\R*sin(\Teta-\Alpha)*sin(\Phi)} %
\pgfmathsetmacro{\zP}{\R*cos(\Teta-\Alpha)} %
\coordinate[label=$P$] (P) at (\xP,\yP,\zP);
\draw[thick] (Z) -- (P);
\draw[->] (M) -- (P);
\path let
\p0 = (M), % Center
\p1 = (P),
\n1 = {veclen(\y1-\y0,\x1-\x0)}, \n2={atan2(\y1-\y0,\x1-\x0)}
in [savevalue={\Radius}{\n1}, savevalue={\angle}{\n2}];
\pgfmathsetmacro{\RadiusP}{\Radius/28.4528} % wipe of 'pt'
% Point Q of direction vector q
\pgfmathsetmacro{\xQ}{\R*sin(\Teta)*cos(\Phi-\Alpha)} %
\pgfmathsetmacro{\yQ}{\R*sin(\Teta)*sin(\Phi-\Alpha)} %
\pgfmathsetmacro{\zQ}{\R*cos(\Teta)} %
\coordinate[label=$Q$] (Q) at (\xQ,\yQ,\zQ);
\draw[thick] (Z) -- (Q);
\draw[->] (M) -- (Q);
\path let
\p0 = (M), % Center
\p1 = (Q),
\n1 = {veclen(\y1-\y0,\x1-\x0)}, \n2={atan2(\y1-\y0,\x1-\x0)}
in [savevalue={\Radius}{\n1}, savevalue={\angle}{\n2}];
\pgfmathsetmacro{\RadiusQ}{\Radius/28.4528} % wipe of 'pt'
%OLD
% 3D Small Circle
%\foreach \t in {0,...,360}{
%\pgfmathsetmacro{\rp}{cos(\t)*\r/\RadiusP} %
%\pgfmathsetmacro{\rq}{sin(\t)*\r/\RadiusQ} %
%\coordinate[label=$$] (X) at ($(M)+\rp*(P)-\rp*(M)+\rq*(Q)-\rq*(M)$);
%\draw[red] (X) circle (1pt);
%}
% NEW:
% 3D Small Circle
% Set Range of angles for drawing points
\def\Range{0,...,360}
\pgfmathsetmacro{\rp}{\r/\RadiusP} %
\pgfmathsetmacro{\rq}{\r/\RadiusQ} %
% Create List of Coordinates
\newcommand{\List}{}% reserve name
\let\List=\empty% create list
\makeatletter
\foreach \t in \Range
{
\coordinate[label=$$] (X-\t) at ($(M)+cos(\t)*\rp*(P)-cos(\t)*\rp*(M)+sin(\t)*\rq*(Q)-sin(\t)*\rq*(M)$);
\pgfmathsetmacro\temp{"(X-\t)"}%
\ifx\empty\List{} \protected@xdef\List{\temp}%
\else \protected@xdef\List{\List \temp}%
\fi
}
\makeatother
\draw[red, thick] plot[] coordinates{\List};
% Sphere
\begin{scope}[tdplot_screen_coords, on background layer]
\fill[ball color= gray!20, opacity = 0.3] (Z) circle (\R);
\end{scope}
\begin{scope}[-latex, shift={(Z)}, xshift=0*2.1*\R cm, yshift=0*0.1*\R cm]
\foreach \P/\s/\Pos in {(5,0,0)/x/right, (0,5,0)/y/below, (0,0,5)/z/right}
\draw[] (0,0,0) -- \P node (\s) [\Pos, pos=0.9,inner sep=2pt]{$\s$};
\node[above=1cm, align=left, font=\normalsize] at (z){Equation of a 3D-circle: \\
$\vec{x} = \vec{m} + r \cos(t) \cdot \vec{p} + r \sin(t) \cdot \vec{q}
~~\text{(with $t = 0\dots 2\pi$)}$
};
\end{scope}
\node[anchor=north west, align=left] at (0,-3,-5){
Radius of Sphere: $R = \R$ \\
Distance Small Circle Middlepoint from Sphere Middlepoint: $|ZM| = a = \a$ \\
Angle beetween $\vec{ZM}$ and $\vec{ZP}$: $\alpha=\Alpha^\circ$ \\
Radius of Small Circle: $r = \r$ \\
$|MP|=\RadiusP,~ |MQ|=\RadiusQ$ \\
$r_p = \dfrac{r}{|MP|} = \rp,~ r_q = \dfrac{r}{|MQ|} = \rq$
};
\end{tikzpicture}
\end{document}
答案1
使用旋转坐标会容易得多。只需调整角度直到(0,0,\R)
与对齐即可(A)
。
\documentclass[margin=5mm, tikz]{standalone}
\usepackage{mathtools}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\usetikzlibrary{arrows,calc,backgrounds}
\begin{document}
\pgfmathsetmacro{\R}{3} %
\pgfmathsetmacro{\a}{1.5} %
\pgfmathsetmacro{\r}{sqrt(\R*\R-\a*\a} %
%\pgfmathsetmacro{\Alpha}{atan(\r/\a)}
\pgfmathsetmacro{\Alpha}{acos(\a/\R)} %
\pgfkeys{/tikz/savevalue/.code 2 args={\global\edef#1{#2}}}
\tdplotsetmaincoords{60}{110}
\begin{tikzpicture}[
tdplot_main_coords,
>=latex, font=\footnotesize,
]
\coordinate[label=$Z$] (Z) at (0,0,0);
\pgfmathsetmacro{\Teta}{90} % measured to the z-axis
\pgfmathsetmacro{\Phi}{50} % measured to the x-axis
\tdplotsetrotatedcoords{50}{90}{0}
\begin{scope}[tdplot_rotated_coords]
\coordinate[label=$A$] (A) at (0,0,\R);
\coordinate[label=$M$] (M) at (0,0,\a);
\draw[red, thick] (M) circle[radius=\r];
\end{scope}
\draw[thick] (Z) -- (A);
\draw[red, thick] (Z) -- (M);
% Point P of direction vector p
\pgfmathsetmacro{\xP}{\R*sin(\Teta-\Alpha)*cos(\Phi)} %
\pgfmathsetmacro{\yP}{\R*sin(\Teta-\Alpha)*sin(\Phi)} %
\pgfmathsetmacro{\zP}{\R*cos(\Teta-\Alpha)} %
\coordinate[label=$P$] (P) at (\xP,\yP,\zP);
\draw[thick] (Z) -- (P);
\draw[->] (M) -- (P);
\path let
\p0 = (M), % Center
\p1 = (P),
\n1 = {veclen(\y1-\y0,\x1-\x0)}, \n2={atan2(\y1-\y0,\x1-\x0)}
in [savevalue={\Radius}{\n1}, savevalue={\angle}{\n2}];
\pgfmathsetmacro{\RadiusP}{\Radius/28.4528} % wipe of 'pt'
% Point Q of direction vector q
\pgfmathsetmacro{\xQ}{\R*sin(\Teta)*cos(\Phi-\Alpha)} %
\pgfmathsetmacro{\yQ}{\R*sin(\Teta)*sin(\Phi-\Alpha)} %
\pgfmathsetmacro{\zQ}{\R*cos(\Teta)} %
\coordinate[label=$Q$] (Q) at (\xQ,\yQ,\zQ);
\draw[thick] (Z) -- (Q);
\draw[->] (M) -- (Q);
\path let
\p0 = (M), % Center
\p1 = (Q),
\n1 = {veclen(\y1-\y0,\x1-\x0)}, \n2={atan2(\y1-\y0,\x1-\x0)}
in [savevalue={\Radius}{\n1}, savevalue={\angle}{\n2}];
\pgfmathsetmacro{\RadiusQ}{\Radius/28.4528} % wipe of 'pt'
%OLD
% 3D Small Circle
%\foreach \t in {0,...,360}{
%\pgfmathsetmacro{\rp}{cos(\t)*\r/\RadiusP} %
%\pgfmathsetmacro{\rq}{sin(\t)*\r/\RadiusQ} %
%\coordinate[label=$$] (X) at ($(M)+\rp*(P)-\rp*(M)+\rq*(Q)-\rq*(M)$);
%\draw[red] (X) circle (1pt);
%}
% Sphere
\begin{scope}[tdplot_screen_coords, on background layer]
\fill[ball color= gray!20, opacity = 0.3] (Z) circle (\R);
\end{scope}
\begin{scope}[-latex, shift={(Z)}, xshift=0*2.1*\R cm, yshift=0*0.1*\R cm]
\foreach \P/\s/\Pos in {(5,0,0)/x/right, (0,5,0)/y/below, (0,0,5)/z/right}
\draw[] (0,0,0) -- \P node (\s) [\Pos, pos=0.9,inner sep=2pt]{$\s$};
\node[above=1cm, align=left, font=\normalsize] at (z){Equation of a 3D-circle: \\
$\vec{x} = \vec{m} + r \cos(t) \cdot \vec{p} + r \sin(t) \cdot \vec{q}
~~\text{(with $t = 0\dots 2\pi$)}$
};
\end{scope}
\pgfmathsetmacro{\rp}{\r/\RadiusP} %
\pgfmathsetmacro{\rq}{\r/\RadiusQ} %
\node[anchor=north west, align=left] at (0,-3,-5){
Radius of Sphere: $R = \R$ \\
Distance Small Circle Middlepoint from Sphere Middlepoint: $|ZM| = a = \a$ \\
Angle beetween $\vec{ZM}$ and $\vec{ZP}$: $\alpha=\Alpha^\circ$ \\
Radius of Small Circle: $r = \r$ \\
$|MP|=\RadiusP,~ |MQ|=\RadiusQ$ \\
$r_p = \dfrac{r}{|MP|} = \rp,~ r_q = \dfrac{r}{|MQ|} = \rq$
};
\end{tikzpicture}
\end{document}
有一个基本的图形函数,可以用来使用M
、P
和绘制圆形Q
。
\pgfscope
\color{blue}%
\pgfpathellipse{\pgfpointanchor{M}{center}}%
{\pgfpointdiff{\pgfpointanchor{M}{center}}{\pgfpointanchor{P}{center}}}%
{\pgfpointdiff{\pgfpointanchor{M}{center}}{\pgfpointanchor{Q}{center}}}%
\pgfusepath{draw}%
\endpgfscope