Start with the following parametric equations of a torus:

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_}}] := 
     {θ = 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:

   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?

   {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.


2 Answers 2

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

enter image description here


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

With[{R = 2, r = 1},
                     Graphics3D[{Red, PointSize[Large], 
                                 Point[{(R + r Cos[ϕ]) Cos[θ],
                                        (R + r Cos[ϕ]) Sin[θ], r Sin[ϕ]}]}]], 
                Row[{Control[{{θ, 0}, Experimental`AngularSlider[Dynamic[θ]] &}],
                     Control[{{ϕ, 0}, Experimental`AngularSlider[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]]

Manipulate for torus

  • $\begingroup$ 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. $\endgroup$
    – murray
    Mar 11, 2019 at 22:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.