Как построить гиперболу, указав фокусы и фиксированное разностное расстояние, используя TikZ

Как построить гиперболу, указав фокусы и фиксированное разностное расстояние, используя TikZ

Учитывая координаты двух фокусов гиперболы и фиксированную разницу расстояний, как я могу нарисовать ее с помощью 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}

Связанный контент