Draw an ellipse from the two focus points (foci) and the sum of the distances from foci to border
Third Edit: A simpler solution without node or memoization... The result is the same as the second edit (see below) but without labels.
\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}
Second Edit: Here is a solution with an example of clipped ellipse (using my answer to Best way to draw scaled polygons in tikz just to memoize path of ellipse node).
\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}
First Edit: Here is a solution with the constant multiplier as required (see below for explanations).
\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}
First answer: Here is a solution with a node shaped as ellipse (via shapes.geometric
library).
I define the \ellipsebyfoci
macro with four arguments:
- options for the ellipse (to draw it, to fill it, etc.),
- first focus pt,
- second focus pt,
- sum of distance between foci and border.
All calculations are in centimeters to avoid overflows (! Dimension too large.
).
The code:
\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}
I got what I wanted! Not sure if there is a better way to do it though...
\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
this example is not a complete answer but just an outline of a point by point calculation of the ellipse from Tikz tools, this is certainly not optimal
\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}