Is there a way to use a colorscheme to a KnotData image?

One way is probably convert it to a parametric form and then use Colorfunction with ParametricPlot3D. The method is described in J.M.'s answer to How to create a new “person curve”?. Although it seems to have some problems with Trefoil.

Is there any simpler way to do this?

In summary, I want to use (say) Colorfunction->Hue with the output of KnotData["Trefoil"].

Using J.M.'s method

FourierCurve[x_, m_, t_, tol_: 0.01] := Module[{rat = Rationalize[#, tol] &, fc},
fc = Take[Chop[Fourier[x, FourierParameters -> {-1, 1}]],
       Min[m, Ceiling[Length[x]/2]]];
       2 rat[Abs[fc]].Cos[Pi (2 Range[0, Length[fc] - 1] t - rat[Arg[fc]/Pi])]]

{f[t_], g[t_], h[t_]} = FourierCurve[#, 20, t] & /@ 
  KnotData["FigureEight", "SpaceCurve"]["ValuesOnGrid"];

ParametricPlot3D[{f[t], g[t], h[t]}, {t, 0, 1}, Axes -> None, 
 Boxed -> False, Method -> {"TubePoints" -> 20}, 
 ColorFunction -> "Rainbow", ViewPoint -> Top] /. 
 Line[pts_, rest___] :> Tube[pts, 1/8, rest]

It works nicely with "FigureEight", "SolomonSeal", "Stevedore". (There is a small hole in the red region which can be fixed by adjusting the PlotRange).

enter image description here

When I try with "Trefoil", it returns

Fourier::fftl: Argument Sin[ValuesOnGrid]+2 Sin[2 ValuesOnGrid] is not a non-empty list or rectangular array of numeric quantities. >>

Using Tube works with the data, but coloring is not very flexible in that case.

Graphics3D[Tube[(KnotData["Trefoil", "SpaceCurve"][#]) 
                 & /@ Range[0, 2.1 Pi, Pi/50], 0.1]]

enter image description here

  • 1
    $\begingroup$ "it seems" - can you include a picture and corresponding code to show why you think it's unsatisfactory? $\endgroup$ – J. M.'s torpor Apr 13 '16 at 12:36
  • $\begingroup$ Thanks @J.M. for the comment. I often forget to put tea bag in my tea :) $\endgroup$ – Sumit Apr 13 '16 at 13:22
  • 1
    $\begingroup$ The reason it doesn't work on "Trefoil" is that actual trigonometric expressions are used for "SpaceCurve" instead of interpolating functions as with the other knots. $\endgroup$ – J. M.'s torpor Apr 13 '16 at 13:53
  • 1
    $\begingroup$ a way to color Tube is to use VertexColors: e.g., Graphics3D[ Tube[KnotData["Trefoil", "SpaceCurve"] /@ #, 0.1, VertexColors -> Hue /@ #]] &@Range[0, 2 Pi, Pi/50] $\endgroup$ – kglr Apr 13 '16 at 19:44

In this case, the KnotData evaluates directly to a parametric curve,

KnotData["Trefoil", "SpaceCurve"]
(* {Sin[#1] + 2 Sin[2 #1], Cos[#1] - 2 Cos[2 #1], -Sin[3 #1]} & *)

so that no sampling is necessary.

  KnotData["Trefoil", "SpaceCurve"][t], {t, 0, 2 \[Pi]}, 
  PlotRange -> All, Axes -> None, Boxed -> False, ViewPoint -> Top,
  ColorFunction -> "Rainbow"] /. 
 Line[pts_, rest__] :> Tube[pts, 1/8, rest]

enter image description here

Of course, this was true for "FigureEight" as well. But the difference is that "FigureEight" like many of the KnotData objects, is only stored as an interpolating function. Since "Trefoil" is not an interpolating function, it does not have the "ValuesOnGrid" property.

  • 1
    $\begingroup$ …and in fact the reason I used FourierCurve[] on all the other knots was precisely because I wanted simple(?) trigonometric expressions for them like with "Trefoil". $\endgroup$ – J. M.'s torpor Apr 13 '16 at 14:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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