繁体   English   中英

C# wpf hittest对角线

[英]C# wpf hittest diagonal line

我在对角线上尝试命中测试。

不幸的是,当点击线的边界框时,hittest 返回 true。

知道任何人是否可以在不手动计算的情况下过滤它? 谢谢!

    private void MainWindow_PreviewMouseDown(object sender)
    {
        System.Windows.Point pt = Mouse.GetPosition((UIElement)sender);

        SheetHitResultList.Clear();

        VisualTreeHelper.HitTest((UIElement)sender, new HitTestFilterCallback(OnHitTestFilter), new HitTestResultCallback(MyHitTestResult), new PointHitTestParameters(pt));
        if (Mouse.LeftButton == MouseButtonState.Pressed)
        {
            if (SheetHitResultList.Count > 0)
            {
                foreach (HitTestResult htr in SheetHitResultList)
                {
                    var temp = htr.VisualHit;
                    if (temp.GetType() == typeof(Line))
                    {
                        MessageBox.Show("Hitted");
                        //Here the MessageBox will be shown even when I click on the bounding box
                    }
                }
            }
        }
    }

    public HitTestResultBehavior MyHitTestResult(HitTestResult result)
    {
        SheetHitResultList.Add(result);

        return HitTestResultBehavior.Continue;
    }

    HitTestFilterBehavior OnHitTestFilter(DependencyObject target)
    {
        if (target.GetType() == typeof(Line))
        {

            return HitTestFilterBehavior.Continue;
        }
        else
        {
            return HitTestFilterBehavior.ContinueSkipSelf;
        }
    }

这是我对命中测试的一些代码的改编:

    private void Canvas_PreviewMouseDown(object sender, MouseButtonEventArgs e)
    {
        Point pt = Mouse.GetPosition(ParentCanvas);
        AddIfInPath(ParentCanvas, pt);
    }
    private List<DependencyObject> foundControls = new List<DependencyObject>();
    private void AddIfInPath(Canvas canvas, Point point)
    {
        Point pt = new Point(point.X + 1, point.Y + 1);
        var hitTestArea = new EllipseGeometry(pt, 1, 1);
        foundControls.Clear();
        VisualTreeHelper.HitTest(
              canvas
            , null
            , new HitTestResultCallback(SelectionResult)
            , new GeometryHitTestParameters(hitTestArea));
        if (foundControls.Count > 0 && foundControls[0] is Line)
        {
            MessageBox.Show("Hit!");
        }
    }
    public HitTestResultBehavior SelectionResult(HitTestResult result)
    {
        IntersectionDetail id = ((GeometryHitTestResult)result).IntersectionDetail;
        switch (id)
        {
            case IntersectionDetail.FullyContains:
            case IntersectionDetail.FullyInside:
            case IntersectionDetail.Intersects:
                foundControls.Add(result.VisualHit);
                return HitTestResultBehavior.Continue;
            default:
                return HitTestResultBehavior.Stop;
        }
    }

我的观点

  <Grid>
    <Canvas PreviewMouseDown="Canvas_PreviewMouseDown"
            Name="ParentCanvas"
            >
        <Line X1="0" Y1="0" X2="700" Y2="500" Stroke="Black" StrokeThickness="2"/>
    </Canvas>
  </Grid>
</Window>

请注意,命中测试非常昂贵,因此相对较慢。 如果您想以编程方式使用它来查找一个点是否在给定的线上并且只执行一次,那么命中测试可能会足够快。 如果您想进行大量的命中测试检查,那么它们可能不是 go 的好方法。 Bresenham 线算法是基于 integer 的,并且会很快为您提供两个给定点之间的 integer X、Y 单元的列表。 舍入基于双精度的 x,y 值并进行比较。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM