Сведения о вопросе

GANGST1ER

09:18, 4th August, 2020

Теги

Ошибка отсечения чертежа .Net

Просмотров: 497   Ответов: 3

Функция 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);
 }

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

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



  Сведения об ответе

dumai

20:51, 6th August, 2020

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

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

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);
    }

Примечание: Я сделал AntiAlias ' в строке и расширил область отсечения на 1

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

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

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

http://www.tech-archive.net/pdf/Archive/Development/microsoft.public.win32.programmer.gdi/2004-08/0350.pdf http://www.tech-archive.net/Archive/Development/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(). Это ясно показывает, что черный прямоугольник появляется только в обрезанной области.

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

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


  Сведения об ответе

fo_I_K

15:49, 27th August, 2020

Что же, по-видимому, случилось с кодом?

OK, вопрос должен быть таким... что должен делать код, чего он уже не делает?

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

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

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

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


  Сведения об ответе

SSESION

06:53, 23rd August, 2020

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


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться