I want to export the numerical solution of the Chan-Lee oscillator as an STL file so that I could print it out. But when I expanded the curve into a tube, DiscretizeGraphics
recognizes it as an empty region. How could I somehow fill the tube and make it a discretizable solid?
My code:
α = 5; β = -10; δ = -.38;
s = NDSolve[{α x[t] - y[t] z[t] ==
D[x[t], t], β y[t] + x[t] z[t] ==
D[y[t], t], δ z[t] + x[t] y[t]/3 == D[z[t], t],
x[0] == y[0] == z[0] == 10}, {x, y, z}, {t, 0, 100},
MaxSteps -> ∞];
ps = Table[{x[t] - y[t]/Sqrt[2], y[t], z[t]} /. First[s], {t, 0,
100, .1}];
curve = Graphics3D[Tube[BSplineCurve[ps], .5]];
Export["Chan-Lee.stl", DiscretizeGraphics[curve]]
Answer
A possible workaround (brought up by the Wizard in the comments) involves the use of some of the functions from this previous answer. In particular, you will need orthogonalDirections[]
, extend[]
, and crossSection[]
from that answer, along with these two additional functions for generating a suitable MeshRegion[]
object:
MakeTriangleMesh[vl_List, opts___] := Module[{dims = Most[Dimensions[vl]]},
MeshRegion[Apply[Join, vl], Triangle /@ Flatten[
Apply[{Append[Reverse[#1], Last[#2]], Prepend[#2, First[#1]]} &,
Partition[Partition[Range[Times @@ dims], Last[dims]],
{2, 2}, {1, 1}], {2}], 2], opts]] /; ArrayDepth[vl] == 3
TubeMesh[path_?MatrixQ, cs : (_Integer | _?MatrixQ), opts___] :=
MakeTriangleMesh[FoldList[Function[{p, t}, With[{o = orthogonalDirections[t]},
extend[#, t[[2]], t[[2]] - t[[1]], o] & /@ p]],
crossSection[path, 1., cs],
Partition[path, 3, 1, {1, 2}, {}]], opts]
(The observant will notice that these are only slight modifications of the previous routines MakePolygons[]
and TubePolygons[]
.)
For your specific example:
With[{α = 5, β = -10, δ = -.38},
{xx, yy, zz} = NDSolveValue[{α x[t] - y[t] z[t] == x'[t],
β y[t] + x[t] z[t] == y'[t],
δ z[t] + x[t] y[t]/3 == z'[t],
x[0] == y[0] == z[0] == 10}, {x, y, z}, {t, 0, 100}]]
path = Transpose[{{1/Sqrt[2], -1/Sqrt[2], 0}, {0, 1, 0}, {0, 0, 1}} .
Through[{xx, yy, zz}["ValuesOnGrid"]]];
TubeMesh[path, CirclePoints[0.5, 20]]
Note that the result is an open tube (equivalent to using CapForm[None]
with Tube[]
); the equivalent of using CapForm["Round"]
is slightly trickier to do.
Comments
Post a Comment