如何检查2个WPF路径(应用了MatrixTransform)是否重叠



在我的WPF多点触摸应用程序中,我想检查一个路径是否与另一个路径重叠。

我该怎么做?我在互联网上找到了不同的解决方案,但由于需求的组合,没有一个是有效的:

  • 2条不规则形状的路径(因此边界不起作用:无矩形)
  • 在路径上应用MatrixTransform(由于操纵事件)
  • 路径可以旋转和缩放(使用MatrixTransform)
  • RenderTransformOrigin为0.5,0.5

我该怎么做?

示例:在这个示例中,蓝色和红色的星星是重叠的,红色和绿色不是。

<Window x:Class="WPFTest.OtherWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="OtherWindow" Height="300" Width="300" >
<Canvas >
    <Path x:Name="path1" Data="M17,0 L23,11 34,13 27,21 28,32 18,24 8,30 9,19 0,11 13,11 z" Fill="#99FF0000" Stroke="Black" RenderTransformOrigin="0.5,0.5">
        <Path.RenderTransform>
            <MatrixTransform Matrix="1,0,0,1,50,50"/>
        </Path.RenderTransform>
    </Path>
    <Path x:Name="path2" Data="M17,0 L23,11 34,13 27,21 28,32 18,24 8,30 9,19 0,11 13,11 z" Fill="#990000FF" Stroke="Black" RenderTransformOrigin="0.5,0.5">
        <Path.RenderTransform>
            <MatrixTransform Matrix="0.777817459305202,0.777817459305202,-0.777817459305202,0.777817459305202,35,45"/>
        </Path.RenderTransform>
    </Path>
    <Path x:Name="path3" Data="M17,0 L23,11 34,13 27,21 28,32 18,24 8,30 9,19 0,11 13,11 z" Fill="#9900FF00" Stroke="Black" RenderTransformOrigin="0.5,0.5">
        <Path.RenderTransform>
            <MatrixTransform Matrix="0.777817459305202,0.777817459305202,-0.777817459305202,0.777817459305202,82,55"/>
        </Path.RenderTransform>
    </Path>
</Canvas>

我如何从代码隐藏中进行检查?

谢谢,

Jim

如果可以接受,您可以使用变换后的几何体作为Path.Data,而不是(render-)变换后的路径(当然,缺点是它们的笔划不会缩放)。一旦使用了这样的变换几何图形,就可以通过Geometry.FillContainsWithDetail确定它们的相互交点,这会为交点类型提供枚举值。

您的XAML可能如下所示。请注意,因为几何体没有类似变换原点的东西,所以我修改了几何体,使坐标原点位于其中心。我还将生成的偏移添加到MatrixTransform偏移值中。

<Canvas>
    <Path Name="redStar" Fill="#99FF0000" Stroke="Black">
        <Path.Data>
            <PathGeometry Figures="M0,-16 L6,-5 17,-3 10,5 11,16 1,8 -9,14 -8,3 -17,-5 -4,-5 z">
                <PathGeometry.Transform>
                    <MatrixTransform Matrix="1,0,0,1,67,66"/>
                </PathGeometry.Transform>
            </PathGeometry>
        </Path.Data>
    </Path>
    <Path Name="blueStar" Fill="#990000FF" Stroke="Black">
        <Path.Data>
            <PathGeometry Figures="M0,-16 L6,-5 17,-3 10,5 11,16 1,8 -9,14 -8,3 -17,-5 -4,-5 z">
                <PathGeometry.Transform>
                    <MatrixTransform Matrix="0.777817459305202,0.777817459305202,-0.777817459305202,0.777817459305202,52,61"/>
                </PathGeometry.Transform>
            </PathGeometry>
        </Path.Data>
    </Path>
    <Path Name="greenStar" Fill="#9900FF00" Stroke="Black">
        <Path.Data>
            <PathGeometry Figures="M0,-16 L6,-5 17,-3 10,5 11,16 1,8 -9,14 -8,3 -17,-5 -4,-5 z">
                <PathGeometry.Transform>
                    <MatrixTransform Matrix="0.777817459305202,0.777817459305202,-0.777817459305202,0.777817459305202,99,71"/>
                </PathGeometry.Transform>
            </PathGeometry>
        </Path.Data>
    </Path>
</Canvas>

以下代码将确定交叉点:

Geometry redGeometry = redStar.Data;
Geometry blueGeometry = blueStar.Data;
Geometry greenGeometry = greenStar.Data;
Trace.TraceInformation("red/blue intersection: {0}", redGeometry.FillContainsWithDetail(blueGeometry));
Trace.TraceInformation("blue/green intersection: {0}", blueGeometry.FillContainsWithDetail(greenGeometry));
Trace.TraceInformation("green/red intersection: {0}", greenGeometry.FillContainsWithDetail(redGeometry));
redGeometry.Transform = new MatrixTransform(1, 0, 0, 1, 70, 90);
Trace.TraceInformation("red/blue intersection: {0}", redGeometry.FillContainsWithDetail(blueGeometry));

最新更新