径向扫描刷子

时间:2013-06-11 20:30:43

标签: c# wpf

我正在寻找一种方法来使用WPF中定义画笔的径向扫描来填充某些东西。我打算在一系列图片中分解我想要的东西,试图说清楚。

假设我在WPF中定义了一个看起来像这样的画笔:

Brush

然后我想像这样使用一块画笔:

Brush with Slice

将其平铺在圆的半径上,如图所示:

Tiling the Radius

最后,为了填充形状,我想将画笔扫过圆的所有角度,为我提供类似于此的结果:

Sweeping the Circle

在这个特殊情况下,我试图制作同心圆。我知道我可以使用RadialGradientBrush实现这一点,但这是一个令人讨厌的解决方案,因为为了精确控制同心圆的宽度,我需要根据圆的大小改变径向挡块的数量。更糟糕的是,如果圆圈尺寸发生变化,径向挡块不会改变,除非我根据圆宽/高度使用某种转换器。

我希望有一个干净的解决方案,可能会使用路径或其他东西,但欢迎任何其他建议制作受控尺寸的圆形切片。

2 个答案:

答案 0 :(得分:1)

使用画笔绘制几个同心圆怎么样?

<Rectangle>
    <Rectangle.Fill>
        <DrawingBrush Stretch="Uniform">
            <DrawingBrush.Drawing>
                <GeometryDrawing>
                    <GeometryDrawing.Pen>
                        <Pen Brush="Black" Thickness="1"/>
                    </GeometryDrawing.Pen>
                    <GeometryDrawing.Geometry>
                        <GeometryGroup>
                            <EllipseGeometry RadiusX="1" RadiusY="1"/>
                            <EllipseGeometry RadiusX="3" RadiusY="3"/>
                            <EllipseGeometry RadiusX="5" RadiusY="5"/>
                            <EllipseGeometry RadiusX="7" RadiusY="7"/>
                            <EllipseGeometry RadiusX="9" RadiusY="9"/>
                            <EllipseGeometry RadiusX="11" RadiusY="11"/>
                        </GeometryGroup>
                    </GeometryDrawing.Geometry>
                </GeometryDrawing>
            </DrawingBrush.Drawing>
        </DrawingBrush>
    </Rectangle.Fill>
</Rectangle>

答案 1 :(得分:1)

关于同心圆情况,将Clemens的解决方案与转换器结合使用可以得到精确尺寸的圆,其宽度可以动态改变,圆的数量设置为允许区域中的任意数量。

class SizeSpacingToCircleGroupConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (values == null) return values;
        var input = values.OfType<double>().ToArray();
        if (input.Length != 3) return values;

        var width = input[0];
        var height = input[1];
        var spacing = input[2];

        var halfSpacing = spacing / 2;
        var diameter = width > height ? height : width;

        var lineCount = (int)Math.Floor((diameter / (2 * spacing)) - 1);
        if (lineCount <= 0) return values;

        var circles = Enumerable.Range(0, lineCount).Select(i =>
        {
            var radius = halfSpacing + (i * spacing);
            return new EllipseGeometry() { RadiusX = radius, RadiusY = radius };
        }).ToArray();

        var group = new GeometryGroup();
        foreach (var circle in circles) group.Children.Add(circle);

        return group;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

和XAML:

<Rectangle Height="{StaticResource Diameter}" Width="{StaticResource Diameter}">
    <Rectangle.Fill>
        <DrawingBrush Stretch="None">
            <DrawingBrush.Drawing>
                <GeometryDrawing>
                    <GeometryDrawing.Pen>
                        <Pen Brush="{StaticResource ForegroundBrush}" Thickness="{StaticResource SpacingDiv2}"/>
                    </GeometryDrawing.Pen>
                    <GeometryDrawing.Geometry>
                        <MultiBinding Converter="{StaticResource SizeSpacingToCircleGroupConverter}">
                            <Binding Source="{StaticResource Diameter}" />
                            <Binding Source="{StaticResource Diameter}" />
                            <Binding Source="{StaticResource Spacing}" />
                        </MultiBinding>
                    </GeometryDrawing.Geometry>
                </GeometryDrawing>
            </DrawingBrush.Drawing>
        </DrawingBrush>
    </Rectangle.Fill>
</Rectangle>

在我的情况下,我只是使用资源字典中定义的双打,但我可以轻松地使用视图模型中的绑定。

我仍然不会将任何内容标记为已接受的答案,但因为问题是关于平铺的径向扫描,这可能是有用的其他原因。