Почему рисование эллипса с помощью набора 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
}
}