Учитывая координаты двух фокусов гиперболы и фиксированную разницу расстояний, как я могу нарисовать ее с помощью TikZ $(x_1,y_1)$
?$(x_2,y_2)$
Вот краткое объяснение:
решение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
и , rotate around
предоставляемые TikZ. Если вам интересно: они не работают для преобразования \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}