MATLAB 轮廓尖角
MATLAB contour sharp corners
MATLAB 等高线图出现圆角,即使它们不应该圆角。
剧情中
num_incs = 1000;
x = linspace(-1,1,num_incs);
[Xa,Ya] = meshgrid(x,x);
Z = abs(Xa) + abs(Ya);
contour(Xa,Ya,Z,20,'LineWidth',4);
角是圆的。有没有办法关闭自动圆角以使拐角“尖锐”?
我试过更改 renderer,但没有任何影响。此外,使用
关闭图形平滑
set(gcf,'GraphicsSmoothing','off');
不会产生尖角。
编辑:
请注意,在带有 num_incs = 1001
(或 3
)的 Matlab 2020b 上,
我仍然得到圆角:
编辑 2:
我正在尝试访问和修改 LineJoin 属性:
num_incs = 3;
x = linspace(-1,1,num_incs);
[Xa,Ya] = meshgrid(x,x);
Z = abs(Xa) + abs(Ya);
[C,hContour] = contour(Xa,Ya,Z,20,'LineWidth',4);
drawnow;
for i = 1:length(hContour.EdgePrims)
hContour.EdgePrims(i).LineJoin = deal('miter');
hContour.EdgePrims(i).LineWidth = 1; % to see what is being adjusted
end
但这只会影响“外”线。这种方法的灵感来自 this post.
结论:
渲染器的选择可能会影响抗锯齿将如何应用于绘制的线条,但在您的情况下,圆角效果只是因为没有在应该是实际角的坐标处定义数据。
如果放大任何“角”,您会注意到没有为所有 x=0
点定义点(也没有为所有 y=0
点定义点)。为了克服这个问题,Matlab 在两个最接近的定义点之间画了一条线:
这是因为您定义网格的方式。通过在一个区间内选择偶数个点(您选择了 1000 个),您永远不会在区间的中心定义一个点。要定义间隔的中心点,您必须使用 奇数 个点。
下面的 table 显示了接近过渡的网格 Ya
。您会注意到值从负变为正,但在 y=0
:
处没有定义任何点
为了在不必放大太多的情况下进行演示,我们可以使用较少的点数。观察下面两张图的区别,除了第一行外,它们使用相同的代码。在左边我使用了 num_incs = 10;
,而在右边我使用了 num_incs = 11;
:
所以在你的情况下,使用 num_incs = 1001;
你的角落应该消失。或者,如果您的示例实际上是您的案例使用,请注意,对于如此简单的形状,您可以获得与 num_incs = 3;
完全相同的视觉结果。这只定义了必要的corner点,也就是每条线的起点和终点(不要使用一条线上不必要的中间点)。
您可以将线的 LineJoin
属性 设置为 'miter'
以获得尖角:
[C,h] = contour(Xa,Ya,Z,20, 'LineWidth',4);
draw now
set(h.EdgePrims,'LineJoin','miter')
默认情况下 属性 是 'round'
。
但请注意,根据两条线相交的角度,产生的尖角可能会过长,并导致对数据的误解。第三个选项是 'chamfer'
,它提供尖角,但如果它们变得太大则将其切断。
MATLAB 等高线图出现圆角,即使它们不应该圆角。
剧情中
num_incs = 1000;
x = linspace(-1,1,num_incs);
[Xa,Ya] = meshgrid(x,x);
Z = abs(Xa) + abs(Ya);
contour(Xa,Ya,Z,20,'LineWidth',4);
角是圆的。有没有办法关闭自动圆角以使拐角“尖锐”?
我试过更改 renderer,但没有任何影响。此外,使用
关闭图形平滑set(gcf,'GraphicsSmoothing','off');
不会产生尖角。
编辑:
请注意,在带有 num_incs = 1001
(或 3
)的 Matlab 2020b 上,
我仍然得到圆角:
编辑 2: 我正在尝试访问和修改 LineJoin 属性:
num_incs = 3;
x = linspace(-1,1,num_incs);
[Xa,Ya] = meshgrid(x,x);
Z = abs(Xa) + abs(Ya);
[C,hContour] = contour(Xa,Ya,Z,20,'LineWidth',4);
drawnow;
for i = 1:length(hContour.EdgePrims)
hContour.EdgePrims(i).LineJoin = deal('miter');
hContour.EdgePrims(i).LineWidth = 1; % to see what is being adjusted
end
但这只会影响“外”线。这种方法的灵感来自 this post.
结论:
渲染器的选择可能会影响抗锯齿将如何应用于绘制的线条,但在您的情况下,圆角效果只是因为没有在应该是实际角的坐标处定义数据。
如果放大任何“角”,您会注意到没有为所有 x=0
点定义点(也没有为所有 y=0
点定义点)。为了克服这个问题,Matlab 在两个最接近的定义点之间画了一条线:
这是因为您定义网格的方式。通过在一个区间内选择偶数个点(您选择了 1000 个),您永远不会在区间的中心定义一个点。要定义间隔的中心点,您必须使用 奇数 个点。
下面的 table 显示了接近过渡的网格 Ya
。您会注意到值从负变为正,但在 y=0
:
为了在不必放大太多的情况下进行演示,我们可以使用较少的点数。观察下面两张图的区别,除了第一行外,它们使用相同的代码。在左边我使用了 num_incs = 10;
,而在右边我使用了 num_incs = 11;
:
所以在你的情况下,使用 num_incs = 1001;
你的角落应该消失。或者,如果您的示例实际上是您的案例使用,请注意,对于如此简单的形状,您可以获得与 num_incs = 3;
完全相同的视觉结果。这只定义了必要的corner点,也就是每条线的起点和终点(不要使用一条线上不必要的中间点)。
您可以将线的 LineJoin
属性 设置为 'miter'
以获得尖角:
[C,h] = contour(Xa,Ya,Z,20, 'LineWidth',4);
draw now
set(h.EdgePrims,'LineJoin','miter')
默认情况下 属性 是 'round'
。
但请注意,根据两条线相交的角度,产生的尖角可能会过长,并导致对数据的误解。第三个选项是 'chamfer'
,它提供尖角,但如果它们变得太大则将其切断。