Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF InkCanvas访问笔划下的所有像素_C#_Wpf_Inkcanvas_Viewport3d - Fatal编程技术网

C# WPF InkCanvas访问笔划下的所有像素

C# WPF InkCanvas访问笔划下的所有像素,c#,wpf,inkcanvas,viewport3d,C#,Wpf,Inkcanvas,Viewport3d,似乎WPF的InkCanvas只能提供笔划的点(与笔划的宽度和高度无关)。对于应用程序,我需要知道InkCanvas绘制的所有点 例如,假设笔划的宽度和高度为16。使用此笔划大小,我在InkCanvas上绘制了一个点。有没有一种简单的方法可以获得这个点的所有256个像素(而不仅仅是这个巨大点的中心点) 我为什么在乎: 在我的应用程序中,用户使用InkCanvas在显示一些3D对象的Viewport3D上绘制。我想使用笔划的所有点来执行光线投射,并确定用户笔划覆盖了视口3D中的哪些对象。我发现了一

似乎WPF的InkCanvas只能提供笔划的点(与笔划的宽度和高度无关)。对于应用程序,我需要知道
InkCanvas
绘制的所有点

例如,假设笔划的宽度和高度为16。使用此笔划大小,我在
InkCanvas
上绘制了一个点。有没有一种简单的方法可以获得这个点的所有256个像素(而不仅仅是这个巨大点的中心点)

我为什么在乎:

在我的应用程序中,用户使用
InkCanvas
在显示一些3D对象的
Viewport3D
上绘制。我想使用笔划的所有点来执行光线投射,并确定用户笔划覆盖了
视口3D
中的哪些对象。

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

下面是我现在使用的代码:

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);
        }
}
foreach(inkCanvas.Strokes中的var stroke)
{
列表点sinside=新列表();
几何图形sketchGeo=stroke.GetGeometry();
Rect strokeBounds=sketchGeo.Bounds;
对于(int x=(int)strokeBounds.TopLeft.x;x<(int)strokeBounds.TopRight.x+1;x++)
对于(int y=(int)strokeBounds.TopLeft.y;y<(int)strokeBounds.BottomLeft.y+1;y++)
{
点p=新点(x,y);
如果(sketchGeo.FillContains(p))
加上(p);
}
}

您可以使用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
}
您可以在此处找到文档:

此外,如果您只关心rect中是否有任何点,则可以使用下面的代码。它比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;
    }
private bool StrokeHitTest(矩形边界、StrokeCollection笔划)
{
对于(int ix=0;ix