3

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]{};
}
1
  • Nice question! (+1) Do you insist on creating a node, or would a solution based on intersections also work?
    – user121799
    Feb 6, 2018 at 23:14

1 Answer 1

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

10
  • 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, 2018 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.
    – user121799
    Feb 6, 2018 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, 2018 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, 2018 at 23:53
  • @tobiasBora Just in case you didn't do it yourself, please have a look at my update.
    – user121799
    Feb 7, 2018 at 1:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .