# How to mesh two ParametricPlot3D function and change the line to cuboid

Show[ParametricPlot3D[{Sin[u], Cos[u], u}, {u, 0, 2},
PlotStyle -> Directive[Red, Thick], PlotRange -> All],
ParametricPlot3D[{2 Sin[u], 2 Cos[u], u}, {u, 0, 2},
PlotStyle -> Directive[Black, Thick], PlotRange -> All]]


Hi experts,

1) How to make the line be replaced with cuboid so that we can see how it's twisted? I did replace the line with tube, but I cant see how the line is twisted:

2) What if we want to mesh the two lines with seperate ParametricPlot3D as shown above (This is just an example)?

• What do you mean by "twisted"? Do you want to visualize the Frenet frame? Apr 27, 2018 at 6:08
• Instead of visualize Frenet Frame, how i wish is to enlarge the curve (in cuboid shape) to see how the curve is twisted.
– VTeh
Apr 27, 2018 at 6:13
• The method in this answer can be used as well. Oct 12, 2018 at 2:12
• Possible duplicate: mathematica.stackexchange.com/questions/69831/… Oct 12, 2018 at 10:36

Maybe this is what you ask for. It used the Frenet frame of a curve in order to map the corners of a square into $$\mathbb{R}^3$$. Afterwards, these points are connected to form a tube with rectangular cross section.

curve = t \[Function] {Sin[t], Cos[t], t};
tangent = t \[Function] Evaluate[Simplify[curve'[t]/Sqrt[curve'[t].curve'[t]]]];
normal = t \[Function] Evaluate[Simplify[tangent'[t]/Sqrt[tangent'[t].tangent'[t]]]];
binormal = t \[Function] Evaluate[Cross[tangent[t], normal[t]]];

crosssection0 = radius {{1, 1}, {-1, 1}, {-1, -1}, {1, -1}};
crosssection = t \[Function] Evaluate[crosssection0.{normal[t], binormal[t]}];
tlist = Subdivide[0., 2. Pi, 1000];

pts = Flatten[Plus[
Transpose[
ConstantArray[curve /@ tlist, Length[crosssection0]], {2, 1,
3}],
(crosssection /@ tlist)
], 1];
m = Length[crosssection0];
n = Length[tlist];
polys = Partition[Flatten[BlockMap[
Transpose[{Partition[#[[1]], 2, 1, #[[1, 1]]],
Reverse /@ Partition[#[[2]], 2, 1, #[[2, 1]]]}] &,
Transpose[Table[Range[i, m n, m], {i, 1, m}]],
2, 1
]], 4];

gc = GraphicsComplex[pts, {
FaceForm[Orange, Darker@Darker@Blue],
Specularity[White, 30], EdgeForm[], Polygon[polys]
}];
Graphics3D[
gc,
Lighting -> "Neutral"
]


You can do that also with other cross sections. For example,

crosssection0 = Times[
CirclePoints[10.],
Flatten[Transpose[{
ConstantArray[0.5, 5]
}]]
];


Edit

I packaged everything into a simple function.

ClearAll[plot]
PlotStyle -> {},
"CrossSection" -> {{1, 1}, {-1, 1}, {-1, -1}, {1, -1}}
}]] :=
Module[{tangent, normal, binormal, crosssection, crosssection0, pts,
m, n, polys, gc},
tangent =
t \[Function] Evaluate[Simplify[curve'[t]/Sqrt[curve'[t].curve'[t]]]];
normal = t \[Function]
Evaluate[Simplify[tangent'[t]/Sqrt[tangent'[t].tangent'[t]]]];
binormal = t \[Function] Evaluate[Cross[tangent[t], normal[t]]];
crosssection0 = N[OptionValue["CrossSection"]];
crosssection =
t \[Function]

pts = Flatten[
Plus[
Transpose[ConstantArray[curve /@ tlist, Length[crosssection0]], {2, 1, 3}],
(crosssection /@ tlist)
],
1];
m = Length[crosssection0];
n = Length[tlist];
polys =
Partition[
Flatten[BlockMap[
Transpose[{Partition[#[[1]], 2, 1, #[[1, 1]]],
Reverse /@ Partition[#[[2]], 2, 1, #[[2, 1]]]}] &,
Transpose[Table[Range[i, m n, m], {i, 1, m}]], 2, 1]], 4];

gc = GraphicsComplex[
pts, {FaceForm[Orange, Darker@Darker@Blue],
Specularity[White, 30], EdgeForm[],
Sequence @@ Flatten[{OptionValue["PlotStyle"]}], Polygon[polys]}];
Graphics3D[gc, Lighting -> "Neutral"]
]


Now you can do things like this:

tlist = Subdivide[0., 2. Pi, 250];
img = Import["https://i.sstatic.net/wtJoA.png"];
img = Binarize[img~ColorConvert~"Grayscale"~ImageResize~500~Blur~3];
pts = DeleteDuplicates@
Cases[Normal@
ListContourPlot[Reverse@ImageData[img],
Contours -> {0.5}], _Line, -1][[1, 1]];
center = Mean@MinMax[pts] & /@ Transpose@pts;
pts = # - center & /@ pts[[;; ;; 20]];

Show[
plot[u \[Function] {Sin[u], Cos[u], u}, tlist, 0.15,
"CrossSection" -> 0.01 Reverse[pts],
PlotStyle -> FaceForm[Pink, Blend[{Red, Blue}, 0.5]]
],
plot[u \[Function] {2 Sin[u], 2 Cos[u], u}, tlist, 0.2]
]


I got the elephant from this post by anderstood.

• Ok, is that mean i can only draw it with Graphic3D only?
– VTeh
Apr 27, 2018 at 7:15
• How about meshing two ParametricPlor3D curves as shown above?
– VTeh
Apr 27, 2018 at 7:15
• I don't know of a built-in way to do it with, e.g. ParametricPlot3D. But Graphics3D is what is internally used in all 3D plots. Apr 27, 2018 at 7:20
• Great. Thanks for your help.
– VTeh
Apr 27, 2018 at 8:19
• You're welcome. Apr 27, 2018 at 8:22

It's unclear from the image what sort of twisting is desired. The image in the OP, to my eye, does not reflect the torsion of the Frenet Frame. In any case, here is a way using Tube with the method option "TubePoints" -> 4 to get a square cross section (see, for example, here):

ParametricPlot3D[{Sin[u], Sin[2 u], u/5 Cos[u]}, {u, 0, 10},
PlotStyle -> Red, PlotRange -> All, Method -> {"TubePoints" -> 4}
] /. Line[p_] :> Tube[p, 0.2]


Here's a mesh of a torus (zoomed in image shown):

Show[
ParametricPlot3D[Evaluate@
Table[{4 + (3 + Cos[v]) Sin[u], 4 + (3 + Cos[v]) Cos[u],
4 + Sin[v]} /. {u -> 2 u, v -> u + 3 v} // Evaluate,
{v, 0, Pi, Pi/8}],
{u, 0, 2 Pi}, PlotStyle -> Directive[Red, Thick], PlotRange -> All,
Method -> {"TubePoints" -> 4}],
ParametricPlot3D[Evaluate@
Table[{4 + (3 + Cos[v]) Sin[u], 4 + (3 + Cos[v]) Cos[u],
4 + Sin[v]} /. {u -> 2 u - v, v -> 3 v} // Evaluate,
{u, 0, Pi, Pi/8}],
{v, 0, 2 Pi}, PlotStyle -> Directive[Blue, Thick],
PlotRange -> All, Method -> {"TubePoints" -> 4}]
] /. Line[p_] :> Tube[p, 0.1]