dy/dx=-x/yの方向フィールド

dy/dx=-x/yの方向フィールド
\documentclass{beamer}
\usepackage{tikz,pgfplots}
\begin{document}
\begin{frame}
\def\length{sqrt(1+(-x/y)^2)}
\begin{tikzpicture}
\begin{axis}[
domain=-3:3, 
view={0}{90},
title={$\displaystyle\frac{dy}{dx}=-\frac{x}{y}$},
xmin=-3,
xmax=3,
ymin=-3,
ymax=3,
ytick={-3,-2,-1,0,1,2,3}
]
\addplot3[gray, quiver={u={1/(\length)}, v={(-x/y)/(\length)}, scale arrows=0.15}, -,samples=40] {0};
\addplot +[blue, samples=31, smooth, thick, no markers, domain=-sqrt(2):sqrt(2)]{sqrt(2-x^2)};
\addplot +[red, samples=31, smooth, thick, no markers, domain=-2:2]{sqrt(4-x^2)};
\addplot +[orange, samples=31, smooth, thick, no markers, domain=-sqrt(6):sqrt(6)]{sqrt(6-x^2)};
\addplot +[blue, samples=31, smooth, thick, no markers, domain=-sqrt(2):sqrt(2)]{-sqrt(2-x^2)};
\addplot +[red, samples=31, smooth, thick, no markers, domain=-2:2]{-sqrt(4-x^2)};
\addplot +[orange, samples=31, smooth, thick, no markers, domain=-sqrt(6):sqrt(6)]{-sqrt(6-x^2)};
\end{axis}
\end{tikzpicture}
\end{frame}
\end{document}

これは $\frac{dy}{dx}=-\frac{x}{y}$ の方向フィールドです。問題が 2 つあります。

  1. プログラムで負の x 軸上にベクトルを描画するにはどうすればよいですか?
  2. グラフ上に特定の半径の円を描くにはどうすればよいですか (私が考え出した方法は明らかに機能しません)?

ご協力いただきありがとうございます。

編集: ドキュメント クラスを beamer として追加しましたが、article でも同じように動作します。

答え1

ここに画像の説明を入力してください

\documentclass{beamer}
\usepackage{pgfplots}
\usetikzlibrary{arrows.meta}
\begin{document}
\begin{frame}
\def\length{sqrt(1+(-x/y)^2)}
\begin{tikzpicture}
\begin{axis}[
domain=-3:3, 
view={0}{90},
title={$\displaystyle\frac{dy}{dx}=-\frac{x}{y}$},
xmin=-3,
xmax=3,
ymin=-3,
ymax=3,
ytick={-3,-2,-1,0,1,2,3}
]
\addplot3[gray, quiver={u={1/(\length)}, v={(-x/y)/(\length)}, scale arrows=0.1}, -{Stealth[width=2pt,length=2pt]},samples=24,domain=-3:3] {0};
\addplot[blue, samples=50, thick, no markers, domain=0:2*pi] ({cos(deg(x))},{sin(deg(x))});
\addplot[red, samples=50, thick, no markers, domain=0:2*pi] ({2*cos(deg(x))},{2*sin(deg(x))});
\addplot[orange, samples=50, thick, no markers, domain=0:2*pi] ({3*cos(deg(x))},{3*sin(deg(x))});
\end{axis}
\end{tikzpicture}
\end{frame}
\end{document}

これで十分かどうかはわかりません。円はパラメトリックプロットとして描かれます。つまり、次のような形式です。\addplot ({r*cos(x)}, {r*sin(x)});

x < 0 の矢印間のギャップは、私が見る限り、座標 (x,y) が矢印の始点を指していることが原因です。矢印は反対方向を指しているため (上の画像を参照)、そこにギャップが生じ、x > 0 では重なりが生じます。矢印のスケーリングを少し減らすと、重なりの問題は修正されます。上の画像ではサンプル数が 24 に減らされていますが、実際に 40 サンプルが必要な場合は、矢印をさらにスケーリングする必要があります。例:

