1

WPFInkCanvasはストロークのポイントしか提供できないようです (ストロークの幅と高さとは関係ありません)。アプリケーションの場合、 によって描画されるすべてのポイントを知る必要がありInkCanvasます。

たとえば、ストロークの幅と高さが 16 であるとします。このストローク サイズを使用して、上にドットをペイントしInkCanvasます。このドットの 256 ピクセルすべてを取得する簡単な方法はありますか (この巨大なドットの中心点だけではありません)。

気にする理由:
私のアプリケーションでは、ユーザーは を使用して 、いくつかの 3D オブジェクトを表示しているInkCanvasの上に描画します。Viewport3Dストロークのすべてのポイントを使用してレイ キャスティングを実行Viewport3Dし、ユーザーのストロークによってオーバーレイされたオブジェクトを特定したいと考えています。

4

2 に答える 2

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

さらに、任意の点が rect 内にあるかどうかのみを気にする場合は、以下のコードを使用できます。StrokeCollection.HitTest よりも 1 桁高速です。これは、ストロークのパーセンテージを気にしないため、作業量が大幅に減るためです。

    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 に答える