1

似乎 WPFInkCanvas只能提供笔画的点(与笔画的宽度和高度无关)。对于应用程序,我需要知道InkCanvas.

例如,假设笔画的宽度和高度为 16。使用这个笔画大小,我在InkCanvas. 有没有一种直接的方法来获得这个点中的所有 256 个像素(而不仅仅是这个巨大点的中心点)?

为什么我关心:
在我的应用程序中,用户使用 an在 显示几个 3D 对象InkCanvas的 a 上进行绘制。Viewport3D我想使用笔划的所有点来执行射线投射并确定其中哪些对象Viewport3D已被用户的笔划覆盖。

4

2 回答 2

2

我发现了一种非常肮脏的处理方式。如果有人知道更好的方法,我将非常乐意投票并接受他们的回答作为答案。
基本上,我的方法涉及获取Geometry每个笔划的 ,遍历该几何边界内的所有点并确定该点是否在几何内部。

这是我现在使用的代码:

foreach (var stroke in inkCanvas.Strokes)
{
    List<Point> pointsInside = new List<Point>();

    Geometry sketchGeo = stroke.GetGeometry();
    Rect strokeBounds = sketchGeo.Bounds;

    for (int x = (int)strokeBounds.TopLeft.X; x < (int)strokeBounds.TopRight.X + 1; x++)
        for (int y = (int)strokeBounds.TopLeft.Y; y < (int)strokeBounds.BottomLeft.Y + 1; y++)
        {
            Point p = new Point(x, y);

            if (sketchGeo.FillContains(p))
                pointsInside.Add(p);
        }
}
于 2015-05-02T04:16:53.377 回答
2

您可以使用 StrokeCollection 的 HitTest 方法。我将您的解决方案的性能与此实现进行了比较,发现 HitTest 方法的性能更好。你的里程等

// get our position on our parent.
var ul = TranslatePoint(new Point(0, 0), this.Parent as UIElement);

// get our area rect
var controlArea = new Rect(ul, new Point(ul.X + ActualWidth, ul.Y + ActualHeight));
            
// hit test for any strokes that have at least 5% of their length in our area
var strokes = _formInkCanvas.Strokes.HitTest(controlArea, 5);

if (strokes.Any())
{
   // do something with this new knowledge
}

您可以在此处找到文档: https ://docs.microsoft.com/en-us/dotnet/api/system.windows.ink.strokecollection.hittest?view=netframework-4.7.2

此外,如果您只关心矩形中是否有任何点,您可以使用下面的代码。它比 StrokeCollection.HitTest 快一个数量级,因为它不关心笔画的百分比,因此它的工作量要少得多。

    private bool StrokeHitTest(Rect bounds, StrokeCollection strokes)
    {
        for (int ix = 0; ix < strokes.Count; ix++)
        {
            var stroke = strokes[ix];
            var stylusPoints = stroke.DrawingAttributes.FitToCurve ? 
                stroke.GetBezierStylusPoints() : 
                stroke.StylusPoints;

            for (int i = 0; i < stylusPoints.Count; i++)
            {
                if (bounds.Contains((Point)stylusPoints[i]))
                {
                    return true;
                }
            }
        }
        return false;
    }
于 2021-05-28T15:02:46.547 回答