查看以下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的笔划填充轮廓。但是,三角形溢出。因此,外观取决于绘制三角形的顺序。
是否有任何干净的解决方案或至少是对此问题的改进?
答案 0 :(得分: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>
另一种选择可能是将一些三角形改为五边形,一个相邻的梯形区域覆盖三角形之间的分隔线(见下面的代码),该区域适用于缩放因子&gt; 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>
答案 1 :(得分:1)
这是使用光栅化策略的结果,并没有简单的解决方法。
一个解决方法是划动三角形,但行程非常非常薄。例如,这是一个行程为0.2px的行程:
或者,您可以将图形加倍并在实际内容下面渲染描边版本。
<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 }
(如果您在用户代理(如可用的Web浏览器)中运行,则可以通过JS自动执行此操作。)
此演示非常清楚地显示了问题。
<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)
上方的rgba(0,0,0,0.5)
像素生成rgba(0,0,0,0.75)
,而不是rgba(0,0,0,1)
。
这是问题的症结所在,并不是SVG所特有的。例如,请参阅:
当您将无限精确的矢量图像采样到有限像素网格时,信息会丢失。你需要破解它来解决它。
答案 2 :(得分: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>";