Ошибка отсечения рисования .Net - PullRequest
2 голосов
/ 19 августа 2008

Функция GDI + DrawLines имеет ошибку отсечения, которая может быть воспроизведена с помощью следующего кода на c #. При выполнении кода появляются два пути строки, которые должны быть идентичны, поскольку оба они находятся внутри области отсечения. Но когда задана область отсечения, один из отрезков линии не рисуется.

protected override void OnPaint(PaintEventArgs e)
{
   PointF[] points = new PointF[] { new PointF(73.36f, 196), 
             new PointF(75.44f, 32), 
             new PointF(77.52f, 32), 
             new PointF(79.6f, 196), 
             new PointF(85.84f, 196) };

   Rectangle b = new Rectangle(70, 32, 20, 164);         
   e.Graphics.SetClip(b);
   e.Graphics.DrawLines(Pens.Red, points); // clipped incorrectly
   e.Graphics.TranslateTransform(80, 0);
   e.Graphics.ResetClip();
   e.Graphics.DrawLines(Pens.Red, points);
 }

Устранение этой проблемы разрешено настройкой режима antials на графическом объекте. Но это не настоящее решение.

Кто-нибудь знает об обходном пути?

Ответы [ 3 ]

3 голосов
/ 20 августа 2008

Похоже, это известная ошибка ...

Следующий код работает, как вы просили:

protected override void OnPaint(PaintEventArgs e)
    {
        PointF[] points = new PointF[] { new PointF(73.36f, 196), 
         new PointF(75.44f, 32), 
         new PointF(77.52f, 32), 
         new PointF(79.6f, 196), 
         new PointF(85.84f, 196) };

        e.Graphics.SmoothingMode =  System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
        Rectangle b = new Rectangle(70, 32, 20, 165);
        e.Graphics.SetClip(b);
        e.Graphics.DrawLines(Pens.Red, points); // clipped incorrectly
        e.Graphics.TranslateTransform(80, 0);
        e.Graphics.ResetClip();           
        e.Graphics.DrawLines(Pens.Red, points);
    }

Примечание. Антилайя добавила строку и расширила область обрезки на 1

.

похоже, что могут помочь следующие обходные пути (хотя и не проверенные):

  • Ручка имеет толщину более одного пикселя
  • Линия идеально горизонтальная или вертикальная
  • Отсечение по границам окна, а не по прямоугольнику клипа

Ниже приведен список статей, которые могут / или могут снова не помочь:

http://www.tech -archive.net / PDF / Архив / Разработка / microsoft.public.win32.programmer.gdi / 2004-08 / 0350.pdf http://www.tech -archive.net / Архив / Разработка / microsoft.public.win32.programmer.gdi / 2004-08 / 0368.html

OR ...

возможно также следующее:

protected override void OnPaint ( PaintEventArgs e )
    {
        PointF[] points = new PointF[] { new PointF(73.36f, 196), 
         new PointF(75.44f, 32), 
         new PointF(77.52f, 32), 
         new PointF(79.6f, 196), 
         new PointF(85.84f, 196) };

        Rectangle b = new Rectangle( 70, 32, 20, 164 );
        Region reg = new Region( b );
        e.Graphics.SetClip( reg, System.Drawing.Drawing2D.CombineMode.Union);
        e.Graphics.DrawLines( Pens.Red, points ); // clipped incorrectly
        e.Graphics.TranslateTransform( 80, 0 );
        e.Graphics.ResetClip();
        e.Graphics.DrawLines( Pens.Red, points );
    }

Это эффективно обрезает, используя область, объединенную / объединенную (я думаю) с ClientRectangle canvas / Control. Поскольку область отличается от прямоугольника, результаты должны соответствовать ожидаемым. Этот код может быть доказан для работы, добавив

e.Graphics.FillRectangle( new SolidBrush( Color.Black ), b );

после вызова setClip (). Это ясно показывает, что черный прямоугольник появляется только в обрезанной области.

Это может быть допустимым обходным решением, если сглаживание линии не является вариантом.

Надеюсь, это поможет

0 голосов
/ 19 августа 2008

Ошибка в том, что оба отрезка линии должны быть нарисованы одинаково, но это не так, потому что пик, который рисуется в области отсечения, полностью находится в области отсечения и не должен каким-либо образом вырезаться, но это так. Это очень раздражает, но это приводит к тому, что любое программное обеспечение, которое сильно использует прорисовку + усечение, выглядит непрофессионально из-за пробелов, которые могут появиться в многоугольниках.

0 голосов
/ 19 августа 2008

В чем дело с кодом?

Хорошо, вопрос должен быть ... что должен делать код, которого он не делает.

Когда я запускаю код, я вижу 2 красных «шипа», неужели я не мент?

Похоже, вы рисуете первый всплеск в области ограниченного прямоугольника, проверенный путем добавления следующего после объявления Rectangle:

e.Graphics.FillRectangle( new SolidBrush( Color.Black ), b );

Затем вы выполняете перевод, сбрасываете клип, поэтому в этот момент я предполагаю, что clientRectangle используется в качестве соответствующей области клипа, а затем пытаюсь повторить преобразованный скачок. Где ошибка?!?

...