두 개의 초점 좌표 $(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
실제로 이 작업을 수행하는 (다소) 쉬운 방법이 있습니다. 원점을 중심으로 하는 쌍곡선의 표준 매개변수화를 사용하고 초점이 원하는 위치에 놓이도록 회전하고 이동하기만 하면 됩니다.
유일한 문제는 PGFplot 좌표에 아핀 변환을 적용하는 것이 내장되어 있지 않다는 것입니다. 하지만 고맙게도 질문은 다음과 같습니다.pgfplots에서 아핀 좌표 변환을 어떻게 수행할 수 있나요?이에 대한 매우 좋은 솔루션을 제공합니다. 기본 벡터 대신 각도를 사용하도록 조정했습니다.
shift
TikZ에서 제공하는 및 키를 사용하여 원점을 중심으로 하는 것처럼 쌍곡선에 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는 있지만 PGFPlot은 없는 대체 솔루션입니다. 기본 아이디어는 Fritz의 답변과 동일합니다: 회전 및 이동. 매개변수화는 사용자가 ( )의 비율을 지정하는 것과 같습니다. 여기서 는 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}