Почему рисование эллипса с помощью набора Pen::DashPattern не дает ожидаемого результата?

Я пытаюсь (просто) нарисовать некоторые линии, вращающиеся вдоль траектории эллипса, и подумал, что у меня есть хороший простой способ сделать это. К сожалению, мое решение, похоже, имеет некоторые проблемы:

void EllipseDisplayControl::OnPaint(PaintEventArgs^ e)
{
    Graphics^ gfx = e->Graphics;
    gfx->SmoothingMode = Drawing2D::SmoothingMode::AntiAlias;

    int width = 100;
    int height = 10;

    for( int i = 0; i < 15; i ++ )
    {
        Drawing::Pen^ myPen = (Drawing::Pen^) Drawing::Pens::RoyalBlue->Clone(); //use the standard blue as a start point
        myPen->Color = Drawing::Color::FromArgb(64, 32, 111, 144);
        myPen->Width = 3;
        myPen->DashStyle = Drawing::Drawing2D::DashStyle::Solid;
        gfx->DrawEllipse(myPen, 0, 50+i*20, width, height); // Draw the blue ring

        float ellipseCircumference = Math::PI * Math::Sqrt(2* (Math::Pow(0.5*width,2) + Math::Pow(0.5*height,2)));
        array<Single>^ pattern = {4, ellipseCircumference};

        Drawing::Pen^ myPen2 = (Drawing::Pen^) Drawing::Pens::White->Clone(); //use the standard blue as a start point
        myPen2->DashPattern = pattern;
        myPen2->DashOffset = i*10;
        gfx->DrawEllipse(myPen2, 0, 50+i*20, width, height); // Draw the rotating white dot
    }
}

... производит:

http://www.joncage.co.uk/media/img/BadPattern.png

... так почему вторые два эллипса полностью белые? ... и как я могу избежать проблемы?

2 ответа

Вероятно, это одна из многочисленных ошибок GDI+. Это связано с сглаживанием в сочетании с DashPattern. Забавно, что (ну, вроде...), если вы удалите SmoothingMode = AntiAlias, вы получите замечательное исключение OutOfMemoryException (и если вы воспользуетесь "gdi+ pattern outofmemoryexception", вы найдете сотни таких. Какой беспорядок.

Поскольку GDI+ на самом деле не поддерживается (хотя он также используется в.NET Framework Winforms, кстати, я воспроизвел вашу проблему с.NET C#), как эта ссылка может сказать нам: Pen.DashPattern выбрасывает OutOfMemoryException, используя перо по умолчанию, единственный способ, которым вы можете это сделать. вероятно, обойти это, чтобы попробовать различные значения.

Например, если вы измените настройку DashOffset с помощью этого:

 myPen2->DashOffset = i*ellipseCircumference;

Вы получите хороший набор эллипсов, так что, возможно, вы сможете найти одну комбинацию, которая действительно вам подходит. Удачи:-)

Я не могу представить, что это решит проблему, но вы можете взять большую часть обработки из цикла:

void EllipseDisplayControl::OnPaint(PaintEventArgs^ e)
{
    Graphics^ gfx = e->Graphics;
    gfx->SmoothingMode = Drawing2D::SmoothingMode::AntiAlias;

    int width = 100;  
    int height = 10;

    Drawing::Pen^ myPen = (Drawing::Pen^) Drawing::Pens::RoyalBlue->Clone(); //use the standard blue as a start point
    myPen->Color = Drawing::Color::FromArgb(64, 32, 111, 144);
    myPen->Width = 3;
    myPen->DashStyle = Drawing::Drawing2D::DashStyle::Solid;

    float ellipseCircumference = Math::PI * Math::Sqrt(2* (Math::Pow(0.5*width,2) + Math::Pow(0.5*height,2)));
    array<Single>^ pattern = {4, ellipseCircumference};

    Drawing::Pen^ myPen2 = (Drawing::Pen^) Drawing::Pens::White->Clone(); //use the standard blue as a start point
    myPen2->DashPattern = pattern;

    for( int i = 0; i < 15; i ++ )
    {
        gfx->DrawEllipse(myPen, 0, 50+i*20, width, height); // Draw the blue ring

        myPen2->DashOffset = i*10;
        gfx->DrawEllipse(myPen2, 0, 50+i*20, width, height); // Draw the rotating white dot
    }
}
Другие вопросы по тегам