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

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

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 ]

3 голосов
/ 21 декабря 2010

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

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

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

 myPen2->DashOffset = i*ellipseCircumference;

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

1 голос
/ 21 декабря 2010

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

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
    }
}
...