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

发布于 2024-10-03 20:55:48 字数 1418 浏览 4 评论 0原文

我试图(简单地)画一些沿着椭圆路径旋转的线,并认为我有一个很好的简单方法来做到这一点。不幸的是,我的解决方案似乎有一些问题:

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

...那么为什么后两个椭圆是全白色的? ...我怎样才能避免这个问题?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

鲸落 2024-10-10 20:55:48

这可能是众多 GDI+ 错误之一。这是由于抗锯齿与 DashPattern 相结合所致。有趣的是(好吧,有点......),如果你删除 SmoothingMode = AntiAlias,你会得到一个美妙的 OutOfMemoryException (如果你在 google 上搜索“gdi+ 模式 outofmemoryException”,你会发现数百个这样的异常。真是一团糟。

因为GDI+ 并没有真正得到维护(尽管它也在 .NET Framework Winforms 中使用,顺便说一句,我用 .NET C# 重现了您的问题),因为此链接可以告诉我们: Pen.DashPattern 使用默认笔抛出 OutOfMemoryException,这是您可能工作的唯一方法围绕这个问题的方法是尝试各种值。

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

 myPen2->DashOffset = i*ellipseCircumference;

您将生成一组漂亮的省略号,因此也许您可以找到真正适合您的组合:-)。

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 :-)

一腔孤↑勇 2024-10-10 20:55:48

我无法想象它会解​​决问题,但是您可以将大量处理从循环中取出:

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

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
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文