C# WPF:如何检测画布上的几何体相交?

C# WPF:如何检测画布上的几何体相交?,c#,wpf,geometry,intersection,C#,Wpf,Geometry,Intersection,我需要确定在画布上移动的对象的交点(不一定在画布或任何其他面板上) 我正试图用FillContainsWithDetail确定交叉点。 交叉点似乎忽略了对象的相对位置 XAML: 在本例中,结果始终为:相交 我错过了什么 最近我不得不处理同样的问题。所以 我们需要一个从源对象提取所有变换的方法。在我的应用程序中,我只在画布中使用RenderTransform。另外,请确保在TranslateTransform之前使用Canvas.Top和Canvas.Left参数应用此转换: private s

我需要确定在画布上移动的对象的交点(不一定在画布或任何其他面板上)

我正试图用FillContainsWithDetail确定交叉点。 交叉点似乎忽略了对象的相对位置

XAML:

在本例中,结果始终为:相交

我错过了什么


最近我不得不处理同样的问题。所以

  • 我们需要一个从源对象提取所有变换的方法。在我的应用程序中,我只在画布中使用RenderTransform。另外,请确保在TranslateTransform之前使用Canvas.Top和Canvas.Left参数应用此转换:

    private static Transform GetFullTransform(UIElement e)
    {
        // The order in which transforms are applied is important!
        var transforms = new TransformGroup();
    
        if(e.RenderTransform != null)
            transforms.Children.Add(e.RenderTransform);
    
        var xTranslate = (double)e.GetValue(Canvas.LeftProperty);
        if (double.IsNaN(xTranslate)) 
            xTranslate = 0D;
    
        var yTranslate = (double)e.GetValue(Canvas.TopProperty);
        if (double.IsNaN(yTranslate)) 
            yTranslate = 0D;
    
        var translateTransform = new TranslateTransform(xTranslate, yTranslate);
        transforms.Children.Add(translateTransform);
    
        return transforms;
    }
    
  • 介绍一种将给定对象转换为几何体的方法。出于演示目的,我将转换一个形状对象:

    public Geometry GetGeometry(Shape s)
    {
        var g = s.RenderedGeometry.Clone();
        g.Transform = GetFullTransform(s);
        return g;
    }
    
  • 最后,使用方法。以下条件在两种情况下返回真值:存在交叉点时,或当一个几何图形完全位于另一个几何图形内时:

    private static bool HasIntersection(Geometry g1, Geometry g2) =>
        g1.FillContainsWithDetail(g2) != IntersectionDetail.Empty;
    

  • 比较两条路径的渲染几何体。它们是相同的。不管你是设置画布。左边还是上面。试着用不同的颜色画两个形状,每个都有50%的透明度。这样,您可以直观地确定它们是否确实重叠,或者您的代码是否错误。@Clemens,没错。问题是如何确定移动对象的碰撞。@CShark,实际上两个图形都已填充,我为post编写了此代码。如果要使用对几何体(如FillContainsWithDetail)进行操作的方法来执行此操作,则需要将实际考虑“相对位置”的几何体考虑在内。不是路径元素应该移动,而是几何图形应该“移动”,即改变以使其类似于所需的移动。尝试设置
    几何体.Transform
    属性,而不是Canvas.Left和Top。
    public Geometry GetGeometry(Shape s)
    {
        var g = s.RenderedGeometry.Clone();
        g.Transform = GetFullTransform(s);
        return g;
    }
    
    private static bool HasIntersection(Geometry g1, Geometry g2) =>
        g1.FillContainsWithDetail(g2) != IntersectionDetail.Empty;