【问题标题】:Connecting two WPF canvas elements by a line, without using anchors?通过一条线连接两个 WPF 画布元素,而不使用锚点?
【发布时间】:2009-11-15 13:19:04
【问题描述】:

我有一个用于绘制图表的画布,并希望通过定向线(箭头末端)连接图表中的节点。 我尝试了锚点方法,其中线只附加在节点上的特定点上,但这对我不起作用,看起来很垃圾。

我只是想要一条从每个对象的中心到另一个对象的线,然后将线停在节点的边缘,以便正确显示箭头末端。但事实证明,要找到画布元素的边缘来测试交叉点是很困难的。

有什么想法吗?

【问题讨论】:

    标签: wpf join element line intersection


    【解决方案1】:

    我有一个使用元素边界框的方法。它并不完美,因为我的元素不是完美的矩形,但看起来还不错。

    基本上我通过以下方式在 Canvas 坐标中找到元素的边界框:

        private static Rect GetBounds(FrameworkElement element, UIElement visual)
        {
            return new Rect(
                element.TranslatePoint(new Point(0, 0), visual),
                element.TranslatePoint(new Point(element.ActualWidth, element.ActualHeight), visual));
        }
    

    然后我找到中心到中心线与边界框四个边中的每一个的交点,并使用该交点通过线条形状连接两个元素。

    我在第三方忍者找到了路口代码: http://thirdpartyninjas.com/blog/2008/10/07/line-segment-intersection/

    private void ProcessIntersection()
        {
            float ua = (point4.X - point3.X) * (point1.Y - point3.Y) - (point4.Y - point3.Y) * (point1.X - point3.X);
            float ub = (point2.X - point1.X) * (point1.Y - point3.Y) - (point2.Y - point1.Y) * (point1.X - point3.X);
            float denominator = (point4.Y - point3.Y) * (point2.X - point1.X) - (point4.X - point3.X) * (point2.Y - point1.Y);
    
            intersection = coincident = false;
    
            if (Math.Abs(denominator) <= 0.00001f)
            {
                if (Math.Abs(ua) <= 0.00001f && Math.Abs(ub) <= 0.00001f)
                {
                    intersection = coincident = true;
                    intersectionPoint = (point1 + point2) / 2;
                }
            }
            else
            {
                ua /= denominator;
                ub /= denominator;
    
                if (ua >= 0 && ua <= 1 && ub >= 0 && ub <= 1)
                {
                    intersection = true;
                    intersectionPoint.X = point1.X + ua * (point2.X - point1.X);
                    intersectionPoint.Y = point1.Y + ua * (point2.Y - point1.Y);
                }
            }
        }
    

    瞧!现在绘制的线条就像从每个节点的中心到另一个节点一样,但大致停在节点的边缘,因此箭头末端可见。

    此方法的一个改进是针对节点本身的实际边缘进行测试,例如椭圆节点,但我还没有找到一种 WPF 方法,可以为我提供可以测试的几何或路径。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-20
      • 2011-09-10
      • 2013-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-23
      • 1970-01-01
      相关资源
      最近更新 更多