Circumnavigating a curve or going through it to show different behavior

One way to detect crossings is to form a straight line between the previous position of the locator and the new position, and then check if there is an intersection between that straight line and $x^3$. I wrote this function to count the number of line intersection of a straight line with endpoints p1 and p2. The function which in this case is $x^3$ can be any function, and the interval which in this case is $0<x<1$ can be any interval.

SetAttributes[countIntersections, HoldFirst]
countIntersections[{f_, {xmin_, xmax_}}, p1_, p2_] := Module[{delta = p2 - p1, sol},
  If[p1 == p2, Return[0]];
  sol = Solve[{
     {x, f} == p1 + Normalize[delta] k,
     # < x < #2 & @@ Sort[{First[p1], First[p1 + delta]}],
     xmin < x < xmax,
     0 < k < Norm[delta]
     }, {x, k}];
  Length@sol
  ]

Just to emphasize how this work I built a little demo.

DynamicModule[{p1 = {0.5, 0.5}, p2 = {0.6, 0.5}},
 LocatorPane[
  Dynamic[{p1, p2}],
  Dynamic@Show[
    Plot[x^3, {x, 0, 1}],
    Graphics[{
      If[
       countIntersections[{x^3, {0, 1}}, p1, p2] == 0,
       Black,
       Red
       ],
      Line[{p1, p2}]
      }]
    ]
  ]
 ]

First demo

But of course for the real thing we don't have two locators. The second position is simply the previous position of the locator. Here's how that can be written:

DynamicModule[{p1 = {0.5, 0.5}, p2, plot, diskColor = Black},
 p2 = p1;
 LocatorPane[
  Dynamic[p1],
  Dynamic[
   If[
     countIntersections[{x^3, {0, 1}}, p1, p2] != 0,
     diskColor = diskColor /. {Red -> Black, Black -> Red}
     ]
    plot = Show[
      Plot[x^3, {x, 0, 1}],
      Graphics[{
        diskColor,
        Disk[{0.2, 1}, 0.08]
        }], AspectRatio -> 0.75, PlotRange -> {{0, 2}, {0, 1.5}}
      ];
   p2 = p1;
   plot
   ]
  ]
 ]

Second demo


I don't know how to handle parallel Events but if there is single Locator you can try this:

DynamicModule[{col = Blue, acc = 0, p = {1, 1}},
 EventHandler[
  Show[
   Graphics[{Dynamic@Disk[p, [email protected]]}],
   Plot[x^3, {x, 0, 1}] /. l_Line :> EventHandler[ l, {"MouseEntered" :> 
                   If[acc === 1, (col = col /. {Red -> Blue, Blue -> Red})]}]
   , Frame -> True, PlotRange -> {{0, 1.5}, {0, 1.5}}, 
   Epilog -> Inset[Graphics[Dynamic@{col, Disk[]}, ImageSize -> 30], {0.2, 1}]
   ],
  {"MouseDown" :> (acc = 1; p = MousePosition["Graphics"]), 
   "MouseDragged" :> (p = MousePosition["Graphics"]),
   "MouseUp" :> (acc = 0;)}, PassEventsDown -> True]
 ]

enter image description here

Do not move cursor too quickly :P

The order of things in Show is important. Our custom locator has to be under the border line.


Partial answer: this does not handle the going-around-the-curve bit.

 g1 = Graphics[{Blue, Table[Circle[{0, 0}, i], {i, 3}]}, ImageSize -> 20];
 g2 = Graphics[{Red, Table[Circle[{0, 0}, i], {i, 3}]},  ImageSize -> 20];

 DynamicModule[{pt = {0.1, 1}},
    Plot[x^3, {x, 0, 1}, PlotRange -> {{0, 1.5}, {0, 1.5}}, 
       Filling -> Bottom, Frame -> True, ImageSize -> 600,
       Epilog -> Dynamic@{
          If[Last[pt] < First[pt]^3, Blue, Red], PointSize[.05], Point[{.1, 1}],
          Locator[Dynamic[pt], If[Last[pt] < First[pt]^3, g1, g2]]}]]

enter image description here

enter image description here