# Vector field on the circle

I am trying to plot a vector field on the circle, something like:

Here I have periodic function $f(\theta)$, such that $f(\theta + 2\pi) = f(\theta)$. The arrows on the circle should point in the direction corresponding to the sign of $f(\theta)$. The figure shows a particularly simple example where $f(\theta)$ has a constant sign.

• $f$ is always real-valued? – J. M.'s ennui Mar 13 '18 at 16:00
• @J.M. Yes, $f(\theta)$ is always real valued and periodic. You can also assume it is smooth. – becko Mar 13 '18 at 16:15

Here is a start. Define a function that gives you a nice arrow based on position, the direction it should look at and a size. This can be done by transforming the coordinates

arrowHead[p_, dir_, size_] :=
With[{pts =
size*{{-1/4, 0}, {-1/2, -1/3}, {1/2, 0}, {-1/2,
1/3}}.RotationMatrix[-dir]},
Polygon[p + # & /@ pts]
]



The most simple solution is now to create a table of angles where you want to plot the arrows. For each angle you calculate the Sign and use it to calculate the arrow direction. Then draw a circle and over it all the arrows:

f = Sin;
Graphics[
{Thick, Circle[],
arrowHead[{Cos[#1], Sin[#1]}, #2, .2] & @@@
Table[{phi, phi + Pi/2*Sign[f[phi]]}, {phi, 0, 2 Pi - Pi/5, Pi/5}]
}]


When the Sign is 0, then the arrows will point outwards.

Depending on your real function f, you might want to consider to analyze the regions of angles, where f has the same Sign. You can then put exactly one arrow directly in the middle. This might be preferable to using a fixed sampling of arrows.

What I mean by that is the following. Assume f to be

f = Sin[#] + 2 Sin[2 #] &
Plot[f[x], {x, 0, 2 Pi}]


If you find the roots of your f, you can create the ranges. For the given f, this can be done by

ranges = Partition[
Sort[N@Values[Flatten[Solve[f[x] == 0 && 0 <= x <= 2 Pi, x]]]], 2, 1]
(* {{0., 1.82348}, {1.82348, 3.14159}, {3.14159, 4.45971}, {4.45971, 6.28319}} *)


Now we can calculate the middle point inside each range and create a nice colored circle that has only one arrow for each range

inspectRange[f_, {min_, max_}] :=
Module[{m = Mean[{min, max}], s, col},
s = Sign[f[m]];
col = Switch[s, -1, ColorData[96, 1], 1, ColorData[96, 2], _, Black];
{col, Circle[{0, 0}, 1, {min, max}],
arrowHead[{Cos[m], Sin[m]}, m + Pi/2*s, .2]}
]

Graphics[{Thickness[.02], Circle[], Thickness[.01],
inspectRange[f, #] & /@ ranges}]


myArrow[θ_, h_] :=