2

I found a nice function to draw a nice ellipse between two points. However, I'd like to be able to use this ellipse as a border of a new node, so that if I draw an arrow towards this ellipse, it stops at the border. I tried to look at decoration but it didn't solve my problem...

MWE

\documentclass{report}

\usepackage{tikz}
\usetikzlibrary{arrows,backgrounds,positioning}
\usetikzlibrary{calc,math,fit,shapes}
\usetikzlibrary{decorations.pathmorphing}
\pgfdeclarelayer{bg}    % declare background layer
\pgfdeclarelayer{bgmain}    % declare background layer
\pgfsetlayers{bg,bgmain,main}  % set the order of the layers (main is the standard layer)

\usepackage{xcolor}

\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}
  \node(a) at (-1,1) {};
  \node(b) at (1,-1) {};
  \begin{pgfonlayer}{bg}
    \ellipsebyfoci{draw,fill=green!50}{a}{b}{1.5}
  \end{pgfonlayer}
  %% I want to point to the ellipse, not the points
  \node[label=east:Should point to the ellipse](c) at (3,-1) {};
  \draw[-latex] (c) -- (0,0);
\end{tikzpicture}


\end{document}

What I get: enter image description here

What I want: enter image description here

Thank you !

-- EDIT 01 -- I found a kind of solution that basically uses the fit package and the ellipse package. It produces a node, but it's not exactly following the exact ellipse shape of the above function:

\begin{tikzpicture}
  \node(a) at (-1,1) {a};
  \node(b) at (1,-1) {b};
  \node[rotate fit=45,fit=(a)(b),ellipse,fill=red!,opacity=.5](ell){};
  \node(x) at (3,2) {};
  \draw[->] (x) -- (ell);
  \node(y) at (-4,2) {};
  \draw[->] (y) -- (ell);
\end{tikzpicture}

enter image description here

And here is the general function for that:

\newcommand\fitEllipse[3]{% options, focus pt1, focus pt2
  \pgfmathanglebetweenpoints{\pgfpointanchor{#2}{center}}
  {\pgfpointanchor{#3}{center}}
 \edef\angle{\pgfmathresult} % save result in \angle 
  \node[rotate fit=\angle, fit=(#2)(#3),ellipse,#1]{};
}
  • Nice question! (+1) Do you insist on creating a node, or would a solution based on intersections also work? – marmot Feb 6 '18 at 23:14
1

A solution based on intersections.

\documentclass{report}

\usepackage{tikz}
\usetikzlibrary{arrows,backgrounds,positioning}
\usetikzlibrary{calc,math,fit,shapes,intersections}%<- added intersections
\usetikzlibrary{decorations.pathmorphing}
\pgfdeclarelayer{bg}    % declare background layer
\pgfdeclarelayer{bgmain}    % declare background layer
\pgfsetlayers{bg,bgmain,main}  % set the order of the layers (main is the standard layer)

\usepackage{xcolor}

\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}
  \node(a) at (-1,1) {};
  \node(b) at (1,-1) {};
  \begin{pgfonlayer}{bg}
    \ellipsebyfoci{draw,fill=green!50,name path=ellipse}{a}{b}{1.5}
  \end{pgfonlayer}
  %% I want to point to the ellipse, not the points
  \node[label=east:points to the ellipse](c) at (3,-1) {};
  \path[name path=connection] (c) -- ($(a)!0.5!(b)$);
  \draw [-latex, name intersections={of=ellipse and connection}] (c)--
    (intersection-1);;
\end{tikzpicture}

enter image description here

EDIT: Here comes your elliptic node.

\documentclass{report}

\usepackage{tikz}
\usetikzlibrary{arrows,backgrounds,positioning}
\usetikzlibrary{calc,math,fit,shapes,intersections}%<- added intersections
\usetikzlibrary{decorations.pathmorphing}
\pgfdeclarelayer{bg}    % declare background layer
\pgfdeclarelayer{bgmain}    % declare background layer
\pgfsetlayers{bg,bgmain,main}  % set the order of the layers (main is the standard layer)

\usepackage{xcolor}
\makeatletter % from https://tex.stackexchange.com/a/412901/121799
\newcommand{\Distance}[3]{% % from https://tex.stackexchange.com/q/56353/121799
\tikz@scan@one@point\pgfutil@firstofone($#1-#2$)\relax  
\pgfmathsetmacro{#3}{veclen(\the\pgf@x,\the\pgf@y)/28.45274}
}\makeatother 

% from https://tex.stackexchange.com/a/75084/121799
\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]{};
}

\newcommand\ellipticnode[5][]{% options, focus pt1, focus pt2, cste
 \pgfmathanglebetweenpoints{\pgfpointanchor{#2}{center}}
                            {\pgfpointanchor{#3}{center}}
 \edef\angle{\pgfmathresult} % save result in \angle 
 \Distance{(#2)}{(#3)}{\focal}
 \pgfmathsetmacro{\lentotcm}{\focal*#4}
 \pgfmathsetmacro{\axeone}{2*((\lentotcm - \focal)/2+\focal/2)}
 \pgfmathsetmacro{\axetwo}{2*(sqrt((\lentotcm/2)*(\lentotcm/2)-\focal*\focal/4)}
 \node at ($(#2)!.5!(#3)$) [shape=ellipse,minimum width=\axeone cm,minimum
 height=\axetwo cm, rotate=\angle,#1] (#5)
  {};
}

\begin{document}

\begin{tikzpicture}
  \node(a) at (-1,1) {};
  \node(b) at (1,-1) {};
  \begin{pgfonlayer}{bg}
    \ellipticnode[draw,fill=green!50]{a}{b}{1.5}{d}
  \end{pgfonlayer}
  \node[label=east:points to the ellipse](c) at (3,-1) {};
  \draw[->] (c)--(d);   
\end{tikzpicture}

enter image description here

  • That's a pretty good idea, so you got a (+1). Thank you! But if you find a way to set it as a node, you will be the kind of the day, because I need to create lot's of arrows like this ;-) (But if no answer are found, you'll be the accepted answer) – tobiasBora Feb 6 '18 at 23:26
  • @tobiasBora another possibility would be to compute the values in a macro and then draw the elliptic node. If no one else does it, I'll try later. – marmot Feb 6 '18 at 23:41
  • I could do it, but I did not found in the documentation how to define a custom node boundary (I think I missed the good page in the 1161 pages...) . If you point me to the good section/the good name of the functionality, I can try to do it! – tobiasBora Feb 6 '18 at 23:47
  • Hum, I just found tex.stackexchange.com/questions/294876/… (first solution). But if everything needs to be defined in pure pgf, it may be quite dirty to do... I may give it a try... – tobiasBora Feb 6 '18 at 23:53
  • @tobiasBora Just in case you didn't do it yourself, please have a look at my update. – marmot Feb 7 '18 at 1:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.