1

I am trying to define what is the rotation number of a vector field and for this I need to show the following graph (or one quite similar)

enter image description here

my attempt is as follows (I used as template the code given here): It is not very good I know that it can be improved from two aspects:

  1. The field is quite improvised trying to reach something similar
  2. I would also like to graph fields in the plane as F(x,y)=(P(x,y),Q(x,y)) like this.
\documentclass[border=5mm,tikz]{standalone}
\usetikzlibrary{calc}

\begin{document}
\begin{tikzpicture}[declare function={f(\x,\y)=\x*\y-3*tan(\x+\y);}]
\def\xmax{3} \def\xmin{-3}
\def\ymax{3} \def\ymin{-3}
\def\nx{15}  \def\ny{15}

\pgfmathsetmacro{\hx}{(\xmax-\xmin)/\nx}
\pgfmathsetmacro{\hy}{(\ymax-\ymin)/\ny}
\foreach \i in {0,...,\nx}
\foreach \j in {0,...,\ny}{
\pgfmathsetmacro{\yprime}{f({\xmin+\i*\hx},{\ymin+\j*\hy})}
\draw[gray,-stealth,shift={({\xmin+\i*\hx},{\ymin+\j*\hy})}] (0,0)--(.1,.1*\yprime);
}

%\draw[->] (\xmin-.5,0)--(\xmax+.5,0) node[below right] {$x$};
%\draw[->] (0,\ymin-.5)--(0,\ymax+.5) node[above left] {$y$};

\draw[red,line width = 1 pt]
    (-2,2) .. controls + (-1,0) and +(-0.5,0) ..
    (-1,-1) .. controls + (1,0) and + (-0.2,0) ..
    (1,-2) .. controls + (0.2,0) and + (2,0) ..
    (2,1) .. controls + (-2,0) and + (1,0) ..
    (-2,2) -- cycle;

\end{tikzpicture}
\end{document}

Output: enter image description here

3
  • I guess the code of your MWE from this link tex.stackexchange.com/questions/471741/… Please cite that link for the flow of info on codes that this forum aiming at, for convenience of other users.
    – Black Mild
    2 days ago
  • What does the red closed curve mean? 2 days ago
  • @NguyenVanChi1998 The red curve is simply a smooth closed curve that surrounds the origin, it could simply be a circle but as it is an example it is about giving any curve. I tried to do it with the Bezier curve without success.
    – Zaragosa
    2 days ago

2 Answers 2

2

When it comes to rotation numbers, it is not the size of the vectors in the field that matter, but only their directions. I therefore prefer to draw all vectors with the same length. For the arrows along the path, I suggest to have small disks in the background, since I think it makes it more clear when following the path to find the rotation number.

Below is an example done in MetaPost (which is what I have learned), but it can easily be translated into tikz/asymptote/pstricks. (The \startMPpage and \stopMPpage are only there for me to be able to run context on the file directly, and not really part of the figure.)

\startMPpage[offset=1dk]
s:=1.5cm ;

% This defines the vector field
vardef u(expr x,y) = (x*x*x*x-6*x*x*y*y+y*y*y*y) enddef ;
vardef v(expr x,y) = (4*x*x*x*y-4*x*y*y*y) enddef ;

% Vector plot of the vector field
% Note that the base points of the arrows are not at the foot but at the "stomach".
path tmparr ;
for x = -4 step 0.25 until 4 :
    for y = -4 step 0.25 until 4 :
        if ((x,y) = (0,0)):
        else:
            tmparr := (origin -- unitvector (u(x,y), v(x,y))) scaled 0.2s ;
            tmparr := tmparr shifted - center tmparr ;
            drawarrow  tmparr shifted ((x,y) scaled s) withcolor 0.8white;
        fi;
    endfor ;
endfor ;

% The red path
path p ; p = ((1,-2.5){up}..{dir 120}(3,2)..{dir -80}(-2,1)..(-2,-2)..cycle) scaled s ;
draw p withpen pencircle scaled 1 withcolor darkred ;

% The arrows along the path
numeric N ; N := 30 ;
pair tmpxy ;

for l = 1 upto N:
    tmpxy := point l/N along p ;
    tmparr := (origin -- unitvector (u(xpart tmpxy,ypart tmpxy), v(xpart tmpxy,ypart tmpxy))) scaled 0.3s ;
    tmparr := tmparr shifted - center tmparr ;
    fill (fullcircle scaled 0.3s) shifted tmpxy withcolor 0.9[darkblue,white];
    draw (fullcircle scaled 0.3s) shifted tmpxy withpen pencircle scaled 0.25 withcolor 0.3[darkblue,white] ;
    drawarrow tmparr shifted tmpxy withcolor darkblue ;
endfor ;

% Labeling the point
dotlabel.bot("$p$", origin) withpen pencircle scaled 3 ;

\stopMPpage

Output:

Vector plot with directions along a path

Update

With some modifications, here is a version that can be used on Troy's nice MetaPost preview page (I needed to do some small modifications, so not exactly the same):

s:=1.5cm ;

% This defines the vector field
vardef u(expr x,y) = (x*x*x*x-6*x*x*y*y+y*y*y*y) enddef ;
vardef v(expr x,y) = (4*x*x*x*y-4*x*y*y*y) enddef ;

% Vector plot of the vector field
% Note that the base points of the arrows are not at the foot but at the "stomach".
path tmparr ;
for x = -4 step 0.25 until 4 :
    for y = -4 step 0.25 until 4 :
        if ((x,y) = (0,0)):
        else:
            tmparr := (origin -- unitvector (u(x,y), v(x,y))) scaled 0.2s ;
            tmparr := tmparr shifted - center tmparr ;
            drawarrow  tmparr shifted ((x,y) scaled s) withcolor 0.8white;
        fi;
    endfor ;
