4

I'm trying to (simply) draw some lines rotating along an ellipse path and thought I had a nice easy way of doing it. Unfortunately, my solution seems to have some problems:

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

...produces:

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

...so why are the second two ellipses fully white? ...and how can I avoid the problem?

Jon Cage
  • 36,366
  • 38
  • 137
  • 215

2 Answers2

3

This is probably one of the numerous GDI+ bug. This is due to the Antialiasing combined with the DashPattern. Funny though (well, sort of...), if you remove SmoothingMode = AntiAlias, you will get get a wonderful OutOfMemoryException (and if you google on "gdi+ pattern outofmemoryexception" you'll find hundreds of these. What a mess.

Since GDI+ is not really maintained (although it's also used in .NET Framework Winforms, BTW I reproduced your problem with .NET C#), as this link can tell us: Pen.DashPattern throw OutOfMemoryException using a default pen, the only way you can probably work around this is to try various values.

For example, if you change the DashOffset setting with this instead:

 myPen2->DashOffset = i*ellipseCircumference;

You will produce a nice set of ellipses, so maybe you can find one combination that really suits you. Good luck :-)

Simon Mourier
  • 132,049
  • 21
  • 248
  • 298
  • The problem is that I have multiple different circumferences when this code is in normal operation. I can find some that work in a few instances, but I need it to work for all of them. – Jon Cage Dec 21 '10 at 22:10
  • Hmmm... That sounds bad. Can't you use something else than GDI+? Like WPF? – Simon Mourier Dec 22 '10 at 08:01
  • Our GUI's written using C++ / Windows Forms so not without a re-write. – Jon Cage Dec 26 '10 at 15:58
1

I can't imagine it will fix the problem, but you can take a lot of the processing out of the loop:

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
    }
}
Jackson Pope
  • 14,520
  • 6
  • 56
  • 80
  • The code was just an example. In reality I'm just drawing one of those ellipses at a time. I just added a few to highlight the issue. – Jon Cage Dec 21 '10 at 22:12