为什么不用Pen :: DashPattern设置绘制椭圆会产生预期的结果?

时间:2010-11-24 18:00:20

标签: .net winforms c++-cli drawing drawellipse

我正试图(简单地)绘制一些沿椭圆路径旋转的线条,并认为我有一个很好的简单方法。不幸的是,我的解决方案似乎存在一些问题:

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 个答案:

答案 0 :(得分:3)

这可能是众多GDI +中的一个。这是由于Antialiasing与DashPattern相结合。虽然有趣(好吧,有点......),如果你删除SmoothingMode = AntiAlias,你会得到一个精彩的OutOfMemoryException(如果你谷歌上的“gdi + pattern outofmemoryexception”,你会发现数百个。真糟糕。< / p>

由于GDI +没有真正维护(尽管它也用于.NET Framework Winforms,BTW我用.NET C#重现了你的问题),因为这个链接可以告诉我们:Pen.DashPattern throw OutOfMemoryException using a default pen,你唯一可能的方法解决这个问题的方法是尝试各种价值观。

例如,如果您使用此更改DashOffset设置:

 myPen2->DashOffset = i*ellipseCircumference;

你会产生一组很好的椭圆,所以也许你可以找到一个非常适合你的组合。祝你好运: - )

答案 1 :(得分:1)

我无法想象它会解​​决问题,但你可以从循环中进行大量的处理:

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