endfor ;

% The red path
path p ; p = ((1,-2.5){up}..{dir 120}(3,2)..{dir -80}(-2,1)..(-2,-2)..cycle) scaled s ;
draw p withpen pencircle scaled 1 withcolor red ;

% The arrows along the path
numeric N ; N := 30 ;
numeric pL ; pL := arclength(p) ;
pair tmpxy ;


for l = 1 upto N:
    tmpxy := point (arctime (l/N)*pL of p) of p ;
    tmparr := (origin -- unitvector (u(xpart tmpxy,ypart tmpxy), v(xpart tmpxy,ypart tmpxy))) scaled 0.3s ;
    tmparr := tmparr shifted - center tmparr ;
    fill (fullcircle scaled 0.3s) shifted tmpxy withcolor 0.9[blue,white];
    draw (fullcircle scaled 0.3s) shifted tmpxy withpen pencircle scaled 0.25 withcolor 0.3[blue,white] ;
    drawarrow tmparr shifted tmpxy withcolor blue ;
endfor ;
4
  • Hello this was much more than I expected. I don't use that program, one question: can I use that same code to compile it online or do I have to download the program?
    – Zaragosa
    yesterday
  • I updated with a version that you can run onilne. I am so used to context, so I did not think of the fact that darkred and darkblue are not standard colors in metapost. I also forgot that point l/N along p is not standard either (perhaps in the metafun extension). Good luck!
    – mickep
    yesterday
  • Thank you very much I appreciate it a thousand times! Could you see this post? I think that with your method it would also come out, I have tried it without much success since I do not know much about the program.
    – Zaragosa
    yesterday
  • Yes, I've seen that, and I played a bit (works fine for some flows), but for streamplots one seem to need to code a bit more to get something that looks nice. Difficult to "compete with Mathematica". You could try with matplotlib in case you like that look of it.
    – mickep
    yesterday
1

Here is a TikZ solution. Define a pic which is an arrow of length \rotlen (I set at .5cm) in the direction of (1,f(x,y)). Then using foreach during the drawing of each segment of the curve, place the pic at each pos.

The calculation f(.03514*\yyy,.03514*\xxx) is to convert points to cm.

To add arrows to the original (red) path, use the decorations.markings library. I defined a style myarrow that takes a position argument, so adding myarrow=.8 to the \draw options will draw an arrow 80% along the curve. If you want to add more than one arrow, you have to add them in order. For example, \draw[red, line width = 1 pt, myarrow=.32, myarrow=.8] will add two arrows, one at position .32 and one at position .8 as shown. (Don't switch the order—it won't work.)

enter image description here

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{calc,decorations.markings}

\tikzset{perp/.pic={\path(0,0); \pgfgetlastxy{\xx}{\yy}\pgfmathsetmacro{\xxx}{\xx}\pgfmathsetmacro{\yyy}{\yy}
        \draw[blue,-stealth,thick](0,0)--($(0,0)!\rotlen!(1,{f(.03514*\yyy,.03514*\xxx)})$);},
    myarrow/.style={decoration={markings, mark=at position #1 with {\arrow{>}}}, postaction={decorate}},
    myarrow/.default={.5}}

\def\rotlen{.5cm}

\begin{document}
\begin{tikzpicture}[declare function={f(\x,\y)=\x*\y-3*tan(\x+\y);}]
\def\xmax{3} \def\xmin{-3}
\def\ymax{3} \def\ymin{-3}
\def\nx{15}  \def\ny{15}

\pgfmathsetmacro{\hx}{(\xmax-\xmin)/\nx}
\pgfmathsetmacro{\hy}{(\ymax-\ymin)/\ny}
\foreach \i in {0,...,\nx}
\foreach \j in {0,...,\ny}{
\pgfmathsetmacro{\yprime}{f({\xmin+\i*\hx},{\ymin+\j*\hy})}
\draw[gray,-stealth,shift={({\xmin+\i*\hx},{\ymin+\j*\hy})}] (0,0)--(.1,.1*\yprime);
}

%\draw[->] (\xmin-.5,0)--(\xmax+.5,0) node[below right] {$x$};
%\draw[->] (0,\ymin-.5)--(0,\ymax+.5) node[above left] {$y$};

\draw[red, line width = 1 pt, myarrow=.32, myarrow=.8]
    (-2,2) .. controls + (-1,0) and +(-0.5,0) ..
    (-1,-1)foreach \t in {0, 0.2, ..., .8} {pic [pos=\t] {perp} } .. controls + (1,0) and + (-0.2,0) ..
    (1,-2)foreach \t in {0, 0.2, ..., .8} {pic [pos=\t] {perp} } .. controls + (0.2,0) and + (2,0) ..
    (2,1)foreach \t in {0, 0.2, ..., .8} {pic [pos=\t] {perp} } .. controls + (-2,0) and + (1,0) ..
    (-2,2)foreach \t in {0, 0.2, ..., .8} {pic [pos=\t] {perp} };
\end{tikzpicture}
\end{document}
5
  • Beautiful solution! Thank you very much
    – Zaragosa
    yesterday
  • One question, how can I put a sense (for example counterclockwise) to the red curve?
    – Zaragosa
    23 hours ago
  • Adding an arrow to the middle of a curve requires the decorations.markings library. Give me a few minutes. I'll add it to my solution. It's too long for a comment.
    – Sandy G
    22 hours ago
  • @Zaragosa: I updated my solution.
    – Sandy G
    22 hours ago
  • (+1) Thank you!
    – Zaragosa
    22 hours ago

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.