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]
]
Graphics[arrowHead[{1, 1}, Pi/2, 1]]

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}]
