问题描述
我一直在寻找一个已经存在的预制函数,用于创建一个不会引起如下所示的撕裂/滑动的圆角矩形。归功于@György Kőszeg。如果矩形足够大,此功能可以正常工作。当您开始缩小矩形时,您会遇到如下图所示的问题。我正在为此寻找简单的解决方法。
如果此问题在本网站上,但我错过了,我很抱歉再次提出要求。 (我记得曾经在这里或在另一个网站上问过这个问题,并且收到了一个非常有效的答案)。这个问题已经使我很久了(再次)。
public static GraphicsPath RoundedRect(Rectangle bounds,int radius)
{
int diameter = radius * 2;
Size size = new Size(diameter,diameter);
Rectangle arc = new Rectangle(bounds.Location,size);
GraphicsPath path = new GraphicsPath();
if (radius == 0)
{
path.AddRectangle(bounds);
return path;
}
// top left arc
path.AddArc(arc,180,90);
// top right arc
arc.X = bounds.Right - diameter;
path.AddArc(arc,270,90);
// bottom right arc
arc.Y = bounds.Bottom - diameter;
path.AddArc(arc,90);
// bottom left arc
arc.X = bounds.Left;
path.AddArc(arc,90,90);
path.CloseFigure();
return path;
}
更新:
同时,我开始使用下面的代码,如果宽度小于高度,则该代码将覆盖矩形。这将创建一个完美的圆(最小的圆角矩形可以没有毛刺/撕裂)。对此发表了评论,我不应该使用“撕裂”,因为它仅仅是由我理解的数学引起的,但是我真的不知道该图像中的毛刺矩形还有什么。
基本上,我希望使用椭圆形而不是圆形来正确反射“ Exp”值。
public static GraphicsPath RoundedRect(Rectangle bounds,size);
GraphicsPath path = new GraphicsPath();
//new code here//
if(bounds.Height >= bounds.Width)
{
bounds.Width = bounds.Height;
}
if (radius >= diameter) {
path.AddRectangle(bounds);
return path;
}
// top left arc
path.AddArc(arc,90);
// top right arc
arc.X = bounds.Right - diameter;
path.AddArc(arc,90);
// bottom right arc
arc.Y = bounds.Bottom - diameter;
path.AddArc(arc,90);
// bottom left arc
arc.X = bounds.Left;
path.AddArc(arc,90);
path.CloseFigure();
return path;
}
解决方法
类似的方法可能会更好。尝试使用curveSize
的各种值。请注意,curveSize
必须在1到rect.Width / 4和rect.Height / 4的最小值之间:
public static GraphicsPath RoundedRect(Rectangle rc,float curveSize)
{
if (curveSize < 0 || curveSize > rc.Height / 4.0f || curveSize > rc.Width / 4.0f)
curveSize = 0;
var result = new GraphicsPath();
if (curveSize > 0)
{
float size4 = curveSize * 4;
result.AddArc(rc.Right - size4,rc.Top,size4,270,90);
result.AddArc(rc.Right - size4,rc.Bottom - size4,90);
result.AddArc(rc.Left,90,180,90);
result.CloseFigure();
}
else if (rc.Width > 0 && rc.Height > 0)
{
result.AddRectangle(rc);
}
return result;
}