給定雙曲線的兩個焦點座標$(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 的替代方案。基本想法與弗里茲的答案相同:旋轉和移位。參數化是這樣的,即使用者指定a
與c
( \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}