# Controlling the motion of points in an animation

I am looking for a better way to show this behavior on a pressure-composition diagram for immiscible liquids (two black dots show behavior at different x-positions, only one is present otherwise): The piston (right) is moved with a slider and that controls the y-position of the black dot location. Whenever the black dot passes through the purple horizontal line or blue, orange, and magenta dots, the black dot needs to stay at that position for a while (until one of the phases is vaporized) before moving again.

The way I've accomplished this for this and similar demonstrations is inefficient and buggy. Here is what I used for this one:

Controls

Control[{{comp, 0.3, "benzene composition"},
If[(step == 2 ∨ step == 10), 0.01, 0],
If[(step == 2 ∨ step == 10), 0.99, 1], 0.01,
Appearance -> "Labeled",
Enabled ->
If[step == 1 ∨ step == 11 ∨ step == 3 ∨ step == 13,
False, True]}],
Control[{{pistonheight, 0.1, "piston height"}, 0.1, 6.5, 0.01}],
Button["reset to initial conditions", {comp = 0.3, pistonheight = 0.1,
location = 0, step = 0}],
Control[{{location, 0}, None}],
Control[{{step, 0}, 0, 14, None}]


Code that sets the y-position of the black dot location

height = 6.5 - pistonheight;
P1 = height + 1;
P2 = height;

stop[loc_] := P2 <= loc ∧ P1 > loc;
phase = Piecewise[{{Py2[comp], 0 <= comp <= xp}, {Py1[comp], xp < comp <= 1}}];


Mess

If[0 < comp < 1, {
If[(step == 0 ∨ step == 10) ∧ P2 > P, {location = P2,
step = 0}],
If[(step == 0 ∨ step == 2) ∧ stop[P], {location = P,
step = 10}],
If[(step == 4 ∨ step == 10) ∧
stop[P] ∧ (Abs[phase - P] <= 0.2), {location = P,
step = 14}],
If[step == 14, location = P],
If[step == 14 ∧ P1 < P, {location = P1, step = 2}],
If[
step == 14 ∧
P2 > P ∧ (Abs[phase - P] <= 0.2), {location = P2, step = 0}],
If[step == 10, location = P],
If[(step == 10 ∨ step == 4) ∧
phase <= P1 < P, {location = P1, step = 2}],
If[step == 2, location = P1],
If[step == 2 ∧ P1 < phase, {location = P1, step = 4}],
If[step == 4, location = P1]
}];

If[comp == 0 ∨ comp == 1, {
If[(step == 0 ∨ step == 1 ∨ step == 3) ∧
P2 > P, {location = P2, step = 0}],
If[(step == 0 ∨ step == 11 ∨ step == 13) ∧
phase < P2 <= P, {location = P2,
If[comp == 0, step = 1, step = 3]}],
If[(step == 1 ∨ step == 3), location = P2],
If[(step == 1 ∨ step == 3 ∨ step == 4) ∧
stop[phase], {location = phase,
If[comp == 0, step = 11, step = 13]}],
If[(step == 11 ∨ step == 13) ∧ P1 < phase, {location = P1,
step = 4}],
If[step == 4, location = P1]
}];


The idea with this code was also to be able to define regions. There has to be a better way to accomplish this because what I currently am doing is impractical.

Perhaps something like this:

point[y_] := {y - 5, 10, y + 5}
point2[y_] := {y - 5, 30, y + 5}

activePoint[pts : {_, _, _}] := Sort[pts][]

Manipulate[Graphics[{
Thick, PointSize[Large],
Darker@Green,
Line[{{0, 10}, {40, 10}}],
Point[{10, activePoint[point[y]]}],
Darker@Blue,
Line[{{0, 30}, {40, 30}}],
Point[{30, activePoint[point2[y]]}]
}, PlotRange -> {{0, 40}, {0, 40}}], {y, 0, 40}] 