我得到了一个使用元素边界框的方法。它不是完美的,因为我的元素不是完全矩形的,但是看起来不错。
基本上,我在画布坐标中通过以下方式找到元素的边界框:
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));
}
然后我找到中心到中心线的交点,与边界框的四个边相对,并使用该交点将两个元素通过一个线条形状连接起来。
我在第三方Ninjas找到了交叉密码:
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);
}
}
}
还有Voice!这些线现在被绘制成从每个节点的中心到另一个节点的样子,但是它们大约停在节点的边缘,因此箭头端可见。
这种方法的一个改进是针对节点本身的实际边缘进行测试,例如对于椭圆节点,但是我还没有找到一个WPF方法,它为我提供了一个可以测试的几何体或路径。