背景
YouTube 上刷到一个用 manim 做的实验动画——3D 图形投影到 xy 平面,效果挺有意思。其数学原理是使用三角函数绘制凸凹的椭圆曲线,最近在学 MatheMatica,拿它来练练手。不过光是照搬太单调,不如发挥一下,把它变成一个“鸟巢”造型。
绘制流程
最好先搞清几个关键形状的数学原理,比如中间内凹的椭圆、穿过四个点的曲线等。
icon
mathematica 绘制中间内凹的椭圆
椭圆绘制基于参数方程 r(t)=( 2 cos(t), 2 sin(t), 0.5 sin(2 t) + 2 ) ,通过调整参数即可得到不同的形态。 该椭圆由参数方程 r(t)=(2cost,2sint,0.5sin(2t)+2)r(t)=(2cost,2sint,0.5sin(2t)+2) 通过调整参数生成。
1curve = ParametricPlot3D[{4 Cos[t], 4.2 Sin[t], 2 0.6 Sin[2 t + Pi + Pi/2] + 3.2}, {t, 0, 2 Pi}, 3 PlotStyle -> {Thick, Blue}, 4 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}];5 6axes = Graphics3D[{Arrowheads[0.05], {Red, 7 Arrow[{{0, 0, 0}, {5, 0, 0}}]},(*X 轴*){Green, 8 Arrow[{{0, 0, 0}, {0, 5, 0}}]},(*Y 轴*){Blue, 9 Arrow[{{0, 0, 0}, {0, 0, 5}}]} (*Z 轴*)}];10 11 12png = Show[curve, axes, AxesLabel -> {"X", "Y", "Z"}, 13 LabelStyle -> {FontSize -> 14}, Boxed -> True]
mathematica 绘制鸟巢几条主要的轮廓线
1curve12 = 2 ParametricPlot3D[{2 Cos[t], 1.5 Sin[t], 3 0.2 Sin[2 t + Pi + Pi/2] + 3}, {t, 0, 2 Pi}, 4 PlotStyle -> {Thick, Blue}, 5 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}];6curve21 = 7 ParametricPlot3D[{4 Cos[t], 4.2 Sin[t], 8 0.6 Sin[2 t + Pi + Pi/2] + 3.2}, {t, 0, 2 Pi}, 9 PlotStyle -> {Thick, Blue}, 10 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}];11curve22 = 12 ParametricPlot3D[{4.2 Cos[t], 4.4 Sin[t], 13 0.6 Sin[2 t + Pi + Pi/2] + 2.5}, {t, 0, 2 Pi}, 14 PlotStyle -> {Thick, Blue}, 15 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}];16curve31 = 17 ParametricPlot3D[{3.4 Cos[t], 3.8 Sin[t], 0}, {t, 0, 2 \[Pi]}, 18 PlotStyle -> {Thick, Blue}, Axes -> False, 19 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}];20 21axes = Graphics3D[{Arrowheads[0.05], {Red, 22 Arrow[{{0, 0, 0}, {5, 0, 0}}]},(*X 轴*){Green, 23 Arrow[{{0, 0, 0}, {0, 5, 0}}]},(*Y 轴*){Blue, 24 Arrow[{{0, 0, 0}, {0, 0, 5}}]} (*Z 轴*)}];25 26 27png = Show[curve12, curve21, curve22, curve31, axes, 28 AxesLabel -> {"X", "Y", "Z"}, LabelStyle -> {FontSize -> 14}, 29 Boxed -> True]
mathematica 四段曲线上分别选取一个点,连接成线
1curve12 = 2 ParametricPlot3D[{2 Cos[t], 1.5 Sin[t], 3 0.2 Sin[2 t + Pi + Pi/2] + 3}, {t, 0, 2 Pi}, 4 PlotStyle -> {Thick, Blue}, 5 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}];6 7curve21 = 8 ParametricPlot3D[{4 Cos[t], 4.2 Sin[t], 9 0.6 Sin[2 t + Pi + Pi/2] + 3.2}, {t, 0, 2 Pi}, 10 PlotStyle -> {Thick, Blue}, 11 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}];12 13curve22 = 14 ParametricPlot3D[{4.2 Cos[t], 4.4 Sin[t], 15 0.6 Sin[2 t + Pi + Pi/2] + 2.5}, {t, 0, 2 Pi}, 16 PlotStyle -> {Thick, Blue}, 17 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}];18 19curve31 = 20 ParametricPlot3D[{3.4 Cos[t], 3.8 Sin[t], 0}, {t, 0, 2 \[Pi]}, 21 PlotStyle -> {Thick, Blue}, Axes -> False, 22 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}];23 24axes = Graphics3D[{Arrowheads[0.05], {Red, 25 Arrow[{{0, 0, 0}, {5, 0, 0}}]},(*X 轴*){Green, 26 Arrow[{{0, 0, 0}, {0, 5, 0}}]},(*Y 轴*){Blue, 27 Arrow[{{0, 0, 0}, {0, 0, 5}}]} (*Z 轴*)}];28 29 30p1 = {2 Cos[0], 1.5 Sin[0], 31 0.2 Sin[2*0 + Pi + Pi/2] + 3}; (*curve12 上的点*)32p2 = {4 Cos[0], 4.2 Sin[0], 33 0.6 Sin[2*0 + Pi + Pi/2] + 3.2}; (*curve21 上的点*)34p3 = {4.2 Cos[0], 4.4 Sin[0], 35 0.6 Sin[2*0 + Pi + Pi/2] + 2.5}; (*curve22 上的点*)36p4 = {3.4 Cos[0], 3.8 Sin[0], 37 0}; (*curve31 上的点*)38 39(*连接四个点绘制红色直线*)40connector = 41 Graphics3D[{Thick, Red, Line[{p1, p2, p3, p4}],(*连接四个点的折线*)42 PointSize[0.02], {Black, Point[p1]},(*点1:黑色*){Black, 43 Point[p2]},(*点2:黑色*){Black, Point[p3]},(*点3:黑色*){Black, 44 Point[p4]} (*点4:黑色*)}];45 46 47png = Show[curve12, curve21, curve22, curve31, axes, connector, 48 AxesLabel -> {"X", "Y", "Z"}, LabelStyle -> {FontSize -> 14}, 49 Boxed -> True]
mathematica 四段曲线上分别选取一个点,直线替换为曲线
1curve12 = 2 ParametricPlot3D[{2 Cos[t], 1.5 Sin[t], 3 0.2 Sin[2 t + Pi + Pi/2] + 3}, {t, 0, 2 Pi}, 4 PlotStyle -> {Thick, Blue}, 5 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}];6curve21 = 7 ParametricPlot3D[{4 Cos[t], 4.2 Sin[t], 8 0.6 Sin[2 t + Pi + Pi/2] + 3.2}, {t, 0, 2 Pi}, 9 PlotStyle -> {Thick, Blue}, 10 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}];11curve22 = 12 ParametricPlot3D[{4.2 Cos[t], 4.4 Sin[t], 13 0.6 Sin[2 t + Pi + Pi/2] + 2.5}, {t, 0, 2 Pi}, 14 PlotStyle -> {Thick, Blue}, 15 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}];16curve31 = 17 ParametricPlot3D[{3.4 Cos[t], 3.8 Sin[t], 0}, {t, 0, 2 \[Pi]}, 18 PlotStyle -> {Thick, Blue}, Axes -> False, 19 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}];20 21axes = Graphics3D[{Arrowheads[0.05], {Red, 22 Arrow[{{0, 0, 0}, {5, 0, 0}}]},(*X 轴*){Green, 23 Arrow[{{0, 0, 0}, {0, 5, 0}}]},(*Y 轴*){Blue, 24 Arrow[{{0, 0, 0}, {0, 0, 5}}]} (*Z 轴*)}];25 26 27p1 = {2 Cos[0], 1.5 Sin[0], 28 0.2 Sin[2*0 + Pi + Pi/2] + 3}; (*curve12 上的点*)29p2 = {4 Cos[0], 4.2 Sin[0], 30 0.6 Sin[2*0 + Pi + Pi/2] + 3.2}; (*curve21 上的点*)31p3 = {4.2 Cos[0], 4.4 Sin[0], 32 0.6 Sin[2*0 + Pi + Pi/2] + 2.5}; (*curve22 上的点*)33p4 = {3.4 Cos[0], 3.8 Sin[0], 34 0}; (*curve31 上的点*)35 36 37catmullRom3D[{p0_, p1_, p2_, p3_}, t_] := 38 0.5*{2 p1[[1]] + t (p2[[1]] - p0[[1]]) + 39 t^2 (2 p0[[1]] - 5 p1[[1]] + 4 p2[[1]] - p3[[1]]) + 40 t^3 (-p0[[1]] + 3 p1[[1]] - 3 p2[[1]] + p3[[1]]), 41 2 p1[[2]] + t (p2[[2]] - p0[[2]]) + 42 t^2 (2 p0[[2]] - 5 p1[[2]] + 4 p2[[2]] - p3[[2]]) + 43 t^3 (-p0[[2]] + 3 p1[[2]] - 3 p2[[2]] + p3[[2]]), 44 2 p1[[3]] + t (p2[[3]] - p0[[3]]) + 45 t^2 (2 p0[[3]] - 5 p1[[3]] + 4 p2[[3]] - p3[[3]]) + 46 t^3 (-p0[[3]] + 3 p1[[3]] - 3 p2[[3]] + p3[[3]])};47 48pts = {p1, p2, p3, p4};49newPts = 50 Join[{2.1 pts[[1]] - pts[[2]]}, pts, {2.2 pts[[-1]] - pts[[-2]]}];51 52curvePoints3D = 53 Table[catmullRom3D[{p1, p2, p3, p4}, t], {t, 0, 1, 0.1}];54 55curve = Graphics3D[{{Thick, Blue, Line[curvePoints3D]}, {Black, 56 PointSize[0.02], Point[{p1, p1, p2, p3}]}, {Dashed, Gray, 57 Line[{p1, p1, p2, p3}]}}];58 59 60png = Show[curve, curve12, curve21, curve22, curve31, axes, 61 AxesLabel -> {"X", "Y", "Z"}, LabelStyle -> {FontSize -> 14}, 62 Boxed -> True]
mathematica 四段曲线上分别选取一个点,添加两个辅助点,直线替换为曲线
1curve12 = 2 ParametricPlot3D[{2 Cos[t], 1.5 Sin[t], 3 0.2 Sin[2 t + Pi + Pi/2] + 3}, {t, 0, 2 Pi}, 4 PlotStyle -> {Thick, Blue}, 5 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}];6curve21 = 7 ParametricPlot3D[{4 Cos[t], 4.2 Sin[t], 8 0.6 Sin[2 t + Pi + Pi/2] + 3.2}, {t, 0, 2 Pi}, 9 PlotStyle -> {Thick, Blue}, 10 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}];11curve22 = 12 ParametricPlot3D[{4.2 Cos[t], 4.4 Sin[t], 13 0.6 Sin[2 t + Pi + Pi/2] + 2.5}, {t, 0, 2 Pi}, 14 PlotStyle -> {Thick, Blue}, 15 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}];16curve31 = 17 ParametricPlot3D[{3.4 Cos[t], 3.8 Sin[t], 0}, {t, 0, 2 \[Pi]}, 18 PlotStyle -> {Thick, Blue}, Axes -> False, 19 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}];20 21axes = Graphics3D[{Arrowheads[0.05], {Red, 22 Arrow[{{0, 0, 0}, {5, 0, 0}}]},(*X 轴*){Green, 23 Arrow[{{0, 0, 0}, {0, 5, 0}}]},(*Y 轴*){Blue, 24 Arrow[{{0, 0, 0}, {0, 0, 5}}]} (*Z 轴*)}];25 26p1 = {2 Cos[0], 1.5 Sin[0], 27 0.2 Sin[2*0 + Pi + Pi/2] + 3}; (*curve12 上的点*)28p2 = {4 Cos[0], 4.2 Sin[0], 29 0.6 Sin[2*0 + Pi + Pi/2] + 3.2}; (*curve21 上的点*)30p3 = {4.2 Cos[0], 4.4 Sin[0], 31 0.6 Sin[2*0 + Pi + Pi/2] + 2.5}; (*curve22 上的点*)32p4 = {3.4 Cos[0], 3.8 Sin[0], 33 0}; (*curve31 上的点*)34 35catmullRom3D[{p0_, p1_, p2_, p3_}, t_] := 36 0.5*{2 p1[[1]] + t (p2[[1]] - p0[[1]]) + 37 t^2 (2 p0[[1]] - 5 p1[[1]] + 4 p2[[1]] - p3[[1]]) + 38 t^3 (-p0[[1]] + 3 p1[[1]] - 3 p2[[1]] + p3[[1]]), 39 2 p1[[2]] + t (p2[[2]] - p0[[2]]) + 40 t^2 (2 p0[[2]] - 5 p1[[2]] + 4 p2[[2]] - p3[[2]]) + 41 t^3 (-p0[[2]] + 3 p1[[2]] - 3 p2[[2]] + p3[[2]]), 42 2 p1[[3]] + t (p2[[3]] - p0[[3]]) + 43 t^2 (2 p0[[3]] - 5 p1[[3]] + 4 p2[[3]] - p3[[3]]) + 44 t^3 (-p0[[3]] + 3 p1[[3]] - 3 p2[[3]] + p3[[3]])};45 46pts = {p1, p2, p3, p4};47curvePoints3D = 48 Table[catmullRom3D[{p1, p2, p3, p4}, t], {t, 0, 1, 0.1}];49 50newPts = 51 Join[{2.1 pts[[1]] - pts[[2]]}, pts, {2.2 pts[[-1]] - pts[[-2]]}];52crPts = Flatten[53 Table[Table[54 catmullRom3D[newPts[[i ;; i + 3]], s], {s, 0, 1, 0.1}], {i, 1, 55 Length[newPts] - 3}], 1];56 57curve = Graphics3D[{{Thick, Blue, Line[crPts]}, {Black, 58 PointSize[0.02], Point[{p1, p1, p2, p3}]}, {Dashed, Gray, 59 Line[{p1, p1, p2, p3}]}}];60 61png = Show[curve, curve12, curve21, curve22, curve31, axes, 62 AxesLabel -> {"X", "Y", "Z"}, LabelStyle -> {FontSize -> 14}, 63 Boxed -> True]
mathematica 绘制一圈曲线
1curve12 = 2 ParametricPlot3D[{2 Cos[t], 1.5 Sin[t], 3 0.2 Sin[2 t + Pi + Pi/2] + 3}, {t, 0, 2 Pi}, 4 PlotStyle -> {Thick, Blue}, 5 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}];6curve21 = 7 ParametricPlot3D[{4 Cos[t], 4.2 Sin[t], 8 0.6 Sin[2 t + Pi + Pi/2] + 3.2}, {t, 0, 2 Pi}, 9 PlotStyle -> {Thick, Blue}, 10 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}];11curve22 = 12 ParametricPlot3D[{4.2 Cos[t], 4.4 Sin[t], 13 0.6 Sin[2 t + Pi + Pi/2] + 2.5}, {t, 0, 2 Pi}, 14 PlotStyle -> {Thick, Blue}, 15 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}];16curve31 = 17 ParametricPlot3D[{3.4 Cos[t], 3.8 Sin[t], 0}, {t, 0, 2 \[Pi]}, 18 PlotStyle -> {Thick, Blue}, Axes -> False, 19 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}];20 21axes = Graphics3D[{Arrowheads[0.05], {Red, 22 Arrow[{{0, 0, 0}, {5, 0, 0}}]},(*X 轴*){Green, 23 Arrow[{{0, 0, 0}, {0, 5, 0}}]},(*Y 轴*){Blue, 24 Arrow[{{0, 0, 0}, {0, 0, 5}}]} (*Z 轴*)}];25 26catmullRom3D[{p0_, p1_, p2_, p3_}, t_] := 27 0.5*{2 p1[[1]] + t (p2[[1]] - p0[[1]]) + 28 t^2 (2 p0[[1]] - 5 p1[[1]] + 4 p2[[1]] - p3[[1]]) + 29 t^3 (-p0[[1]] + 3 p1[[1]] - 3 p2[[1]] + p3[[1]]), 30 2 p1[[2]] + t (p2[[2]] - p0[[2]]) + 31 t^2 (2 p0[[2]] - 5 p1[[2]] + 4 p2[[2]] - p3[[2]]) + 32 t^3 (-p0[[2]] + 3 p1[[2]] - 3 p2[[2]] + p3[[2]]), 33 2 p1[[3]] + t (p2[[3]] - p0[[3]]) + 34 t^2 (2 p0[[3]] - 5 p1[[3]] + 4 p2[[3]] - p3[[3]]) + 35 t^3 (-p0[[3]] + 3 p1[[3]] - 3 p2[[3]] + p3[[3]])};36 37 38offset = 0;39step = 0.2540crOneOffsets = {0 + offset, -Pi/16 + offset, -Pi/28 + offset, 41 Pi/8 + offset};42crOneTs = 43 Range[0, 2 Pi - step, 44 step]; (*curve31 上的点*)45crOneConnectors = Table[random = RandomReal[{1, 15}]*0.02;46 p1 = {2 Cos[t + crOneOffsets[[1]] + random], 47 1.5 Sin[t + crOneOffsets[[1]] + random], 48 0.2 Sin[2 (t + crOneOffsets[[1]]) + 3 Pi/2] + 3};49 p2 = {4 Cos[t + crOneOffsets[[2]]], 4.2 Sin[t + crOneOffsets[[2]]],50 0.6 Sin[2 (t + crOneOffsets[[2]]) + 3 Pi/2] + 3.2};51 p3 = {4.2 Cos[t + crOneOffsets[[3]]], 52 4.4 Sin[t + crOneOffsets[[3]]], 53 0.6 Sin[2 (t + crOneOffsets[[3]]) + 3 Pi/2] + 2.5};54 p4 = {3.4 Cos[t + crOneOffsets[[4]] + random], 55 3.8 Sin[t + crOneOffsets[[4]] + random], 0};56 pts = {p1, p2, p3, p4};57 newPts = 58 Join[{2.1 pts[[1]] - pts[[2]]}, 59 pts, {2.2 pts[[-1]] - pts[[-2]]}];60 crPts = 61 Flatten[Table[62 Table[catmullRom3D[newPts[[i ;; i + 3]], s], {s, 0, 1, 63 1/30}], {i, 1, Length[newPts] - 3}], 1];64 (*4. 绘制这一段的 CR 曲线+原控制点*){Thick, Opacity[0.7], Blue, Line[crPts], 65 Black, PointSize[0.015], Point[pts]}, {t, crOneTs}];66 67 68png = Show[Graphics3D[crOneConnectors], curve12, curve21, curve22, 69 curve31, axes, Axes -> True, AxesLabel -> {"X", "Y", "Z"}, 70 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}, 71 ImageSize -> Large, PlotLabel -> "Bird's Nest"]
mathematica 以此类推,绘制更多
1curve12 = 2 ParametricPlot3D[{2 Cos[t], 1.5 Sin[t], 3 0.2 Sin[2 t + Pi + Pi/2] + 3}, {t, 0, 2 Pi}, 4 PlotStyle -> {Thick, Blue}, 5 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}];6curve21 = 7 ParametricPlot3D[{4 Cos[t], 4.2 Sin[t], 8 0.6 Sin[2 t + Pi + Pi/2] + 3.2}, {t, 0, 2 Pi}, 9 PlotStyle -> {Thick, Blue}, 10 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}];11curve22 = 12 ParametricPlot3D[{4.2 Cos[t], 4.4 Sin[t], 13 0.6 Sin[2 t + Pi + Pi/2] + 2.5}, {t, 0, 2 Pi}, 14 PlotStyle -> {Thick, Blue}, 15 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}];16curve31 = 17 ParametricPlot3D[{3.4 Cos[t], 3.8 Sin[t], 0}, {t, 0, 2 \[Pi]}, 18 PlotStyle -> {Thick, Blue}, Axes -> False, 19 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}];20 21axes = Graphics3D[{Arrowheads[0.05], {Red, 22 Arrow[{{0, 0, 0}, {5, 0, 0}}]},(*X 轴*){Green, 23 Arrow[{{0, 0, 0}, {0, 5, 0}}]},(*Y 轴*){Blue, 24 Arrow[{{0, 0, 0}, {0, 0, 5}}]} (*Z 轴*)}];25 26catmullRom3D[{p0_, p1_, p2_, p3_}, t_] := 27 0.5*{2 p1[[1]] + t (p2[[1]] - p0[[1]]) + 28 t^2 (2 p0[[1]] - 5 p1[[1]] + 4 p2[[1]] - p3[[1]]) + 29 t^3 (-p0[[1]] + 3 p1[[1]] - 3 p2[[1]] + p3[[1]]), 30 2 p1[[2]] + t (p2[[2]] - p0[[2]]) + 31 t^2 (2 p0[[2]] - 5 p1[[2]] + 4 p2[[2]] - p3[[2]]) + 32 t^3 (-p0[[2]] + 3 p1[[2]] - 3 p2[[2]] + p3[[2]]), 33 2 p1[[3]] + t (p2[[3]] - p0[[3]]) + 34 t^2 (2 p0[[3]] - 5 p1[[3]] + 4 p2[[3]] - p3[[3]]) + 35 t^3 (-p0[[3]] + 3 p1[[3]] - 3 p2[[3]] + p3[[3]])};36 37 38offset = 0;39step = 0.2540crOneOffsets = {0 + offset, -Pi/16 + offset, -Pi/28 + offset, 41 Pi/8 + offset};42crOneTs = 43 Range[0, 2 Pi - step, 44 step]; (*curve31 上的点*)45crOneConnectors = Table[random = RandomReal[{1, 15}]*0.02;46 p1 = {2 Cos[t + crOneOffsets[[1]] + random], 47 1.5 Sin[t + crOneOffsets[[1]] + random], 48 0.2 Sin[2 (t + crOneOffsets[[1]]) + 3 Pi/2] + 3};49 p2 = {4 Cos[t + crOneOffsets[[2]]], 4.2 Sin[t + crOneOffsets[[2]]],50 0.6 Sin[2 (t + crOneOffsets[[2]]) + 3 Pi/2] + 3.2};51 p3 = {4.2 Cos[t + crOneOffsets[[3]]], 52 4.4 Sin[t + crOneOffsets[[3]]], 53 0.6 Sin[2 (t + crOneOffsets[[3]]) + 3 Pi/2] + 2.5};54 p4 = {3.4 Cos[t + crOneOffsets[[4]] + random], 55 3.8 Sin[t + crOneOffsets[[4]] + random], 0};56 pts = {p1, p2, p3, p4};57 newPts = 58 Join[{2.1 pts[[1]] - pts[[2]]}, 59 pts, {2.2 pts[[-1]] - pts[[-2]]}];60 crPts = 61 Flatten[Table[62 Table[catmullRom3D[newPts[[i ;; i + 3]], s], {s, 0, 1, 63 1/30}], {i, 1, Length[newPts] - 3}], 1];64 (*4. 绘制这一段的 CR 曲线+原控制点*){Thick, Opacity[0.7], Blue, Line[crPts], 65 Black, PointSize[0.015], Point[pts]}, {t, crOneTs}];66 67crOneConnectors1 = Table[random = RandomReal[{1, 15}]*0.02;68 p1 = {2 Cos[t + crOneOffsets[[1]] + random], 69 1.5 Sin[t + crOneOffsets[[1]] + random], 70 0.2 Sin[2 (t + crOneOffsets[[1]] + random) + 3 Pi/2] + 3};71 p2 = {4 Cos[t + crOneOffsets[[2]]], 4.2 Sin[t + crOneOffsets[[2]]],72 0.6 Sin[2 (t + crOneOffsets[[2]]) + 3 Pi/2] + 3.2};73 p3 = {4.2 Cos[t + crOneOffsets[[3]] + step], 74 4.4 Sin[t + crOneOffsets[[3]] + step], 75 0.6 Sin[2 (t + crOneOffsets[[3]] + step) + 3 Pi/2] + 2.5};76 p4 = {3.4 Cos[t + crOneOffsets[[4]] + random + step], 77 3.8 Sin[t + crOneOffsets[[4]] + random + step], 0};78 pts = {p1, p2, p3, p4};79 crPts = 80 Flatten[Table[81 Table[catmullRom3D[pts[[i ;; i + 3]], s], {s, 0, 1, 1/30}], {i, 82 1, Length[pts] - 3}], 1];83 (*4. 绘制这一段的 CR 曲线+原控制点*){Thick, Opacity[0.7], Blue, Line[crPts], 84 Transparent, PointSize[0.001], Point[pts]}, {t, crOneTs}];85 86crOneConnectors2 = Table[random = RandomReal[{1, 15}]*0.02;87 p1 = {2 Cos[t + crOneOffsets[[1]] + random], 88 1.5 Sin[t + crOneOffsets[[1]] + random], 89 0.2 Sin[2 (t + crOneOffsets[[1]] + random) + 3 Pi/2] + 3};90 p2 = {4 Cos[t + crOneOffsets[[2]] + step], 91 4.2 Sin[t + crOneOffsets[[2]] + step], 92 0.6 Sin[2 (t + crOneOffsets[[2]] + step) + 3 Pi/2] + 3.2};93 p3 = {4.2 Cos[t + crOneOffsets[[3]]], 94 4.4 Sin[t + crOneOffsets[[3]]], 95 0.6 Sin[2 (t + crOneOffsets[[3]]) + 3 Pi/2] + 2.5};96 p4 = {3.4 Cos[t + crOneOffsets[[4]] + random - step], 97 3.8 Sin[t + crOneOffsets[[4]] + random - step], 0};98 pts = {p1, p2, p3, p4};99 crPts = 100 Flatten[Table[101 Table[catmullRom3D[pts[[i ;; i + 3]], s], {s, 0, 1, 1/30}], {i, 102 1, Length[pts] - 3}], 1];103 (*4. 绘制这一段的 CR 曲线+原控制点*){Thick, Opacity[0.7], Blue, Line[crPts], 104 Transparent, PointSize[0.001], Point[pts]}, {t, crOneTs}];105 106 107offset = Pi/32;108crTwoOffsets = {0 + offset, Pi/16 + offset, 109 Pi/28 + offset, -Pi/8 + offset};110crTwoTs = Range[0, 2 Pi, step];111crTwoConnectors = Table[random = RandomReal[{1, 15}]*0.02;112 p1 = {2 Cos[t + crTwoOffsets[[1]] + random], 113 1.5 Sin[t + crTwoOffsets[[1]] + random], 114 0.2 Sin[2 (t + crTwoOffsets[[1]]) + 3 Pi/2] + 3};115 p2 = {4 Cos[t + crTwoOffsets[[2]]], 4.2 Sin[t + crTwoOffsets[[2]]],116 0.6 Sin[2 (t + crTwoOffsets[[2]]) + 3 Pi/2] + 3.2};117 p3 = {4.2 Cos[t + crTwoOffsets[[3]]], 118 4.4 Sin[t + crTwoOffsets[[3]]], 119 0.6 Sin[2 (t + crTwoOffsets[[3]]) + 3 Pi/2] + 2.5};120 p4 = {3.4 Cos[t + crTwoOffsets[[4]] + random], 121 3.8 Sin[t + crTwoOffsets[[4]] + random], 0};122 pts = {p1, p2, p3, p4};123 newPts = 124 Join[{2.1 pts[[1]] - pts[[2]]},(*p0=2*p1-p2*)125 pts, {2.2 pts[[-1]] - pts[[-2]]}];126 crPts = 127 Flatten[Table[128 Table[catmullRom3D[newPts[[i ;; i + 3]], s], {s, 0, 1, 129 1/30}], {i, 1, Length[newPts] - 3}], 1];130 {Thick, Opacity[0.7], Blue, Line[crPts], Transparent, 131 PointSize[0.001], Point[pts]}, {t, crTwoTs}];132 133crTwoConnectors1 = Table[random = RandomReal[{1, 15}]*0.02;134 p1 = {2 Cos[t + crTwoOffsets[[1]] + random], 135 1.5 Sin[t + crTwoOffsets[[1]] + random], 136 0.2 Sin[2 (t + crTwoOffsets[[1]]) + 3 Pi/2] + 3};137 p2 = {4 Cos[t + crTwoOffsets[[2]]], 4.2 Sin[t + crTwoOffsets[[2]]],138 0.6 Sin[2 (t + crTwoOffsets[[2]]) + 3 Pi/2] + 3.2};139 p3 = {4.2 Cos[t + crTwoOffsets[[3]] + step], 140 4.4 Sin[t + crTwoOffsets[[3]] + step], 141 0.6 Sin[2 (t + crTwoOffsets[[3]] + step) + 3 Pi/2] + 2.5};142 p4 = {3.4 Cos[t + crTwoOffsets[[4]] + random + step], 143 3.8 Sin[t + crTwoOffsets[[4]] + random + step], 0};144 pts = {p1, p2, p3, p4};145 crPts = 146 Flatten[Table[147 Table[catmullRom3D[pts[[i ;; i + 3]], s], {s, 0, 1, 1/30}], {i, 148 1, Length[pts] - 3}], 1];149 {Thick, Opacity[0.7], Blue, Line[crPts], Transparent, 150 PointSize[0.001], Point[pts]}, {t, crTwoTs}];151 152 153crTwoConnectors2 = Table[random = RandomReal[{1, 15}]*0.02;154 p1 = {2 Cos[t + crTwoOffsets[[1]] + random], 155 1.5 Sin[t + crTwoOffsets[[1]] + random], 156 0.2 Sin[2 (t + crTwoOffsets[[1]]) + 3 Pi/2] + 3};157 p2 = {4 Cos[t + crTwoOffsets[[2]] + step], 158 4.2 Sin[t + crTwoOffsets[[2]] + step], 159 0.6 Sin[2 (t + crTwoOffsets[[2]] + step) + 3 Pi/2] + 3.2};160 p3 = {4.2 Cos[t + crTwoOffsets[[3]]], 161 4.4 Sin[t + crTwoOffsets[[3]]], 162 0.6 Sin[2 (t + crTwoOffsets[[3]]) + 3 Pi/2] + 2.5};163 p4 = {3.4 Cos[t + crTwoOffsets[[4]] + random - step], 164 3.8 Sin[t + crTwoOffsets[[4]] + random - step], 0};165 pts = {p1, p2, p3, p4};166 crPts = 167 Flatten[Table[168 Table[catmullRom3D[pts[[i ;; i + 3]], s], {s, 0, 1, 1/30}], {i, 169 1, Length[pts] - 3}], 1];170 {Thick, Opacity[0.7], Blue, Line[crPts], Transparent, 171 PointSize[0.001], Point[pts]}, {t, crTwoTs}];172 173 174 175 176 177 178png = Show[Graphics3D[crOneConnectors], Graphics3D[crOneConnectors1], 179 Graphics3D[crOneConnectors2], Graphics3D[crTwoConnectors], 180 Graphics3D[crTwoConnectors1], Graphics3D[crTwoConnectors2], curve12,181 curve21, curve22, curve31, axes, Axes -> True, 182 AxesLabel -> {"X", "Y", "Z"}, 183 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}, 184 ImageSize -> Large, PlotLabel -> "Bird's Nest"]
mathematica 调整下图形
1curve12 = 2 ParametricPlot3D[{2 Cos[t], 1.5 Sin[t], 3 0.2 Sin[2 t + Pi + Pi/2] + 3}, {t, 0, 2 Pi}, 4 PlotStyle -> {Thickness[0.002], Blue}, 5 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}];6curve21 = 7 ParametricPlot3D[{4 Cos[t], 4.2 Sin[t], 8 0.6 Sin[2 t + Pi + Pi/2] + 3.2}, {t, 0, 2 Pi}, 9 PlotStyle -> {Thickness[0.002], Blue}, 10 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}];11curve22 = 12 ParametricPlot3D[{4.2 Cos[t], 4.4 Sin[t], 13 0.6 Sin[2 t + Pi + Pi/2] + 2.5}, {t, 0, 2 Pi}, 14 PlotStyle -> {Thickness[0.002], Blue}, 15 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}];16curve31 = 17 ParametricPlot3D[{3.4 Cos[t], 3.8 Sin[t], 0}, {t, 0, 2 \[Pi]}, 18 PlotStyle -> {Thickness[0.002], Blue}, Axes -> False, 19 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}];20 21axes = Graphics3D[{Arrowheads[0.05], {Red, 22 Arrow[{{0, 0, 0}, {5, 0, 0}}]},(*X 轴*){Green, 23 Arrow[{{0, 0, 0}, {0, 5, 0}}]},(*Y 轴*){Blue, 24 Arrow[{{0, 0, 0}, {0, 0, 5}}]} (*Z 轴*)}];25 26catmullRom3D[{p0_, p1_, p2_, p3_}, t_] := 27 0.5*{2 p1[[1]] + t (p2[[1]] - p0[[1]]) + 28 t^2 (2 p0[[1]] - 5 p1[[1]] + 4 p2[[1]] - p3[[1]]) + 29 t^3 (-p0[[1]] + 3 p1[[1]] - 3 p2[[1]] + p3[[1]]), 30 2 p1[[2]] + t (p2[[2]] - p0[[2]]) + 31 t^2 (2 p0[[2]] - 5 p1[[2]] + 4 p2[[2]] - p3[[2]]) + 32 t^3 (-p0[[2]] + 3 p1[[2]] - 3 p2[[2]] + p3[[2]]), 33 2 p1[[3]] + t (p2[[3]] - p0[[3]]) + 34 t^2 (2 p0[[3]] - 5 p1[[3]] + 4 p2[[3]] - p3[[3]]) + 35 t^3 (-p0[[3]] + 3 p1[[3]] - 3 p2[[3]] + p3[[3]])};36 37 38offset = 0;39step = 0.2540crOneOffsets = {0 + offset, -Pi/16 + offset, -Pi/28 + offset, 41 Pi/8 + offset};42crOneTs = 43 Range[0, 2 Pi - step, 44 step]; (*curve31 上的点*)45crOneConnectors = Table[random = RandomReal[{1, 15}]*0.02;46 p1 = {2 Cos[t + crOneOffsets[[1]] + random], 47 1.5 Sin[t + crOneOffsets[[1]] + random], 48 0.2 Sin[2 (t + crOneOffsets[[1]]) + 3 Pi/2] + 3};49 p2 = {4 Cos[t + crOneOffsets[[2]]], 4.2 Sin[t + crOneOffsets[[2]]],50 0.6 Sin[2 (t + crOneOffsets[[2]]) + 3 Pi/2] + 3.2};51 p3 = {4.2 Cos[t + crOneOffsets[[3]]], 52 4.4 Sin[t + crOneOffsets[[3]]], 53 0.6 Sin[2 (t + crOneOffsets[[3]]) + 3 Pi/2] + 2.5};54 p4 = {3.4 Cos[t + crOneOffsets[[4]] + random], 55 3.8 Sin[t + crOneOffsets[[4]] + random], 0};56 pts = {p1, p2, p3, p4};57 newPts = 58 Join[{2.1 pts[[1]] - pts[[2]]}, 59 pts, {2.2 pts[[-1]] - pts[[-2]]}];60 crPts = 61 Flatten[Table[62 Table[catmullRom3D[newPts[[i ;; i + 3]], s], {s, 0, 1, 63 1/30}], {i, 1, Length[newPts] - 3}], 1];64 (*4. 绘制这一段的 CR 曲线+原控制点*){Thickness[0.002], Opacity[0.7], Blue, 65 Line[crPts], Transparent, PointSize[0.015], Point[pts]}, {t, 66 crOneTs}];67 68crOneConnectors1 = Table[random = RandomReal[{1, 15}]*0.02;69 p1 = {2 Cos[t + crOneOffsets[[1]] + random], 70 1.5 Sin[t + crOneOffsets[[1]] + random], 71 0.2 Sin[2 (t + crOneOffsets[[1]] + random) + 3 Pi/2] + 3};72 p2 = {4 Cos[t + crOneOffsets[[2]]], 4.2 Sin[t + crOneOffsets[[2]]],73 0.6 Sin[2 (t + crOneOffsets[[2]]) + 3 Pi/2] + 3.2};74 p3 = {4.2 Cos[t + crOneOffsets[[3]] + step], 75 4.4 Sin[t + crOneOffsets[[3]] + step], 76 0.6 Sin[2 (t + crOneOffsets[[3]] + step) + 3 Pi/2] + 2.5};77 p4 = {3.4 Cos[t + crOneOffsets[[4]] + random + step], 78 3.8 Sin[t + crOneOffsets[[4]] + random + step], 0};79 pts = {p1, p2, p3, p4};80 crPts = 81 Flatten[Table[82 Table[catmullRom3D[pts[[i ;; i + 3]], s], {s, 0, 1, 1/30}], {i, 83 1, Length[pts] - 3}], 1];84 (*4. 绘制这一段的 CR 曲线+原控制点*){Thickness[0.002], Opacity[0.7], Blue, 85 Line[crPts], Transparent, PointSize[0.001], Point[pts]}, {t, 86 crOneTs}];87 88crOneConnectors2 = Table[random = RandomReal[{1, 15}]*0.02;89 p1 = {2 Cos[t + crOneOffsets[[1]] + random], 90 1.5 Sin[t + crOneOffsets[[1]] + random], 91 0.2 Sin[2 (t + crOneOffsets[[1]] + random) + 3 Pi/2] + 3};92 p2 = {4 Cos[t + crOneOffsets[[2]] + step], 93 4.2 Sin[t + crOneOffsets[[2]] + step], 94 0.6 Sin[2 (t + crOneOffsets[[2]] + step) + 3 Pi/2] + 3.2};95 p3 = {4.2 Cos[t + crOneOffsets[[3]]], 96 4.4 Sin[t + crOneOffsets[[3]]], 97 0.6 Sin[2 (t + crOneOffsets[[3]]) + 3 Pi/2] + 2.5};98 p4 = {3.4 Cos[t + crOneOffsets[[4]] + random - step], 99 3.8 Sin[t + crOneOffsets[[4]] + random - step], 0};100 pts = {p1, p2, p3, p4};101 crPts = 102 Flatten[Table[103 Table[catmullRom3D[pts[[i ;; i + 3]], s], {s, 0, 1, 1/30}], {i, 104 1, Length[pts] - 3}], 1];105 (*4. 绘制这一段的 CR 曲线+原控制点*){Thickness[0.002], Opacity[0.7], Blue, 106 Line[crPts], Transparent, PointSize[0.001], Point[pts]}, {t, 107 crOneTs}];108 109 110offset = Pi/32;111crTwoOffsets = {0 + offset, Pi/16 + offset, 112 Pi/28 + offset, -Pi/8 + offset};113crTwoTs = Range[0, 2 Pi, step];114crTwoConnectors = Table[random = RandomReal[{1, 15}]*0.02;115 p1 = {2 Cos[t + crTwoOffsets[[1]] + random], 116 1.5 Sin[t + crTwoOffsets[[1]] + random], 117 0.2 Sin[2 (t + crTwoOffsets[[1]]) + 3 Pi/2] + 3};118 p2 = {4 Cos[t + crTwoOffsets[[2]]], 4.2 Sin[t + crTwoOffsets[[2]]],119 0.6 Sin[2 (t + crTwoOffsets[[2]]) + 3 Pi/2] + 3.2};120 p3 = {4.2 Cos[t + crTwoOffsets[[3]]], 121 4.4 Sin[t + crTwoOffsets[[3]]], 122 0.6 Sin[2 (t + crTwoOffsets[[3]]) + 3 Pi/2] + 2.5};123 p4 = {3.4 Cos[t + crTwoOffsets[[4]] + random], 124 3.8 Sin[t + crTwoOffsets[[4]] + random], 0};125 pts = {p1, p2, p3, p4};126 newPts = 127 Join[{2.1 pts[[1]] - pts[[2]]},(*p0=2*p1-p2*)128 pts, {2.2 pts[[-1]] - pts[[-2]]}];129 crPts = 130 Flatten[Table[131 Table[catmullRom3D[newPts[[i ;; i + 3]], s], {s, 0, 1, 132 1/30}], {i, 1, Length[newPts] - 3}], 1];133 {Thickness[0.002], Opacity[0.7], Blue, Line[crPts], Transparent, 134 PointSize[0.001], Point[pts]}, {t, crTwoTs}];135 136crTwoConnectors1 = Table[random = RandomReal[{1, 15}]*0.02;137 p1 = {2 Cos[t + crTwoOffsets[[1]] + random], 138 1.5 Sin[t + crTwoOffsets[[1]] + random], 139 0.2 Sin[2 (t + crTwoOffsets[[1]]) + 3 Pi/2] + 3};140 p2 = {4 Cos[t + crTwoOffsets[[2]]], 4.2 Sin[t + crTwoOffsets[[2]]],141 0.6 Sin[2 (t + crTwoOffsets[[2]]) + 3 Pi/2] + 3.2};142 p3 = {4.2 Cos[t + crTwoOffsets[[3]] + step], 143 4.4 Sin[t + crTwoOffsets[[3]] + step], 144 0.6 Sin[2 (t + crTwoOffsets[[3]] + step) + 3 Pi/2] + 2.5};145 p4 = {3.4 Cos[t + crTwoOffsets[[4]] + random + step], 146 3.8 Sin[t + crTwoOffsets[[4]] + random + step], 0};147 pts = {p1, p2, p3, p4};148 crPts = 149 Flatten[Table[150 Table[catmullRom3D[pts[[i ;; i + 3]], s], {s, 0, 1, 1/30}], {i, 151 1, Length[pts] - 3}], 1];152 {Thickness[0.002], Opacity[0.7], Blue, Line[crPts], Transparent, 153 PointSize[0.001], Point[pts]}, {t, crTwoTs}];154 155 156crTwoConnectors2 = Table[random = RandomReal[{1, 15}]*0.02;157 p1 = {2 Cos[t + crTwoOffsets[[1]] + random], 158 1.5 Sin[t + crTwoOffsets[[1]] + random], 159 0.2 Sin[2 (t + crTwoOffsets[[1]]) + 3 Pi/2] + 3};160 p2 = {4 Cos[t + crTwoOffsets[[2]] + step], 161 4.2 Sin[t + crTwoOffsets[[2]] + step], 162 0.6 Sin[2 (t + crTwoOffsets[[2]] + step) + 3 Pi/2] + 3.2};163 p3 = {4.2 Cos[t + crTwoOffsets[[3]]], 164 4.4 Sin[t + crTwoOffsets[[3]]], 165 0.6 Sin[2 (t + crTwoOffsets[[3]]) + 3 Pi/2] + 2.5};166 p4 = {3.4 Cos[t + crTwoOffsets[[4]] + random - step], 167 3.8 Sin[t + crTwoOffsets[[4]] + random - step], 0};168 pts = {p1, p2, p3, p4};169 crPts = 170 Flatten[Table[171 Table[catmullRom3D[pts[[i ;; i + 3]], s], {s, 0, 1, 1/30}], {i, 172 1, Length[pts] - 3}], 1];173 {Thickness[0.002], Opacity[0.7], Blue, Line[crPts], Transparent, 174 PointSize[0.001], Point[pts]}, {t, crTwoTs}];175 176 177 178 179png = Show[Graphics3D[crOneConnectors], Graphics3D[crOneConnectors1], 180 Graphics3D[crOneConnectors2], Graphics3D[crTwoConnectors], 181 Graphics3D[crTwoConnectors1], Graphics3D[crTwoConnectors2], 182 curve12,(*curve21,curve22,*)curve31, axes, Axes -> True, 183 AxesLabel -> {"X", "Y", "Z"}, 184 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}, 185 ImageSize -> Large, PlotLabel -> "Bird's Nest"]
mathematica 随机添加一些横线
1curve12 = 2 ParametricPlot3D[{2 Cos[t], 1.5 Sin[t], 3 0.2 Sin[2 t + Pi + Pi/2] + 3}, {t, 0, 2 Pi}, 4 PlotStyle -> {Thickness[0.002], Blue}, 5 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}];6curve21 = 7 ParametricPlot3D[{4 Cos[t], 4.2 Sin[t], 8 0.6 Sin[2 t + Pi + Pi/2] + 3.2}, {t, 0, 2 Pi}, 9 PlotStyle -> {Thickness[0.002], Blue}, 10 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}];11curve22 = 12 ParametricPlot3D[{4.2 Cos[t], 4.4 Sin[t], 13 0.6 Sin[2 t + Pi + Pi/2] + 2.5}, {t, 0, 2 Pi}, 14 PlotStyle -> {Thickness[0.002], Blue}, 15 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}];16curve31 = 17 ParametricPlot3D[{3.4 Cos[t], 3.8 Sin[t], 0}, {t, 0, 2 \[Pi]}, 18 PlotStyle -> {Thickness[0.002], Blue}, Axes -> False, 19 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}];20 21axes = Graphics3D[{Arrowheads[0.05], {Red, 22 Arrow[{{0, 0, 0}, {5, 0, 0}}]},(*X 轴*){Green, 23 Arrow[{{0, 0, 0}, {0, 5, 0}}]},(*Y 轴*){Blue, 24 Arrow[{{0, 0, 0}, {0, 0, 5}}]} (*Z 轴*)}];25 26catmullRom3D[{p0_, p1_, p2_, p3_}, t_] := 27 0.5*{2 p1[[1]] + t (p2[[1]] - p0[[1]]) + 28 t^2 (2 p0[[1]] - 5 p1[[1]] + 4 p2[[1]] - p3[[1]]) + 29 t^3 (-p0[[1]] + 3 p1[[1]] - 3 p2[[1]] + p3[[1]]), 30 2 p1[[2]] + t (p2[[2]] - p0[[2]]) + 31 t^2 (2 p0[[2]] - 5 p1[[2]] + 4 p2[[2]] - p3[[2]]) + 32 t^3 (-p0[[2]] + 3 p1[[2]] - 3 p2[[2]] + p3[[2]]), 33 2 p1[[3]] + t (p2[[3]] - p0[[3]]) + 34 t^2 (2 p0[[3]] - 5 p1[[3]] + 4 p2[[3]] - p3[[3]]) + 35 t^3 (-p0[[3]] + 3 p1[[3]] - 3 p2[[3]] + p3[[3]])};36 37p1Collection = {};38p2Collection = {};39p3Collection = {};40p4Collection = {};41 42offset = 0;43step = 0.2544crOneOffsets = {0 + offset, -Pi/16 + offset, -Pi/28 + offset, 45 Pi/8 + offset};46crOneTs = 47 Range[0, 2 Pi - step, 48 step]; (*curve31 上的点*)49crOneConnectors = Table[random = RandomReal[{1, 15}]*0.02;50 p1 = {2 Cos[t + crOneOffsets[[1]] + random], 51 1.5 Sin[t + crOneOffsets[[1]] + random], 52 0.2 Sin[2 (t + crOneOffsets[[1]]) + 3 Pi/2] + 3};53 p2 = {4 Cos[t + crOneOffsets[[2]]], 4.2 Sin[t + crOneOffsets[[2]]],54 0.6 Sin[2 (t + crOneOffsets[[2]]) + 3 Pi/2] + 3.2};55 p3 = {4.2 Cos[t + crOneOffsets[[3]]], 56 4.4 Sin[t + crOneOffsets[[3]]], 57 0.6 Sin[2 (t + crOneOffsets[[3]]) + 3 Pi/2] + 2.5};58 p4 = {3.4 Cos[t + crOneOffsets[[4]] + random], 59 3.8 Sin[t + crOneOffsets[[4]] + random], 0};60 AppendTo[p1Collection, p1];61 AppendTo[p2Collection, p2];62 AppendTo[p3Collection, p3];63 AppendTo[p4Collection, p4];64 pts = {p1, p2, p3, p4};65 newPts = 66 Join[{2.1 pts[[1]] - pts[[2]]}, 67 pts, {2.2 pts[[-1]] - pts[[-2]]}];68 crPts = 69 Flatten[Table[70 Table[catmullRom3D[newPts[[i ;; i + 3]], s], {s, 0, 1, 71 1/30}], {i, 1, Length[newPts] - 3}], 1];72 (*4. 绘制这一段的 CR 曲线+原控制点*){Thickness[0.002], Opacity[0.7], Blue, 73 Line[crPts], Transparent, PointSize[0.015], Point[pts]}, {t, 74 crOneTs}];75 76crOneConnectors1 = Table[random = RandomReal[{1, 15}]*0.02;77 p1 = {2 Cos[t + crOneOffsets[[1]] + random], 78 1.5 Sin[t + crOneOffsets[[1]] + random], 79 0.2 Sin[2 (t + crOneOffsets[[1]] + random) + 3 Pi/2] + 3};80 p2 = {4 Cos[t + crOneOffsets[[2]]], 4.2 Sin[t + crOneOffsets[[2]]],81 0.6 Sin[2 (t + crOneOffsets[[2]]) + 3 Pi/2] + 3.2};82 p3 = {4.2 Cos[t + crOneOffsets[[3]] + step], 83 4.4 Sin[t + crOneOffsets[[3]] + step], 84 0.6 Sin[2 (t + crOneOffsets[[3]] + step) + 3 Pi/2] + 2.5};85 p4 = {3.4 Cos[t + crOneOffsets[[4]] + random + step], 86 3.8 Sin[t + crOneOffsets[[4]] + random + step], 0};87 pts = {p1, p2, p3, p4};88 crPts = 89 Flatten[Table[90 Table[catmullRom3D[pts[[i ;; i + 3]], s], {s, 0, 1, 1/30}], {i, 91 1, Length[pts] - 3}], 1];92 (*4. 绘制这一段的 CR 曲线+原控制点*){Thickness[0.002], Opacity[0.7], Blue, 93 Line[crPts], Transparent, PointSize[0.001], Point[pts]}, {t, 94 crOneTs}];95 96crOneConnectors2 = Table[random = RandomReal[{1, 15}]*0.02;97 p1 = {2 Cos[t + crOneOffsets[[1]] + random], 98 1.5 Sin[t + crOneOffsets[[1]] + random], 99 0.2 Sin[2 (t + crOneOffsets[[1]] + random) + 3 Pi/2] + 3};100 p2 = {4 Cos[t + crOneOffsets[[2]] + step], 101 4.2 Sin[t + crOneOffsets[[2]] + step], 102 0.6 Sin[2 (t + crOneOffsets[[2]] + step) + 3 Pi/2] + 3.2};103 p3 = {4.2 Cos[t + crOneOffsets[[3]]], 104 4.4 Sin[t + crOneOffsets[[3]]], 105 0.6 Sin[2 (t + crOneOffsets[[3]]) + 3 Pi/2] + 2.5};106 p4 = {3.4 Cos[t + crOneOffsets[[4]] + random - step], 107 3.8 Sin[t + crOneOffsets[[4]] + random - step], 0};108 pts = {p1, p2, p3, p4};109 crPts = 110 Flatten[Table[111 Table[catmullRom3D[pts[[i ;; i + 3]], s], {s, 0, 1, 1/30}], {i, 112 1, Length[pts] - 3}], 1];113 (*4. 绘制这一段的 CR 曲线+原控制点*){Thickness[0.002], Opacity[0.7], Blue, 114 Line[crPts], Transparent, PointSize[0.001], Point[pts]}, {t, 115 crOneTs}];116 117(*生成30条随机连接线,确保位置差不超过30*)118crOneRandomP1P2Lines = 119 Table[(*随机选择p1集合中的索引*)120 idx1 = RandomInteger[{1, Length[p1Collection]}];121 (*计算p2集合中的有效索引范围*)minIdx2 = Max[1, idx1 - 1];122 maxIdx2 = Min[Length[p2Collection], idx1 + 6];123 (*在有效范围内随机选择p2索引*)idx2 = RandomInteger[{minIdx2, maxIdx2}];124 (*获取点*)randomP1 = p1Collection[[idx1]];125 randomP2 = p2Collection[[idx2]];126 (*计算位置差*)posDiff = Abs[idx1 - idx2];127 (*创建颜色-位置差越小越蓝,越大越红*)hueValue = Rescale[posDiff, {0, 10}, {0.6, 0}];128 (*lineColor=Hue[hueValue];*)lineColor = Blue;129 (*绘制线段和端点*){Thickness[0.002], Opacity[0.7], lineColor, 130 Line[{randomP1, randomP2}]}, {30}]; (*循环30次*)131 132crOneRandomP2Lines = 133 Table[(*随机选择p1集合中的索引*)134 idx1 = RandomInteger[{1, Length[p2Collection]}];135 (*计算p2集合中的有效索引范围*)minIdx2 = Max[1, idx1 - 1];136 maxIdx2 = Min[Length[p2Collection], idx1 + 6];137 (*在有效范围内随机选择p2索引*)idx2 = RandomInteger[{minIdx2, maxIdx2}];138 (*获取点*)randomP1 = p2Collection[[idx1]];139 randomP2 = p2Collection[[idx2]];140 (*计算位置差*)posDiff = Abs[idx1 - idx2];141 (*创建颜色-位置差越小越蓝,越大越红*)hueValue = Rescale[posDiff, {0, 10}, {0.6, 0}];142 lineColor = Blue;143 (*绘制线段和端点*){Thickness[0.002], Opacity[0.7], lineColor, 144 Line[{randomP1, randomP2}]}, {30}]; (*循环30次*)145 146crOneRandomP3P4Lines = 147 Table[(*随机选择p1集合中的索引*)148 idx1 = RandomInteger[{1, Length[p3Collection]}];149 (*计算p2集合中的有效索引范围*)minIdx2 = Max[1, idx1 - 8];150 maxIdx2 = Min[Length[p4Collection], idx1];151 (*在有效范围内随机选择p2索引*)idx2 = RandomInteger[{minIdx2, maxIdx2}];152 (*获取点*)randomP1 = p3Collection[[idx1]];153 randomP2 = p4Collection[[idx2]];154 (*计算位置差*)posDiff = Abs[idx1 - idx2];155 (*创建颜色-位置差越小越蓝,越大越红*)hueValue = Rescale[posDiff, {0, 10}, {0.6, 0}];156 lineColor = Blue;157 (*绘制线段和端点*){Thickness[0.002], Opacity[0.7], lineColor, 158 Line[{randomP1, randomP2}]}, {30}]; (*循环30次*)159 160p1Collection = {};161p2Collection = {};162p3Collection = {};163p4Collection = {};164offset = Pi/32;165crTwoOffsets = {0 + offset, Pi/16 + offset, 166 Pi/28 + offset, -Pi/8 + offset};167crTwoTs = Range[0, 2 Pi, step];168crTwoConnectors = Table[random = RandomReal[{1, 15}]*0.02;169 p1 = {2 Cos[t + crTwoOffsets[[1]] + random], 170 1.5 Sin[t + crTwoOffsets[[1]] + random], 171 0.2 Sin[2 (t + crTwoOffsets[[1]]) + 3 Pi/2] + 3};172 p2 = {4 Cos[t + crTwoOffsets[[2]]], 4.2 Sin[t + crTwoOffsets[[2]]],173 0.6 Sin[2 (t + crTwoOffsets[[2]]) + 3 Pi/2] + 3.2};174 p3 = {4.2 Cos[t + crTwoOffsets[[3]]], 175 4.4 Sin[t + crTwoOffsets[[3]]], 176 0.6 Sin[2 (t + crTwoOffsets[[3]]) + 3 Pi/2] + 2.5};177 p4 = {3.4 Cos[t + crTwoOffsets[[4]] + random], 178 3.8 Sin[t + crTwoOffsets[[4]] + random], 0};179 AppendTo[p1Collection, p1];180 AppendTo[p2Collection, p2];181 AppendTo[p3Collection, p3];182 AppendTo[p4Collection, p4];183 pts = {p1, p2, p3, p4};184 newPts = 185 Join[{2.1 pts[[1]] - pts[[2]]},(*p0=2*p1-p2*)186 pts, {2.2 pts[[-1]] - pts[[-2]]}];187 crPts = 188 Flatten[Table[189 Table[catmullRom3D[newPts[[i ;; i + 3]], s], {s, 0, 1, 190 1/30}], {i, 1, Length[newPts] - 3}], 1];191 {Thickness[0.002], Opacity[0.7], Blue, Line[crPts], Transparent, 192 PointSize[0.001], Point[pts]}, {t, crTwoTs}];193 194crTwoConnectors1 = Table[random = RandomReal[{1, 15}]*0.02;195 p1 = {2 Cos[t + crTwoOffsets[[1]] + random], 196 1.5 Sin[t + crTwoOffsets[[1]] + random], 197 0.2 Sin[2 (t + crTwoOffsets[[1]]) + 3 Pi/2] + 3};198 p2 = {4 Cos[t + crTwoOffsets[[2]]], 4.2 Sin[t + crTwoOffsets[[2]]],199 0.6 Sin[2 (t + crTwoOffsets[[2]]) + 3 Pi/2] + 3.2};200 p3 = {4.2 Cos[t + crTwoOffsets[[3]] + step], 201 4.4 Sin[t + crTwoOffsets[[3]] + step], 202 0.6 Sin[2 (t + crTwoOffsets[[3]] + step) + 3 Pi/2] + 2.5};203 p4 = {3.4 Cos[t + crTwoOffsets[[4]] + random + step], 204 3.8 Sin[t + crTwoOffsets[[4]] + random + step], 0};205 pts = {p1, p2, p3, p4};206 crPts = 207 Flatten[Table[208 Table[catmullRom3D[pts[[i ;; i + 3]], s], {s, 0, 1, 1/30}], {i, 209 1, Length[pts] - 3}], 1];210 {Thickness[0.002], Opacity[0.7], Blue, Line[crPts], Transparent, 211 PointSize[0.001], Point[pts]}, {t, crTwoTs}];212 213 214crTwoConnectors2 = Table[random = RandomReal[{1, 15}]*0.02;215 p1 = {2 Cos[t + crTwoOffsets[[1]] + random], 216 1.5 Sin[t + crTwoOffsets[[1]] + random], 217 0.2 Sin[2 (t + crTwoOffsets[[1]]) + 3 Pi/2] + 3};218 p2 = {4 Cos[t + crTwoOffsets[[2]] + step], 219 4.2 Sin[t + crTwoOffsets[[2]] + step], 220 0.6 Sin[2 (t + crTwoOffsets[[2]] + step) + 3 Pi/2] + 3.2};221 p3 = {4.2 Cos[t + crTwoOffsets[[3]]], 222 4.4 Sin[t + crTwoOffsets[[3]]], 223 0.6 Sin[2 (t + crTwoOffsets[[3]]) + 3 Pi/2] + 2.5};224 p4 = {3.4 Cos[t + crTwoOffsets[[4]] + random - step], 225 3.8 Sin[t + crTwoOffsets[[4]] + random - step], 0};226 pts = {p1, p2, p3, p4};227 crPts = 228 Flatten[Table[229 Table[catmullRom3D[pts[[i ;; i + 3]], s], {s, 0, 1, 1/30}], {i, 230 1, Length[pts] - 3}], 1];231 {Thickness[0.002], Opacity[0.7], Blue, Line[crPts], Transparent, 232 PointSize[0.001], Point[pts]}, {t, crTwoTs}];233 234(*生成30条随机连接线,确保位置差不超过30*)235crTwoRandomP1P2Lines = 236 Table[(*随机选择p1集合中的索引*)237 idx1 = RandomInteger[{1, Length[p1Collection]}];238 (*计算p2集合中的有效索引范围*)minIdx2 = Max[1, idx1 - 6];239 maxIdx2 = Min[Length[p2Collection], idx1 + 1];240 (*在有效范围内随机选择p2索引*)idx2 = RandomInteger[{minIdx2, maxIdx2}];241 (*获取点*)randomP1 = p1Collection[[idx1]];242 randomP2 = p2Collection[[idx2]];243 (*计算位置差*)posDiff = Abs[idx1 - idx2];244 (*创建颜色-位置差越小越蓝,越大越红*)hueValue = Rescale[posDiff, {0, 10}, {0.6, 0}];245 lineColor = Blue;246 (*绘制线段和端点*){Thickness[0.002], Opacity[0.7], lineColor, 247 Line[{randomP1, randomP2}]}, {30}]; (*循环30次*)248 249 250 251crTwoRandomP2Lines = 252 Table[(*随机选择p1集合中的索引*)253 idx1 = RandomInteger[{1, Length[p2Collection]}];254 (*计算p2集合中的有效索引范围*)minIdx2 = Max[1, idx1 - 6];255 maxIdx2 = Min[Length[p2Collection], idx1 + 1];256 (*在有效范围内随机选择p2索引*)idx2 = RandomInteger[{minIdx2, maxIdx2}];257 (*获取点*)randomP1 = p2Collection[[idx1]];258 randomP2 = p2Collection[[idx2]];259 (*计算位置差*)posDiff = Abs[idx1 - idx2];260 (*创建颜色-位置差越小越蓝,越大越红*)hueValue = Rescale[posDiff, {0, 10}, {0.6, 0}];261 lineColor = Blue;262 (*绘制线段和端点*){Thickness[0.002], Opacity[0.7], lineColor, 263 Line[{randomP1, randomP2}]}, {30}]; (*循环30次*)264 265crTwoRandomP3P4Lines = 266 Table[(*随机选择p1集合中的索引*)267 idx1 = RandomInteger[{1, Length[p3Collection]}];268 (*计算p2集合中的有效索引范围*)minIdx2 = Max[1, idx1];269 maxIdx2 = Min[Length[p4Collection], idx1 + 8];270 (*在有效范围内随机选择p2索引*)idx2 = RandomInteger[{minIdx2, maxIdx2}];271 (*获取点*)randomP1 = p3Collection[[idx1]];272 randomP2 = p4Collection[[idx2]];273 (*计算位置差*)posDiff = Abs[idx1 - idx2];274 (*创建颜色-位置差越小越蓝,越大越红*)hueValue = Rescale[posDiff, {0, 10}, {0.6, 0}];275 lineColor = Blue;276 (*绘制线段和端点*){Thickness[0.002], Opacity[0.7], lineColor, 277 Line[{randomP1, randomP2}]}, {30}]; (*循环30次*)278 279 280 281png = Show[Graphics3D[crOneConnectors], Graphics3D[crOneConnectors1], 282 Graphics3D[crOneConnectors2], Graphics3D[crTwoConnectors], 283 Graphics3D[crTwoConnectors1], Graphics3D[crTwoConnectors2], 284 Graphics3D[crOneRandomP1P2Lines], Graphics3D[crOneRandomP2Lines], 285 Graphics3D[crOneRandomP3P4Lines], Graphics3D[crTwoRandomP1P2Lines], 286 Graphics3D[crTwoRandomP2Lines], Graphics3D[crTwoRandomP3P4Lines], 287 curve12,(*curve21,curve22,*)curve31, axes, Axes -> True, 288 AxesLabel -> {"X", "Y", "Z"}, 289 PlotRange -> {{-5, 5}, {-5, 5}, {-5, 5}}, BoxRatios -> {1, 1, 1}, 290 ImageSize -> Large, PlotLabel -> "Bird's Nest"]最终效果:
借助 Ai 工具,一步步很容易实现最后的效果,也了解 Mathematica 在 3d 方面使用方法,但最终效果还是过于有规律,mark 一下,后续尝试在 manim 实现这个效果。