Aracılığıyla paylaş


Mürekkep Silme Örneği

Bu uygulama, mürekkep vuruşlarının silinmesini gösteren Mürekkep Koleksiyonu Örneği üzerine inşa edilmiştir. Örnek, kullanıcıya dört farklı mod içeren bir menü sağlar: mürekkep etkinliği, köşelerde silme, kesişim noktalarında silme ve vuruşları silme.

Mürekkep etkin modda, InkCollector nesnesi Mürekkep Koleksiyonu Örneği'nde gösterildiği gibi mürekkep toplar.

Silme modunda, kullanıcının imleçle dokunduğu mevcut mürekkep vuruşlarının kesimleri silinir. Ayrıca, uç noktalar veya kesişimler kırmızı bir daire ile işaretlenebilir.

Bu örneğin en ilginç bölümleri, InkErase formunun OnPaint olay işleyicisinde ve formun OnMouseMove olay işleyicisinden çağrılan silme işlevlerinde bulunur.

Dönerek Cusplar ve Kesişimler Üzerinde Dolaşma

Formun OnPaint olay işleyicisi önce çizgileri boyar ve uygulama moduna bağlı olarak, küçük kırmızı bir daire ile tüm uç noktalarını veya kesişimleri bulabilir ve işaretleyebilir. Bir tepe noktası, bir çizginin ani bir şekilde yön değiştirdiği noktayı işaretler. Kesişim, bir vuruşun kendisiyle veya başka bir vuruşla kesiştiği bir noktayı işaretler.

Paint olayı, bir denetim yeniden çizildiğinde gerçekleşir.

Not

Örnek, formun Refresh yöntemini kullanarak bir çizgi silindiğinde veya uygulama modu değiştiğinde formun kendisini yeniden çizmesini zorlar.

 

private void InkErase_OnPaint(object sender, PaintEventArgs e)
{
    Strokes strokesToPaint = myInkCollector.Ink.Strokes;

    myInkCollector.Renderer.Draw(e.Graphics, strokesToPaint);

    switch (mode)
    {
        case ApplicationMode.CuspErase:
            PaintCusps(e.Graphics, strokesToPaint);
            break;
        case ApplicationMode.IntersectErase:
            PaintIntersections(e.Graphics, strokesToPaint);
            break;
    }
}

PaintCuspsiçinde, kod her vuruştaki her bir cusp içinde yinelenir ve etrafına kırmızı bir daire çizer. Vuruşun PolylineCusps özelliği, bir stok içindeki noktaların cusps'a karşılık gelen dizinlerini döndürür. Ayrıca, noktayı DrawEllipse yöntemiyle ilgili koordinatlara dönüştüren oluşturucu nesnesinin InkSpaceToPixel yöntemine de dikkat edin.

private void PaintCusps(Graphics g, Strokes strokesToPaint)
{
    foreach (Stroke currentStroke in strokesToPaint)
    {
        int[] cusps = currentStroke.PolylineCusps;

        foreach (int i in cusps)
        {
            Point pt = currentStroke.GetPoint(i);

            // Convert the X, Y position to Window based pixel coordinates
            myInkCollector.Renderer.InkSpaceToPixel(g, ref pt);

            // Draw a red circle as the cusp position
            g.DrawEllipse(Pens.Red, pt.X-3, pt.Y-3, 6, 6);
        }
    }
}

PaintIntersectionsiçinde kod, tüm vuruş kümesiyle kesişimlerini bulmak için her vuruşta yinelenir. Vuruşun FindIntersections yöntemine Strokes koleksiyonu geçirildiğini ve kesişimleri temsil eden kayan nokta dizin değerleri dizisi döndürdüğünü unutmayın. Kod daha sonra her kesişim için bir X-Y koordinatı hesaplar ve etrafına kırmızı bir daire çizer.

private void PaintIntersections(Graphics g, Strokes strokesToPaint)
{
    foreach (Stroke currentStroke in strokesToPaint)
    {
        float[] intersections =            currentStroke.FindIntersections(strokesToPaint);
    }
}

İki Ucu Olan Bir Kalemi İşleme

CursorDown, NewPacketsve Stroke olayları için InkCollector nesnesi için üç olay işleyicisi tanımlanır. Her olay işleyicisi, kalemin hangi ucunun kullanıldığını görmek için İmleci nesnesinin Ters özelliğini denetler. Kalem ters çevrildiğinde:

  • myInkCollector_CursorDown yöntemi, vuruşu saydam hale getirir.
  • myInkCollector_NewPackets yöntemi vuruşları siler.
  • myInkCollector_Stroke yöntemi olayı iptal eder. NewPackets olayları, Stroke olayından önce oluşturulur.

