从两个焦点(焦点)以及焦点到边界的距离之和绘制一个椭圆

从两个焦点(焦点)以及焦点到边界的距离之和绘制一个椭圆

我有两个想要的节点和焦点,并且我知道距离之和应该是多少(常数乘以焦点节点之间的距离)。

我所知道的绘制椭圆的方法是将中心点以及长轴和短轴作为参数。

我想定义另一个函数(myellipse?),它将两个节点和常数乘数作为参数。

这是我目前绘制它们的方式,手工进行所有计算(示例并不完美):

\draw [rotate around={-15:(1.8,0.5)}] (1.8,0.5) ellipse (2 and 1); 

答案1

第三次编辑:没有节点或记忆的更简单的解决方案......结果与第二次编辑相同(见下文) 但没有标签。

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}

\newcommand\ellipsebyfoci[4]{% options, focus pt1, focus pt2, cste
  \path[#1] let \p1=(#2), \p2=(#3), \p3=($(\p1)!.5!(\p2)$)
  in \pgfextra{
    \pgfmathsetmacro{\angle}{atan2(\y2-\y1,\x2-\x1)}
    \pgfmathsetmacro{\focal}{veclen(\x2-\x1,\y2-\y1)/2/1cm}
    \pgfmathsetmacro{\lentotcm}{\focal*2*#4}
    \pgfmathsetmacro{\axeone}{(\lentotcm - 2 * \focal)/2+\focal}
    \pgfmathsetmacro{\axetwo}{sqrt((\lentotcm/2)*(\lentotcm/2)-\focal*\focal}
  }
  (\p3) ellipse[x radius=\axeone cm,y radius=\axetwo cm, rotate=\angle];
}

\begin{document}
\begin{tikzpicture}
  \coordinate (a) at (0,0);
  \coordinate (b) at (5,3);
  \ellipsebyfoci{draw,fill=cyan!50}{a}{b}{1.4}
  \begin{scope}
    \ellipsebyfoci{clip}{a}{b}{1.4}
    \ellipsebyfoci{draw,fill=orange!50,name=ell 2}{0,0}{3,5}{1.05}
    \fill[red] (a) circle(2pt);
    \fill[red] (b) circle(2pt);
  \end{scope}
\end{tikzpicture}
\end{document}

第二次编辑:以下是一个带有裁剪椭圆示例的解决方案(使用我的答案在 tikz 中绘制缩放多边形的最佳方法只是为了记住椭圆节点的路径)。

在此处输入图片描述

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{shapes.geometric,decorations.pathreplacing}

\makeatletter
% to produce automaticaly homothetic paths
\newcounter{homothetypoints} % number of vertices of path
\tikzset{
  % homothety is a family...
  homothety/.style={homothety/.cd,#1,/tikz/.cd},
  % ...with some keys
  homothety={
    % parameters
    scale/.store in=\homothety@scale,% scale of current homothetic transformation
    center/.store in=\homothety@center,% center of current homothetic transformation
    name/.store in=\homothety@name,% prefix for named vertices
    % default values
    scale=1,
    center={0,0},
    name=homothety,
    % initialization
    init memoize homothetic path/.code={
      \xdef#1{}
      \setcounter{homothetypoints}{0}
    },
    % incrementation
    ++/.code={\addtocounter{homothetypoints}{1}},
    % a style to store an homothetic transformation of current path into #1 macro
    store in/.style={
      init memoize homothetic path=#1,
      /tikz/postaction={
        decorate,
        decoration={
          show path construction,
          moveto code={
            % apply homothetic transformation to this segment and add result to #1
            \xdef#1{#1 ($(\homothety@center)!\homothety@scale!(\tikzinputsegmentfirst)$)}
            % name this vertex
            \coordinate[homothety/++](\homothety@name-\arabic{homothetypoints})
            at ($(\homothety@center)!\homothety@scale!(\tikzinputsegmentfirst)$);
          },
          lineto code={
            % apply homothetic transformation to this segment and add result to #1
            \xdef#1{#1 -- ($(\homothety@center)!\homothety@scale!(\tikzinputsegmentlast)$)}
            % name this vertex
            \coordinate[homothety/++] (\homothety@name-\arabic{homothetypoints})
            at ($(\homothety@center)!\homothety@scale!(\tikzinputsegmentlast)$);
          },
          curveto code={
            % apply homothetic transformation to this segment and add result to #1
            \xdef#1{#1
              .. controls ($(\homothety@center)!\homothety@scale!(\tikzinputsegmentsupporta)$)
              and ($(\homothety@center)!\homothety@scale!(\tikzinputsegmentsupportb)$)
              .. ($(\homothety@center)!\homothety@scale!(\tikzinputsegmentlast)$)}
            % name this vertex
            \coordinate[homothety/++] (\homothety@name-\arabic{homothetypoints})
            at ($(\homothety@center)!\homothety@scale!(\tikzinputsegmentlast)$);
          },
          closepath code={
            % apply homothetic transformation to this segment and add result to #1
            \xdef#1{#1 -- cycle ($(\homothety@center)!\homothety@scale!(\tikzinputsegmentlast)$)}
          },
        },
      },
    },
  },
}
\makeatother

\newcommand\ellipsebyfoci[4]{% options, focus pt1, focus pt2, cste
  \path let \p1=(#2), \p2=(#3), \p3=($(\p1)!.5!(\p2)$)
  in \pgfextra{
    \pgfmathsetmacro{\angle}{atan2(\y2-\y1,\x2-\x1)}
    \pgfmathsetmacro{\focal}{veclen(\x2-\x1,\y2-\y1)/2/1cm}
    \pgfmathsetmacro{\lentotcm}{\focal*2*#4}
    \pgfmathsetmacro{\axeone}{(\lentotcm - 2 * \focal)/2+\focal}
    \pgfmathsetmacro{\axetwo}{sqrt((\lentotcm/2)*(\lentotcm/2)-\focal*\focal}
  }
  (\p3) node[#1,inner sep=0,rotate=\angle,ellipse,minimum width=2*\axeone cm,minimum height=2*\axetwo cm]{};
}

\begin{document}
\begin{tikzpicture}
  \coordinate (a) at (0,0);
  \coordinate (b) at (5,3);
  \ellipsebyfoci{draw,fill=cyan!50,name=ell 1,homothety={store in=\mypath}}{a}{b}{1.4}
  \node[fill=white] at (ell 1.south){1.4};
  \begin{scope}
    \clip \mypath;
    \ellipsebyfoci{draw,fill=orange!50,name=ell 2}{0,0}{3,5}{1.05}
    \node[fill=white] at (ell 2.south){1.05};
    \fill[red] (a) circle(2pt);
    \fill[red] (b) circle(2pt);
  \end{scope}
\end{tikzpicture}
\end{document}

第一次编辑:这是一个解决方案持续的 乘数按要求 (请参阅下文解释)。

在此处输入图片描述

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{shapes.geometric}
\begin{document}

\newcommand\ellipsebyfoci[4]{% options, focus pt1, focus pt2, cste
  \path let \p1=(#2), \p2=(#3), \p3=($(\p1)!.5!(\p2)$)
  in \pgfextra{
    \pgfmathsetmacro{\angle}{atan2(\y2-\y1,\x2-\x1)}
    \pgfmathsetmacro{\focal}{veclen(\x2-\x1,\y2-\y1)/2/1cm}
    \pgfmathsetmacro{\lentotcm}{\focal*2*#4}
    \pgfmathsetmacro{\axeone}{(\lentotcm - 2 * \focal)/2+\focal}
    \pgfmathsetmacro{\axetwo}{sqrt((\lentotcm/2)*(\lentotcm/2)-\focal*\focal}
  }
  (\p3) node[#1,inner sep=0,rotate=\angle,ellipse,minimum width=2*\axeone cm,minimum height=2*\axetwo cm]{};
}

\begin{tikzpicture}
  \coordinate (a) at (0,0);
  \coordinate (b) at (5,3);
  \ellipsebyfoci{draw,fill=cyan!50,name=ell 1}{a}{b}{1.4}
  \node[fill=white] at (ell 1.south){1.4};
  \ellipsebyfoci{draw,fill=orange!50,name=ell 2}{a}{b}{1.05}
  \node[fill=white] at (ell 2.south){1.05};
  \fill[red] (a) circle(2pt);
  \fill[red] (b) circle(2pt);
\end{tikzpicture}
\end{document}

第一个答案:这是一个节点形状为椭圆的解决方案(通过shapes.geometric库)。

\ellipsebyfoci使用四个参数定义宏:

  1. 椭圆的选项(绘制、填充等),
  2. 第一焦点点,
  3. 第二焦点点,
  4. 焦点和边界之间的距离总和。

所有计算均以厘米为单位以避免溢出(! Dimension too large.)。

在此处输入图片描述

代码:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{shapes.geometric}

\newcommand\ellipsebyfoci[4]{% options, focus pt1, focus pt2, sum
  \path let \p1=(#2), \p2=(#3), \p3=($(\p1)!.5!(\p2)$)
  in \pgfextra{
    \pgfmathsetmacro{\angle}{atan2(\y2-\y1,\x2-\x1)}
    \pgfmathsetmacro{\focal}{veclen(\x2-\x1,\y2-\y1)/2/1cm}
    \pgfmathsetmacro{\lentotcm}{#4/1cm}
    \pgfmathsetmacro{\axeone}{(\lentotcm - 2 * \focal)/2+\focal}
    \pgfmathsetmacro{\axetwo}{sqrt((\lentotcm/2)*(\lentotcm/2)-\focal*\focal}
  }
  (\p3) node[#1,inner sep=0,rotate=\angle,ellipse,minimum width=2*\axeone cm,minimum height=2*\axetwo cm]{};
}

\begin{document}
\begin{tikzpicture}
  \coordinate (a) at (0,0);
  \coordinate (b) at (7,3);

  \fill[red] (a) circle(2pt);
  \fill[red] (b) circle(2pt);

  \ellipsebyfoci{draw,fill=orange,fill opacity=.1}{a}{b}{8cm}
\end{tikzpicture}
\end{document}

答案2

我得到了我想要的东西!但不确定是否有更好的方法……

\makeatletter   
\newcommand*{\myellipse}[3]{
  % Bigger axis: #3
  % Smaller axis: sqrt([#3]ˆ2 - |uv|ˆ2)
  \coordinate (midpoint) at ($(#1)!0.5!(#2)$) {};

  % Calculate angle
  \pgfmathanglebetweenpoints{\pgfpointanchor{#1}{center}}
                            {\pgfpointanchor{#2}{center}}
  \let\angle\pgfmathresult % save result in \angle 


  % calculate distance
  \pgfpointdiff{\pgfpointanchor{#1}{center}}
               {\pgfpointanchor{#2}{center}}
  \pgf@xa=\pgf@x % no need to use a new dimen
  \pgf@ya=\pgf@y
  \pgfmathparse{veclen(\pgf@xa,\pgf@ya)/28.45274} %  to convert from                      % pt to cm 
  \let\uv\pgfmathresult % save the result in \uv

  \draw [rotate around={\angle:(midpoint)}] 
        (midpoint) ellipse ({#3} and {sqrt((#3)*(#3) - (\uv)*(\uv))}); 
}
\makeatother   

答案3

这个例子不是一个完整的答案,而只是 Tikz 工具对椭圆逐点计算的概述,这当然不是最佳的

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{intersections}

\begin{document}
\begin{tikzpicture}

\begin{scope}[rotate=15]
\def\entraxe{200}
\draw (0,0)coordinate(A) -- (\entraxe/100,0)coordinate(B);
\foreach \rr in {101,102,103,...,299}{
\path[red,name path =circleA] (A) circle (\rr/100);
\path[blue,name path =circleB] (B) circle ({(400-\rr)/100});
\path[dashed,name intersections={of=circleA and circleB}];
\draw (intersection-1) circle (0.01cm);
\draw (intersection-2) circle (0.01cm);
}
\end{scope}

\end{tikzpicture}
\end{document}

在此处输入图片描述

相关内容