# Manipulate with arguments points on a circle

R = 2; r = 1;
x3[ϕ_, θ_] := (r Cos[ϕ] + R) Cos[θ]
y3[ϕ_, θ_] := (r Cos[ϕ] + R) Sin[θ]
z3[ϕ_, θ_] := r Sin[ϕ]


I construct a function f whose inputs of interest will be pairs {{s, t}, {u, v}} of points on the circle of radius 1 centered at the origin in the plane, that is, on Circle[]. Like this:

f[{{s_, t_}, {u_, v_}}] :=
Module[
{θ = ArcTan[s, t], ϕ = ArcTan[u, v]},
{x3[ϕ, θ], y3[ϕ, θ], z3[ϕ, θ]}
]


(The values of f at such points should turn out to be points on the torus.)

So as to display values of f dynamically for such points, I would like to do something like the following, with a pair of controls:

Manipulate[
f[{{s, t}, {u, v}}],
{s, t} ∈ Circle[], {u, v} ∈ Circle[]
]


Of course that's nonsense: the manipulate arguments are not of the correct form for variable specification.

What's the simplest way to accomplish that without faking it by parameterizing the circle first, as in the following?

Manipulate[
{u, v} = {Cos[ϕ], Sin[ϕ]};
{s, t} = {Cos[θ], Sin[θ]};
f[{{s, t}, {u, v}}],
{θ, 0, 2 π}, {ϕ, 0, 2 π}
]


Could it be done, for example, by using as controls two locators, one for each of the two copies of the circle?

I am aware of Constrain Locator to specified region. However, in that post the variable is in a region, whereas a circle is not a region as I understand the term.

Manipulate[Column[{Row[{Graphics[{Red, PointSize[Large], Circle[],
Locator[Dynamic[pt1, (pt1 = Normalize[#]) &]], Text[Round[pt1, .01], {0, 1.5}]}],
Graphics[{Blue, PointSize[Large], Circle[],
Locator[Dynamic[pt2, (pt2 = Normalize[#]) &]], Text[Round[pt2, 0.01], {0, 1.5}]}]},
Spacer[20]],
Show[ParametricPlot3D[{Cos[t] (R + Cos[u]), Sin[t] (R + Cos[u]), Sin[u]},
{t, 0, 2 Pi}, {u, 0, 2 Pi},
Mesh -> None, PlotStyle -> Opacity[.4],
PlotLabel -> Style[Row[{"f[{pt1, pt2}] =", f[{pt1, pt2}]}], 16],
ImageSize -> 400],
Graphics3D[{Red, PointSize[Large], Point[f[{pt1, pt2}]]}]]},
Dividers -> Center, Alignment -> Center],
{{pt1, {Cos[0], Sin[0]}}, None}, {{pt2, {Cos[Pi], Sin[Pi]}}, None}]


As an alternative to kglr's take, here is how one can use ExperimentalAngularSlider[] inside Manipulate[]:

With[{R = 2, r = 1},
Manipulate[Show[torus,
Graphics3D[{Red, PointSize[Large],
Point[{(R + r Cos[ϕ]) Cos[θ],
(R + r Cos[ϕ]) Sin[θ], r Sin[ϕ]}]}]],
Row[{Control[{{θ, 0}, ExperimentalAngularSlider[Dynamic[θ]] &}],
Spacer[20],
Control[{{ϕ, 0}, ExperimentalAngularSlider[Dynamic[ϕ]] &}]}],
Initialization :> (torus =
ParametricPlot3D[{(R + Cos[u]) Cos[t], (R + Cos[u]) Sin[t], Sin[u]},
{t, 0, 2 π}, {u, 0, 2 π}, Mesh -> None,
PlotStyle -> Opacity[.4], ImageSize -> 400];),
SaveDefinitions -> True]]


• Except that it's using an Experimental` context function, I find this more evocative of what's going on -- about points rotating around each of the two circles. – murray Mar 11 at 22:06