在WPF中无缝拼接矩形

时间:2009-06-07 13:17:06

标签: wpf tiles tesselation

我想在WPF中无缝平铺一堆不同颜色的矩形。也就是说,我希望将一堆矩形边对边放置,并且它们之间没有间隙。

如果所有内容都与像素对齐,则可以正常工作。但我也想支持任意缩放,理想情况下,我不想使用SnapsToDevicePixels(因为当图像缩小时会影响质量)。但这意味着我的矩形有时会带有间隙。例如:

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      Background="Black">
  <Canvas SnapsToDevicePixels="False">
    <Canvas.RenderTransform>
      <ScaleTransform ScaleX="0.5" ScaleY="0.5"/>
    </Canvas.RenderTransform>
    <Rectangle Canvas.Left="25" Width="100" Height="100" Fill="#CFC"/>
    <Rectangle Canvas.Left="125" Width="100" Height="100" Fill="#CCF"/>
  </Canvas>
</Page>

如果ScaleTransform的ScaleX为1,则矩形无缝地组合在一起。当它为0.5时,它们之间会出现深灰色条纹。我理解为什么 - 组合的半透明边缘像素不能组合成100%不透明。但我想找到一种解决方法。

我总是可以让矩形重叠,但我不会事先知道它们将会是什么样的模式(这适用于最终支持地图编辑器的游戏)。此外,当物体在中以方式放大时,这会在重叠区域周围造成瑕疵(除非我在底层部分做了斜角切割,这是一项非常多的工作,并且仍然会导致角落出现问题)。

有没有什么方法可以将这些矩形组合成一个组合的“形状”,在没有内部间隙的情况下渲染?我玩过GeometryDrawing,它就是这样做的,但后来我没有看到用不同颜色的画笔绘制每个RectangleGeometry的方法。

有没有其他方法可以在任意变换下无缝拼接形状,而不需要使用SnapsToDevicePixels?

2 个答案:

答案 0 :(得分:2)

您可以考虑使用指南(请参阅GuidelineSet on MSDN)并覆盖矩形的OnRender方法,以使其边界与设备的像素边界对齐。 WPF使用指南来确定是否以及在何处捕捉绘图。

在内部,正是SnapsToDevicePixels正在使用它来确保对象与设备的像素对齐,但通过手动放置指南,您将能够控制何时应用捕捉行为以及何时不应用(因此当您的图像时)一直放大,你可以避免绘制指南,或只绘制你的形状与其他形状相邻的指南,并依靠WPF的抗锯齿来处理其余的事情)。您可能能够使用附加属性执行此操作,以便您可以将其应用于任何元素,但如果它只是您需要此行为的一种类型的元素(例如Rectangle),则可能不是值得付出额外的努力。

似乎微软也意识到了这个问题 - WPF 4.0 is expected to feature Layout Roundinglike the version in Silverlight,在启用布局舍入时,在渲染过程中舍入非整数值。

答案 1 :(得分:0)

我猜这些差距不是实际的差距,而是绘制的笔画。缩小比例时,只需将笔划缩小到不再可见的程度即可。我尝试用矩形的颜色绘制笔划,它可以在任何比例下正常工作。

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      Background="Black">
  <Canvas SnapsToDevicePixels="False">
    <Canvas.RenderTransform>
      <ScaleTransform ScaleX="0.5" ScaleY="0.5"/>
    </Canvas.RenderTransform>
    <Rectangle Canvas.Left="25" Width="100" Height="100" Fill="#CFC" Stroke="#CFC"/>
    <Rectangle Canvas.Left="125" Width="100" Height="100" Fill="#CCF" Stroke="#CCF"/>
  </Canvas>
</Page>