如何使用 TikZ 繪製給出焦點和固定差分距離的雙曲線

如何使用 TikZ 繪製給出焦點和固定差分距離的雙曲線

給定雙曲線的兩個焦點座標$(x_1,y_1)$$(x_2,y_2)$固定差距離,我該如何使用 TikZ 繪製它?

這裡簡單解釋一下:

在此輸入影像描述 在此輸入影像描述

答案1

要獲得雙曲線,您可以繪製標準雙曲線:x -> 1/x在適當的底上,以雙曲線的中心為中心,向量在漸近線上。

pics這是TiKz 3.0 中引入的解決方案:

% definition of pic{hyperbola}
\tikzset{
  pics/hyperbola/.style args={(#1)-<#2>-(#3)[#4]}{
    code = { %
      \draw [ samples=100, domain={{1/#4}:{#4}}, % the "size" of the hyperbola 
              shift=($(#1)!.5!(#3)$), % the center of the hyperbola
              x=($(#1)!.25!atan(#2):(#3) - (#1)$), % the first vector of the new base
              y=($(#1)!.25!-atan(#2):(#3) - (#1)$), % the second vector of the new base
              pic actions % transfer pic's styles
            ]
      plot (\x,1/\x) plot (-\x,-1/\x);
    }
  }
}

% example of use
\begin{tikzpicture}
  \draw[help lines] (-4,-3) grid (4,4);
  % the focal points
  \fill (35:2) coordinate (F1) circle(1pt) node[above]{$F_1$};
  \fill (0:-1) coordinate (F2) circle(1pt) node[below]{$F_2$};
  % the center of the hyperbola
  \fill ($(F1)!.5!(F2)$) circle(1pt) node[fill=white, above left]{$\frac{F_1+F_2}2$};
  % the hyperbola with b/a=.7 and "domain" [1/5:5]
  \path (0,0) pic[thick, red]{hyperbola={(F1)-<.7>-(F2)[5]}};
\end{tikzpicture}

在此輸入影像描述

要繪製具有焦點 (F1) 和 (F2)、比率 b/a 和大小 s 的雙曲線,現在可以簡單地執行以下操作:

\path (0,0) pic[thick, red]{hyperbola={(F1)-<b/a>-(F2)[s]}};

答案2

實際上有一種(或多或少)簡單的方法可以做到這一點。您只需採用以原點為中心的雙曲線的標準參數化,然後旋轉並移動它,以使焦點位於所需的位置。

雙曲線參數化

唯一的問題是在 PGFplots 座標上應用仿射變換不是內建的,但幸運的是問題如何在 pgfplots 中進行仿射座標變換?對此給出了一個非常好的解決方案,我已將其調整為採用角度而不是基底向量。

您甚至可以使用TikZ 提供的shift和鍵在雙曲線上繪製 TikZ 裝飾,就好像它以原點為中心一樣。rotate around如果您想知道:這些不適用於變換\addplot座標;相反,當它們在繪圖上使用時,會把事情搞砸。

附註解的雙曲線

程式碼本身非常簡單並帶有註釋,因此應該很容易理解。:-)

\documentclass[tikz,margin=3pt]{standalone}
\usepackage{pgfplots}

\pgfplotsset{
   % 3 Parameters: angle, xshift, yshift
  rotate shift/.style n args={3}{
    filter point/.code = {
      \pgfkeysgetvalue{/data point/x}\X
      \pgfkeysgetvalue{/data point/y}\Y
      \pgfmathparse{cos(#1)*\X - sin(#1)*\Y + #2}
      \pgfkeyslet{/data point/x}\pgfmathresult
      \pgfmathparse{sin(#1)*\X + cos(#1)*\Y + #3}
      \pgfkeyslet{/data point/y}\pgfmathresult
    }
  }
}

% Given: The two foci A and B
\def\Ax{-2}\def\Ay{1}
\def\Bx{3}\def\By{4}
% Given: a = half the distance difference
\def\a{2}

% Calculate half the focus distance c
\pgfmathsetmacro{\c}{sqrt((\Ax-\Bx)^2 + (\Ay-\By)^2)/2}
\pgfmathsetmacro{\b}{sqrt(\c^2-\a^2)}

% Calculate the rotation angle
\pgfmathsetmacro{\rotation}{atan2(\By-\Ay, \Bx-\Ax)}

% Calculate offset from origin to center between hyperbolas
\pgfmathsetmacro{\offsetX}{(\Ax+\Bx)/2}
\pgfmathsetmacro{\offsetY}{(\Ay+\By)/2}

\begin{document}
%\rotation
\begin{tikzpicture}
\begin{axis}[
    axis equal,
    axis lines=center,
]

% Draw the hyperbolas using the PGFplots rotate and shift key defined above.
% Everything is drawn as if the hyperbola were centered around (0,0)
\begin{scope}[/pgfplots/rotate shift={\rotation}{\offsetX}{\offsetY}]
    \addplot[domain=-2:2] ({\a*cosh(x)}, {\b*sinh(x)});
    \addplot[domain=-2:2] ({-\a*cosh(x)}, {\b*sinh(x)});
    \addplot[only marks, mark=+] coordinates {(-\c,0) (\c,0)};
\end{scope}

% Draw some annotations using the TikZ rotate and shift keys.
% Everything is drawn as if the hyperbola were centered around (0,0)
\begin{scope}[shift={(axis direction cs:\offsetX,\offsetY)}, rotate around={\rotation:(axis cs:0,0)}, ]
    \draw (axis cs:-\c,0) -- (axis cs:\c,0);
    \draw[densely dashed]
        (axis cs:-\c,0) node[left] {A}
        -- (axis cs:{\a*cosh(1)}, {\b*sinh(1)}) node[circle,fill, inner sep=1pt] {}
        -- (axis cs:\c,0) node[right] {B};
\end{scope}
\end{axis}
\end{tikzpicture}
\end{document}

答案3

這是使用 TikZ 但不使用 PGFPlots 的替代方案。基本想法與弗里茲的答案相同:旋轉和移位。參數化是這樣的,即使用者指定ac( \acRatio) 的比率,其中c是焦點之間距離的一半,也是a從雙曲線的給定點到兩個焦點的距離固定差的一半。

關於雙曲線數學的一個很好的參考可以在數學世界

範例程式碼的輸出

\documentclass[tikz,border=2pt]{standalone}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}

% Clipping area
\pgfmathsetmacro{\clipLeft}{-4}
\pgfmathsetmacro{\clipRight}{4}
\pgfmathsetmacro{\clipBottom}{-1}
\pgfmathsetmacro{\clipTop}{4}
\clip (\clipLeft,\clipBottom) rectangle(\clipRight,\clipTop);

% Parameters of the hyperbola:
% - Foci (A) and (B). Their distance is 2*c.
% - Ratio of a to c, \acRatio, where a is half of the smallest
%   distance between the two sides of the hyperbola.
%   A number greater than 0, not larger than 1.
\coordinate (A) at (-0.3,1);
\coordinate (B) at (-0.2,2);
\pgfmathsetmacro{\acRatio}{0.35}

%% Computation
% Half the distance between foci
\coordinate (BA) at ($ (B)-(A) $);
\newdimen\myBAx
\pgfextractx{\myBAx}{\pgfpointanchor{BA}{center}}
\newdimen\myBAy
\pgfextracty{\myBAy}{\pgfpointanchor{BA}{center}}
\pgfmathsetlengthmacro{\c}{veclen(\myBAx,\myBAy)/2}
% Semiminor axis
\pgfmathsetlengthmacro{\b}{sqrt(1-\acRatio^2)*\c}
% Semimajor axis
\pgfmathsetlengthmacro{\a}{\acRatio*\c}
% Rotation angle
\pgfmathanglebetweenlines{\pgfpoint{0}{0}}{\pgfpoint{1}{0}}
{\pgfpointanchor{A}{center}}{\pgfpointanchor{B}{center}}
\let\rotAngle\pgfmathresult
% Shift
\coordinate (O) at ($ (A)!.5!(B) $);
%% Plotting
% Hyperbola. Adjust domain if a wider view is needed.
\tikzset{hyperbola/.style={rotate=\rotAngle,shift=(O),
    domain=-3:3,variable=\t,samples=50,smooth}}
\draw[hyperbola] plot ({ \a*cosh(\t)},{\b*sinh(\t)});
\draw[hyperbola] plot ({-\a*cosh(\t)},{\b*sinh(\t)});
% Asymptotes
\pgfmathsetmacro{\baRatio}{\b/\a}
\tikzset{asymptote/.style={rotate=\rotAngle,shift=(O),
    samples=2,domain=\clipLeft:\clipRight,dash pattern=on 2mm off 1mm}}
\draw[asymptote] plot ({\x},{\baRatio*\x});
\draw[asymptote] plot ({\x},{-\baRatio*\x});
% Axes
\tikzset{axis/.style={->,black!40}}
\draw[axis] (\clipLeft,0) -- (\clipRight,0);
\draw[axis] (0,\clipBottom) -- (0,\clipTop);
% Line segment between foci
\draw[blue,thick] (A) -- (O);
\draw[red,thick] (O) -- (B);
% Foci
\fill (A) circle (0.5mm);
\fill (B) circle (0.5mm);
\end{tikzpicture}
\end{document}

相關內容