我想在可见的网格交叉点绘制点,如下所示:
Plot3D[Sin[x + y^2], {x, -3, 3}, {y, -2, 2}, Mesh -> {1, 4}, Boxed -> False]
期望的输出:
我可以根据PlotRange和Mesh基数来计算Mesh的位置,并在那里绘制点,但我认为应该有一种更简单的替代方法。
一个很大的优点是能够根据功能值选择点颜色。此外,标记点将是美好的。
有什么想法吗?
答案 0 :(得分:8)
对于它的价值,我也喜欢简单的解决方案。此外,表面和点都很容易使用相同的着色功能:
g = Plot3D[Sin[x + y^2], {x, -3, 3}, {y, -2, 2}, Mesh -> {1, 4}, Boxed -> False, ColorFunction -> "Rainbow"];
p = ListPointPlot3D[Table[{x, y, Sin[x + y^2]}, {x, -3, 3, (3 - (-3))/(1 + 1)}, {y, -2, 2, (2 - (-2))/(4 + 1)}], ColorFunction -> "Rainbow", PlotStyle -> PointSize[Large]];
Show[g, p]
修改强> 如果我们想把它变成一个自定义的myPlot3D,我想以下应该做:
myPlot3D[f_, {x_, xmin_, xmax_}, {y_, ymin_, ymax_},
Mesh -> {i_Integer, j_Integer}, opts : OptionsPattern[]] :=
Module[{g =
Plot3D[f, {x, xmin, xmax}, {y, ymin, ymax}, Mesh -> {i, j},
Evaluate@FilterRules[{opts}, Options[Plot3D]]],
stx = (xmax - xmin)/(i + 1),
sty = (ymax - ymin)/(j + 1), pts},
pts = ListPointPlot3D[
Table[{x, y, f}, {x, xmin + stx, xmax - stx, stx}, {y,
ymin + sty, ymax - sty, sty}],
Evaluate@FilterRules[{opts}, Options[ListPointPlot3D]]];
Show[g, pts]];
请注意,选项适用于两个图,但会先过滤。我还删除了绘图轮廓上的点。例如,
myPlot3D[Sin[x + y^2], {x, -3, 3}, {y, -2, 2}, Mesh -> {4, 10},
Boxed -> False, ColorFunction -> "Rainbow", Axes -> False,
PlotStyle -> PointSize[Large]]
将作为结果
答案 1 :(得分:5)
这是一种非常糟糕的方法:抓住输出中的网格线并寻找交叉点。由于输出为GraphicsComplex
,因此非常可行
首先,在图形复合体中找到网格线点的索引:
g=Plot3D[Sin[x+y^2],{x,-3,3},{y,-2,2},Mesh->{1,4},Boxed->False];
meshlineptindices=First/@Cases[g, _Line, Infinity]
现在,成对地遍历这些线并寻找交叉点。下面,使用NestWhile
以递归方式查看原始网格线列表的更短和更短子列表的所有对(第一行,另一条线)。生成的交叉点通过Sow
:
intesectionindices=
Flatten@Reap@NestWhile[(
Sow@Outer[Intersection,{First[#]},Rest[#],1];
Rest[#]
)&, meshlineptindices, Length[#]>0&]
Out[4]= {1260,1491,1264,1401,1284,1371,1298,1448,1205,1219,1528,1525,1526,1527}
在GraphicsComplex
:
intesections = Part[g[[1,1]],intesectionindices]
Out[5]= {{-3.,-1.2,-0.997667},{3.,-1.2,-0.961188},<...>,{0.,1.2,0.977754}}
最后,将这些点与原始图形一起显示:
Show[g,Graphics3D[{Red,PointSize[Large],Point[intesections]}]]
HTH
更新:要获得彩色点,您只需使用
即可Graphics3D[{PointSize[Large],({colorfunction[Last@#],Point[#]}&)/@intesections]}]
答案 2 :(得分:4)
好吧,Janus打我写答案。我无法弄清楚使用Part的部分。 无论如何,这是一个简化版本:
g = Plot3D[Sin[x + y^2], {x, -3, 3}, {y, -2, 2}, Mesh -> {1, 4}, Boxed -> False];
index = Cases[Cases[g, _Line, \[Infinity]], _Integer, \[Infinity]];
inter = Part[Select[Tally@index, Part[#, 2] > 1 &], All, 1];
Show[g, Graphics3D[{Red, PointSize[Large], Point[Part[g[[1, 1]], inter]]}]]
<强>更新强>
如果您只想要网格的交点,则需要删除边界上的点。我在这里做了一个4乘4的网格。
g = Plot3D[Sin[x + y^2], {x, -3, 3}, {y, -2, 2}, Mesh -> {4, 4}, Boxed -> False];
index = Cases[Cases[g, _Line, \[Infinity]], _Integer, \[Infinity]];
inter = Part[Select[Tally@index, Part[#, 2] > 1 &], All, 1];
range = AbsoluteOptions[g, PlotRange][[1]][[2]];
interior = Select[
Part[g[[1, 1]], inter],
IntervalMemberQ[Interval[range[[1]]]*0.9999, Part[#, 1]]
&&
IntervalMemberQ[Interval[range[[2]]]*0.9999, Part[#, 2]]
&
];
Show[g, Graphics3D[{Red, PointSize[Large], Point[interior] }]]
答案 3 :(得分:2)
只要有可能,我宁愿远离搞乱图形FullForm。所以,进入我原来的路线,几乎和FelixCQ一样,并尝试获得一般功能。
Options[myPlot3D] = Options[Plot3D];
myPlot3D[f_, p__] :=
Module[
{g = Plot3D[f, p],
(*Get the Mesh Divisions*)
m = Flatten@Cases[{p}, HoldPattern[Rule[Mesh, r_]] -> r],
stx, sty},
(*Get PlotRange*)
pr = (List @@@ Options[g, PlotRange])[[1, 2]];
(*Get Mesh steps*)
stx = (pr[[1, 2]] - pr[[1, 1]])/(First@m + 1);
sty = (pr[[2, 2]] - pr[[2, 1]])/(Last@m + 1);
(*Generate points*)
pts = Point[
Flatten[Table[{a, b, f /. {x -> a, y -> b}}, {a,
pr[[1, 1]] + stx, pr[[1, 2]] - stx, stx},
{b, pr[[2, 1]] + sty, pr[[2, 2]] - sty, sty}], 1]];
Show[g, Graphics3D[{PointSize[Large], pts}]]
];
myPlot3D[Sin[x + y^2], {x, -3, 3}, {y, -2, 2}, Mesh -> {1, 2},
Boxed -> False, ColorFunction -> "Rainbow", Axes -> False]
这里的主要问题是绘制的函数必须依赖于形式参数x
和y
...必须解决它:(