Cómo trazar una hipérbola dando los focos y la distancia diferencial fija usando TikZ

Cómo trazar una hipérbola dando los focos y la distancia diferencial fija usando TikZ

Dadas las coordenadas de los dos focos $(x_1,y_1)$y $(x_2,y_2)$de la hipérbola y la distancia de diferencia fija, ¿cómo puedo dibujarla usando TikZ?

Aquí una breve explicación:

ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí

Respuesta1

Para obtener la hipérbola se puede dibujar la estándar: x -> 1/xen una base adecuada con centro en el centro de la hipérbola y vectores en las asíntotas.

Aquí hay una solución que picsse introduce en 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}

ingrese la descripción de la imagen aquí

Para dibujar una hipérbola con puntos focales (F1) y (F2), con relación b/a y tamaño s, ahora puedes simplemente hacer:

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

Respuesta2

En realidad, existe una manera (más o menos) fácil de hacer esto. Simplemente se toma la parametrización estándar de una hipérbola que está centrada alrededor del origen y luego se gira y se desplaza para que los focos se encuentren en la posición deseada.

Prametrización de hipérbolas.

El único problema es que la aplicación de transformaciones afines en las coordenadas de PGFplots no está integrada, pero afortunadamente la pregunta¿Cómo puedo hacer una transformación de coordenadas afines en pgfplots?da una muy buena solución a eso, que he adaptado para tomar un ángulo en lugar de vectores base.

Incluso puedes dibujar decoraciones TikZ en la hipérbola como si estuviera centrada alrededor del origen, usando las teclas shifty rotate aroundproporcionadas por TikZ. En caso de que te lo preguntes: estos no funcionan para transformar \addplotcoordenadas; en cambio, estropean las cosas cuando se usan en tramas.

Hipérbola comentada

El código en sí es bastante sencillo y está comentado, por lo que debería ser fácil de seguir.:-)

\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}

Respuesta3

Aquí hay una solución alternativa con TikZ pero sin PGFPlots. La idea básica es la misma que en la respuesta de Fritz: rotar y desplazar. La parametrización es tal que el usuario especifica la relación de aa c( \acRatio), donde ces la mitad de la distancia entre los focos y ala mitad de la diferencia fija de distancias desde un punto dado de la hipérbola a los dos focos.

Una buena referencia a las matemáticas de la hipérbola se puede encontrar enMundoMatemático.

Salida de código de ejemplo

\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}

información relacionada