我使用以下代码创建了一些矩形:
double width = 6.546;
for (int i = 0; i < 50; i++)
{
var rect = new Rectangle()
{
Width = width,
Height = i * 10,
Fill = Brushes.Blue,
};
Canvas.SetLeft(rect, i * width);
Canvas.SetBottom(rect, 0);
canvas.Children.Add(rect);
}
结果如下:
有不同亮度的垂直线条。它们为什么会出现?通过使用大width
值可以避免它们。还有其他方法可以避免它们吗?
答案 0 :(得分:2)
这里的关键问题是Width = width
将矩形宽度设置为6,但Canvas.SetLeft(rect, i * width)
将矩形的位置设置为0,6,13,19,26 ......(作为整数获得的整数)截断约0,6.546,13.092,19.638,26.184,......的产物。如您所见,一些位置相距7个单位,例如6和13或19和26.因此,六单位矩形不会跨越七个单位的距离。
在这种情况下,使用Width = ceil(width)
(即7)设置宽度可确保矩形足够宽,以跨越它们之间的距离。
尽管this answer建议您使用int
个数字,但目前尚无法明确这一点。如果将计算转换为int
,则必须将位置设置为一个整数(6或7)的倍数,或者计算出计算相同位置的方法(0,6,13,19,26,... )通过使用整数运算而不是浮点运算。前者是改变绘图以适应算术的选择,这是不合需要的。后者保留了图纸中的斜率但具有相同的条带问题。
该答案还建议使用绘图对象的浮点版本。这是一种合理的方法。但是请注意,这只会减少舍入误差(从整数单位到更精细的浮点单位,在这个数量级);它并没有消除它们。在大型图纸中,除非您注意避免,否则可能仍会偶尔出现绘图。因此,了解细节很重要。即使使用浮点,您也希望确保宽度设置为至少与位置变化一样大。
如果您的绘图界面支持,则另一个选项是更改画布的比例。如果您可以将比例乘以1000(但保持最终图纸大小相同),那么您的比例从6.546变为6546,您可以将宽度设置为6546而不是6000或7000.如您所见,我们是回到关键问题:您必须将宽度设置为至少与任意两个位置之间的差值一样大。
如前所述,将宽度设置为7会使此图形可以接受。我讨论其他解决方案的原因在于,在一些附图中,将宽度从理想值6.546改变为7会不期望地增加物体的尺寸。其他解决方案通过允许您保持更接近所需大小的宽度来改进。
答案 1 :(得分:0)
首先,请将此行添加到代码中(在添加Rectangle
之前),以了解轻松问题如何消失!
canvas.SnapsToDevicePixels = true;
与包括我的第一个在内的一些答案所提到的相反,此问题与浮点数无关,而是与WPF
中使用的渲染系统相关< em>与设备无关的单位测量但这可能会导致设备工作在每英寸96点(dpi)以上。微软公布了这个问题:
...由于抗锯齿,此dpi独立性可能会产生不规则的边缘渲染。当边缘的位置落在设备像素的中间而不是设备像素之间时,可能会出现这些通常被视为模糊或“软”边缘的伪影(Reference)
但该解决方案也由SnapToDevicePixels
属性提供。 (见this)