\addplot3[gray, quiver={u={1/(\length)}, v={(-x/y)/(\length)}, scale arrows=0.07}, -{Stealth[width=1pt,length=1pt]},samples=40,domain=-3:3] {0};

x 軸に垂直矢印を表示する 1 つの方法は、u=0、v=±1 の個別の矢印を追加することです。矢印のスケーリングは異なる場合があります。

\documentclass{beamer}
\usepackage{pgfplots}
\usetikzlibrary{arrows.meta}
\begin{document}
\begin{frame}
\def\length{sqrt(1+(-x/y)^2)}
\begin{tikzpicture}
\begin{axis}[
domain=-3:3, 
view={0}{90},
title={$\displaystyle\frac{dy}{dx}=-\frac{x}{y}$},
xmin=-3,
xmax=3,
ymin=-3,
ymax=3,
ytick={-3,-2,-1,0,1,2,3}
]
\addplot3[gray, quiver={u={1/(\length)}, v={(-x/y)/(\length)}, scale arrows=0.07}, -{Stealth[width=1pt,length=1pt]},samples=20,domain=-3:3] {0};

\addplot3[gray, quiver={u={0}, v={1}, scale arrows=0.05}, -{Stealth[width=1pt,length=1pt]},samples=10,samples y=1,domain=-3:-0.17,y domain=0] {0};
\addplot3[gray, quiver={u={0}, v={-1}, scale arrows=0.05}, -{Stealth[width=1pt,length=1pt]},samples=10,samples y=1,domain=-3:-0.17,y domain=0] {0};

\addplot[blue, samples=50, thick, no markers, domain=0:2*pi] ({cos(deg(x))},{sin(deg(x))});
\addplot[red, samples=50, thick, no markers, domain=0:2*pi] ({2*cos(deg(x))},{2*sin(deg(x))});
\addplot[orange, samples=50, thick, no markers, domain=0:2*pi] ({3*cos(deg(x))},{3*sin(deg(x))});
\end{axis}
\end{tikzpicture}
\end{frame}
\end{document}

ここに画像の説明を入力してください

答え2

quiverこれは、コマンドがpgfplots等間隔グリッドの各ポイントに矢印の中心ではなく尾部を配置することによる、矢印間の間隔の不一致の問題にも対処するソリューションです。

この問題に対処するには、まず通常の方法で矢印を描画し、次に最初の矢印とまったく反対の方向を指すが矢じりのない 2 番目の矢印を描画します。つまり、2 番目の「矢印」は基本的に単なる線です。これら 2 つのオブジェクトを組み合わせると、最初の矢印の方向を指す矢印が構成されます。これにより、矢印が点の中心に配置されているという錯覚が生じます。

例えば:

ここに画像の説明を入力してください

\begin{tikzpicture}[
    declare function = {f(\x) = -\x/\y;} % Define which function we're using
    ]
    \begin{axis}[
        zmax = 1,
        zmin = 0,
        xtick = {-1,-0.5,...,1},
        axis equal image = true, % Unit vectors for both axes have the same length
        view = {0}{90}
        ]
        \addplot3[% Arrows' first-half
            blue,
            -stealth,
            domain  = -1:1,
            samples = 20,
            quiver  = {
                u=1/(2*sqrt(1^2 + f(x)^2)),
                v=f(x)/(2*sqrt(1^2 + f(x)^2)),
                scale arrows=0.075,
                },
        ] (x,y,0);
        \addplot3[% Arrow's second-half
            blue,
            domain  = -1:1,
            samples = 20,
            quiver  = {
                u=-1/(2*sqrt(1^2 + f(x)^2)),
                v=-f(x)/(2*sqrt(1^2 + f(x)^2)),
                scale arrows=0.075,
                },
        ] (x,y,0);
        \addplot [domain=-180:180, samples=100, color=red, thick] ({0.75*cos(x)},{0.75*sin(x)});
    \end{axis}
\end{tikzpicture}

この解決策はメリーランド大学のTobias von PetersdorffによるMatlabコードからヒントを得たものです。リンク

関連情報