4
$\begingroup$

I'm trying to make the complicated ParametricPlot3D curve rotate along the z-axis smoothly. I tried Rotate on a simple 3D object first.

Manipulate[Graphics3D[Rotate[Cuboid[], y, {0, 0, 1}], Boxed -> False], {y, 0, 180 Degree}]

It works fine. But it does not work on the ParametricPlot3D curve, because "Graphics3DBox is not a Graphics3D primitive or directive.".

Then I tried RotationMatrix on ParametricPlot3D curve and it works correctly on simple curves.

Manipulate[ParametricPlot3D[RotationMatrix[\[Theta], {x, y, z}] . {Cos[t], Sin[t], t/10}, {t, 0,10}, PlotRange -> All, AxesLabel -> {"X", "Y", "Z"}], {{\[Theta], 0}, 0, 2   \[Pi]}, {{x, 0}, -1, 1}, {{y, 0}, -1, 1}, {{z, 1}, -1, 1}]

But when the curve becomes complicated, it rotates slowly or ugly.

Manipulate[ParametricPlot3D[RotationMatrix[mm, {x, y, z}] . {Cos[t]  (3 + r  Cos[t/2]), Sin[t]  (3 + r  Cos[t/2]), r  Sin[t/2]}, {r, -1, 1}, {t, 0, 2  Pi}, Mesh -> {5, 10}, PlotStyle -> FaceForm[Red, Yellow], PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}], {{mm, 0}, 0, 2   \[Pi], \[Pi]/20}, {{x, 0}, -1, 1}, {{y, 0}, -1, 1}, {{z, 1}, -1,1}]

Is it possible to make the rotation faster without deformation, like when we drag the object using the mouse?

$\endgroup$
1
  • 1
    $\begingroup$ Precompute all needed arrangements of your plot into a table and then use Manipulate to display particular item of the table. $\endgroup$ Commented Mar 21 at 13:03

4 Answers 4

7
$\begingroup$

The use of Dynamic below keeps the ParametricPlot from reevaluating, which leads to smooth behavior:

Manipulate[
 MapAt[
  Dynamic@Rotate[#, mm, {x, y, z}] &, 
  ParametricPlot3D[{Cos[t]   (3 + r   Cos[t/2]), 
    Sin[t]   (3 + r   Cos[t/2]), r   Sin[t/2]}, {r, -1, 1}, {t, 0, 
    2   Pi}, Mesh -> {5, 10}, PlotStyle -> FaceForm[Red, Yellow], 
   PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}],
  1]
 , {{mm, 0}, 0, 2    \[Pi], \[Pi]/20}, {{x, 0}, -1, 1}, {{y, 0}, -1, 
  1}, {{z, 1}, -1, 1}]
$\endgroup$
6
$\begingroup$
plot = ParametricPlot3D[{Cos[t] (3 + r Cos[t/2]), 
    Sin[t] (3 + r Cos[t/2]), r Sin[t/2]}, {r, -1, 1}, {t, 0, 2 Pi}, 
   Mesh -> {5, 10}, PlotStyle -> FaceForm[Red, Yellow], 
   PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}];
table = Table[
   Graphics3D[
    GeometricTransformation[plot[[1]], 
     RotationTransform[fi, {0, 1, 0}]], plot[[2]]], {fi, 0, 
    2 Pi, Pi/21}];
Manipulate[table[[i]], {i, 1, Length[table], 1}]

enter image description here

$\endgroup$
5
$\begingroup$

You just need to precompute your transformed curve! Otherwise, the transformation matrix and the dot product are recomputed every time you change the parameters, which is very computationally expensive.

curve[m_, x_, y_, z_] = 
 Refine[RotationMatrix[m, {x, y, z}], {x, y, z} ∈ 
     Reals] . {Cos[t] (3 + r Cos[t/2]), Sin[t] (3 + r Cos[t/2]), 
    r Sin[t/2]} // Simplify

Manipulate[
 ParametricPlot3D[
  Evaluate@curve[mm, x, y, z], {r, -1, 1}, {t, 0, 2 Pi}, 
  Mesh -> {5, 10}, PlotStyle -> FaceForm[Red, Yellow], 
  PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}], {{mm, 0}, 0, 
  2 π, π/20}, {{x, 0}, -1, 1}, {{y, 0}, -1, 1}, {{z, 1}, -1, 1}]
$\endgroup$
5
$\begingroup$

Edit

  • Or only use Evaluate and PerformanceGoal -> "Quality".
Manipulate[
 ParametricPlot3D[
  RotationMatrix[mm, {x, y, z}] . {Cos[t]    (3 + r    Cos[t/2]), 
     Sin[t]    (3 + r    Cos[t/2]), r    Sin[t/2]} // 
   Evaluate, {r, -1, 1}, {t, 0, 2    Pi}, Mesh -> {5, 10}, 
  PlotStyle -> FaceForm[Red, Yellow], 
  PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, 
  PerformanceGoal -> "Quality"], {{mm, 0}, 0, 
  2     π, π/20}, {{x, 0}, -1, 1}, {{y, 0}, -1, 
  1}, {{z, 1}, -1, 1}]

Original

  • Use First to ParametricPlot3D to extract the graphics data and use GeometricTransformation to act on such object.

  • Set PerformanceGoal -> "Quality" in ParametricPlot3D.

Manipulate[
 Graphics3D[
  GeometricTransformation[
   First@ParametricPlot3D[{Cos[t]   (3 + r   Cos[t/2]), 
      Sin[t]   (3 + r   Cos[t/2]), r   Sin[t/2]}, {r, -1, 1}, {t, 0, 
      2   Pi}, Mesh -> {5, 10}, PlotStyle -> FaceForm[Red, Yellow], 
     PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, 
     PerformanceGoal -> "Quality"], 
   RotationTransform[mm, {x, y, z}]]], {{mm, 0}, 0, 
  2    π, π/20}, {{x, 0}, -1, 1}, {{y, 0}, -1, 
  1}, {{z, 1}, -1, 1}]
$\endgroup$

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.