1

查看以下 SVG 文件:

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400">
<polygon points="10,10 10,390 390,390 10,10" style="fill:rgb(140,90,90)" />
<polygon points="10,10 390,390 390,10 10,10" style="fill:rgb(90,140,90)" />
</svg>

如果你试试这个,这两个三角形有一个薄的灰色区域,将它们分开。我想摆脱这些,因为我有数百个小三角形,然后分隔线在该区域上作为网格可见,应该被三角形覆盖。我注意到,Mathematica 的 SVG 导出正是这个问题。

我试图用相同颜色和宽度 1 的笔触填充轮廓。但是,三角形过度填充。因此,外观取决于绘制三角形的顺序。

是否有任何干净的解决方案或至少可以改进此问题?

4

3 回答 3

1

我对共享边的多边形之间的空间有同样的问题。这是两个共享一条边的三角形,具有不同的不透明度:

http://jsfiddle.net/YfH9N/embedded/result/

...当多边形具有更高的不透明度时,空间更明显。正如其他答案中所建议的那样,向多边形添加描边轮廓会有所帮助,但描边的正确宽度取决于多边形的不透明度。

使用恒定的 1px 笔划宽度:

http://jsfiddle.net/LKQHf/embedded/result/

使用笔画宽度 = polygon_alpha ^ 6:

http://jsfiddle.net/ekwk3/2/embedded/result/

...我仅凭经验使用此 Perl 脚本找到了笔画宽度的方程式,因此您可以自己尝试一下:

#!/usr/bin/perl

print "<?xml version=\"1.0\" standalone=\"no\"?>
<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">
<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" width=\"1100\" height=\"100\">
";

for (my $alpha = 0; $alpha<=1; $alpha+=0.025) {
    my $alpha_str = sprintf("%.3f", $alpha);
    my $alpha_stroke = 1;#$alpha ** 6;
    my $alpha_stroke_str = sprintf("%.3f", $alpha_stroke);
    my $stroke_width = $alpha ** 6;
    my $stroke_width_str = sprintf("%.3fpx", $stroke_width);

    print "
    <g transform=\"translate(".($alpha*1000).",0)\">    
        <polygon points=\"20,10 25,49 6,40\" style=\"fill:rgb(255,100,0);fill-opacity:$alpha_str;stroke:rgb(255,100,0);stroke-width:$stroke_width_str;stroke-opacity:$alpha_stroke_str\" />
        <polygon points=\"20,10 25,49 40,4\" style=\"fill:rgb(255,100,0);fill-opacity:$alpha_str;stroke:rgb(255,100,0);stroke-width:$stroke_width_str;stroke-opacity:$alpha_stroke_str\" />
    </g>\n";
}

print "</svg>";
于 2014-06-17T13:09:05.780 回答
1

您看到的似乎是将矢量图形映射到位图设备的工件。为了补偿它,稍微扰动其中一个三角形,其量小于 1 个单位。

示例(代码见下文):通过沿 x 轴移动 0.2 个单位来平移紫色多边形。

请注意,除了明显的因素外,结果的质量将取决于缩放系数。在给定的示例中,我可以看到分隔线在 chrome 25 中以 >=150% 的缩放级别消失。

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400">
<polygon points="10.2,10   10.2,390 390.2,390 10.2,10" style="fill:rgb(140,90,90)" />
<polygon points="  10,10    390,390   390,10    10,10" style="fill:rgb(90,140,90)" />
</svg>

另一种选择可能是将一些三角形更改为五边形,这是一个相邻的梯形区域,覆盖三角形之间的分隔线(参见下面的代码),适用于缩放系数 > 67%。三角形及其在平面中的方向是否有任何限制(如一个直角,正交晶格上的边)?

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400">
<polygon points="10,10  10,390  390,390 390,389.6 10.4,10 10,10" style="fill:rgb(140,90,90)" />
<polygon points="10,10      390,390 390,10  10,10"               style="fill:rgb(90,140,90)" />
</svg>
于 2013-03-26T08:50:38.850 回答
1

这是使用光栅化策略的结果,没有简单的解决方法。

一种解决方法是描边三角形,但描边非常非常细。例如,这里有一个 0.2px 的描边:

演示:http: //jsfiddle.net/Qw2HL/

或者,您可以将您的图形加倍并在实际内容下方渲染描边版本。

演示:http: //jsfiddle.net/Qw2HL/1/

<g id="underlay">
  <polygon class="t1" points="10,10 10,390 390,390 10,10" />
  <polygon class="t2" points="10,10 390,390 390,10 10,10" />
</g><g id="content">
  <polygon class="t1" points="10,10 10,390 390,390 10,10" />
  <polygon class="t2" points="10,10 390,390 390,10 10,10" />
</g>
.t1 { fill:rgb(140,90,90); stroke:rgb(140,90,90) }
.t2 { fill:rgb(90,140,90); stroke:rgb(90,140,90) }
#underlay polygon { stroke-width:1px }
#content  polygon { stroke:none      }

(如果您在用户代理(如可用的网络浏览器)中运行,则可以通过 JS 自动执行此操作。)


这个演示非常清楚地显示了这个问题。

问题:http: //jsfiddle.net/tbCxT/

<svg xmlns="http://www.w3.org/2000/svg">
  <g id="aligned">
    <polygon class="a" points="10,10 10,100 100,100, 100,10" />
    <polygon class="b" points="100,10 100,100 200,100, 200,10" />
  </g>
  <g id="shifted" transform="translate(0.5,110)">
    <polygon class="a" points="10,10 10,100 100,100, 100,10" />
    <polygon class="b" points="100,10 100,100 200,100, 200,10" />
  </g>
</svg>

在这里,我们有两个垂直边缘正好在彼此的顶部。在第一种情况下,它们在像素网格上完全对齐。左侧形状完全填充左侧的所有像素,右侧形状完全填充右侧的所有像素,并且都不填充间隙。

然而,在第二种情况下,两个形状都位于像素边界之间。由于我们的形状与这些像素重叠了 50%,因此抗锯齿告诉我们,在这种情况下,我们应该将重叠的像素填充为 50% 的不透明度。所以左边的形状用 50% 的不透明度填充这个共享的像素列,然后右边的形状用另外 50% 的不透明度填充共享的列。

不幸的是,不透明度是通过乘法而不是加法建立的。一个像素的rgba(0,0,0,0.5)overtoprgba(0,0,0,0.5)产生rgba(0,0,0,0.75),NOT rgba(0,0,0,1)

这是问题的症结所在,它并不特定于 SVG。例如,请参阅:

当您将无限精确的矢量图像采样到有限像素网格时,信息会丢失。你需要破解它来解决它。

于 2013-03-26T13:51:30.117 回答