İmleci İzleme

Kullanıcının kalem veya fare kullanıp kullanmadığı MouseMove olayları oluşturulur. MouseMove olay işleyicisi önce geçerli modun bir silme modu olup olmadığını ve herhangi bir fare düğmesine basılıp basılmadığını denetler; eğer bu durumlar mevcut değilse, olayı yoksayar. Ardından olay işleyicisi, oluşturucu nesnesinin PixelToInkSpace yöntemini kullanarak imlecin piksel koordinatlarını mürekkep alanı koordinatlarına dönüştürür ve geçerli silme moduna bağlı olarak kodun silme yöntemlerinden birini çağırır.

Vuruşları Silme

EraseStrokes yöntemi, imlecin konumunu mürekkep alanında alır ve HitTestRadius birim içinde bir vuruş koleksiyonu oluşturur. currentStroke parametresi silinmemesi gereken bir Stroke nesnesi belirtir. Ardından strokes koleksiyonu toplayıcıdan silinir ve form yeniden çizilir.

private void EraseStrokes(Point pt, Stroke currentStroke)
{
    Strokes strokesHit = myInkCollector.Ink.HitTest(pt, HitTestRadius);

    if (null!=currentStroke && strokesHit.Contains(currentStroke))
    {
        strokesHit.Remove(currentStroke);
    }

    myInkCollector.Ink.DeleteStrokes(strokesHit);

    if (strokesHit.Count > 0)
    {
        this.Refresh();
    }
}

Kesişimlerde Silme

EraseAtIntersections yöntemi, test yarıçapı içindeki her vuruş üzerinde yinelenir ve bu vuruşla koleksiyondaki diğer tüm vuruşlar arasında bir kesişim dizisi oluşturur. Kesişimler bulunamazsa, tüm vuruş silinir; aksi takdirde, vuruşta test noktasına en yakın nokta bulunur ve bu noktadan itibaren, noktanın her iki tarafındaki kesişimler bulunur ve kaldırılacak segment tanımlanır.

Stroke nesnesinin Split yöntemi, segmenti vuruşun geri kalanından ayırmak için kullanılır ve ardından segment silinir ve vuruşun geri kalanı olduğu gibi bırakılır. EraseStrokes'de olduğu gibi, yöntem döndürmeden önce form yeniden çizilir.

private void EraseAtIntersections(Point pt)
{
    Strokes strokesHit = myInkCollector.Ink.HitTest(pt, HitTestRadius);

    foreach (Stroke currentStroke in strokesHit)
    {
        float[] intersections = currentStroke.FindIntersections(myInkCollector.Ink.Strokes);
        ...
        float findex = currentStroke.NearestPoint(pt);
        ...
        strokeToDelete = currentStroke.Split(intersections[i]);
        ...
    }
    ...
}

Dönüm Noktalarında Silme

Test yarıçapı içindeki her vuruş için, EraseAtCusps yöntemi, Stroke nesnesinin PolylineCusps metodundan cusp dizisini alır. Vuruşun her ucu da bir cusp'tır, bu nedenle vuruşta yalnızca iki sümük varsa, vuruşun tamamı silinir; aksi takdirde, vuruşta test noktasına en yakın nokta bulunur ve bundan sonra, noktanın her iki tarafındaki kesişimler bulunur ve kaldırılacak segment açıklanır.

Stroke nesnesinin Split yöntemi, segmenti vuruşun geri kalanından ayırmak için kullanılır ve ardından segment silinir ve vuruşun geri kalanı olduğu gibi bırakılır. EraseStrokes'de olduğu gibi, yöntem döndürmeden önce form yeniden çizilir.

private void EraseAtCusps(Point pt)
{
    ...
    strokesHit = myInkCollector.Ink.HitTest(pt, HitTestRadius);
    
    foreach (Stroke currentStroke in strokesHit)
    {
        int[] cusps = currentStroke.PolylineCusps;
        ...
        float findex = currentStroke.NearestPoint(pt);
        ...
        strokeToDelete = currentStroke.Split(cusps[i]); 
        myInkCollector.Ink.DeleteStroke(strokeToDelete);
        ...
    }
    ...
}

Formu Kapatma

Formun Dispose yöntemi, InkCollector nesnesini myInkCollectoryok eder.