Как проверить, перекрываются ли 2 пути WPF (с применением MatrixTransform) - PullRequest
0 голосов
/ 07 января 2012

В моем мультитач-приложении WPF я хочу проверить, перекрывает ли путь другой путь.

Как я могу это сделать?Я нашел различные решения в Интернете, но ни одно не работает, из-за сочетания требований:

  • 2 Пути неправильной формы (поэтому границы не работают: нет Rect)
  • На Пути применяется 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>

Как я могу проверить это из кода?

Спасибо,

Джим

1 Ответ

0 голосов
/ 07 января 2012

Если это приемлемо, вы можете использовать преобразованные геометрии для 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));
...