3

WPF で定義されたブラシの放射状スイープを使用して何かを塗りつぶす方法を探しています。明確にするために、一連の画像で必要なものを分解します。

次のようなブラシを WPF で定義するとします。

みがきます

次に、そのブラシのスライスを次のように使用します。

スライスでブラシ

次に示すように、円の半径全体に並べて表示します。

半径のタイリング

最後に、シェイプを塗りつぶすために、円のすべての角度にわたってブラシをスイープすると、次のような結果が得られます。

円を掃く

この特定のケースでは、同心円を作ろうとしています。RadialGradientBrush を使用してこれを達成できることはわかっていますが、同心円の幅を正確に制御するには、円のサイズに基づいて放射状のストップの数を変更する必要があるため、これは不快な解決策です。さらに悪いことに、円のサイズが変更された場合、円の幅/高さに基づいて何らかのコンバーターを使用しない限り、ラジアル ストップは変更されません。

おそらくパスなどを使用してこれを行うためのクリーンなソリューションを望んでいましたが、制御されたサイズの円スライスを作成するための他の提案は大歓迎です。

4

2 に答える 2

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>
于 2013-06-11T20:58:02.170 に答える
1

同心円の場合、クレメンスのソリューションをコンバーターと組み合わせることで、幅を動的に変更できる正確なサイズの円が可能になり、円の量は許可された領域に収まる数に設定されます。

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>

私の場合、リソース ディクショナリで定義された double を使用しているだけですが、ビュー モデルからバインディングを簡単に使用できます。

ただし、質問はタイル化された放射状のスイープに関するものであり、他の理由で役立つ可能性があるため、受け入れられた回答としてマークすることはまだありません。

于 2013-06-12T14:52:38.490 に答える