【问题标题】:How to draw a rounded rectangle with width less than height? C#如何绘制宽度小于高度的圆角矩形? C#
【发布时间】:2020-12-19 08:09:44
【问题描述】:

我一直在寻找一个已经预制的函数来创建一个不会像下面那样导致撕裂/故障的圆角矩形。归功于@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, 0, 90);

        // bottom left arc 
        arc.X = bounds.Left;
        path.AddArc(arc, 90, 90);

        path.CloseFigure();
        return path;
    }


更新:

与此同时,我已经开始使用下面的代码,如果宽度小于高度,它将覆盖矩形。这将创建一个完美的圆形(最小的圆角矩形可以是没有毛刺/撕裂)。对此发表了评论,声明我不应该使用“撕裂”,因为它只是由我理解的数学引起的,但我真的不知道还有什么可以称呼图像中的故障矩形。

基本上我想要一个椭圆而不是圆形来正确反映“Exp”值。

    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();
        
        //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, 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, 0, 90); 
        
        // bottom left arc  
        arc.X = bounds.Left;
        path.AddArc(arc, 90, 90);
        path.CloseFigure();
        return path;
    }

【问题讨论】:

  • 您显示的图像看起来一点也不像撕裂。它看起来像一个计算错误.. - 另外:当宽度小于直径时应该发生什么??
  • @TaW,我没有说我的措辞百分百正确。我看到它不是“撕裂”,但很明显它没有按照应有的方式呈现。如果宽度小于直径,那么它应该在条形图中显示一个小点,而不是看起来很奇怪的“I”。我过去已经纠正了这个问题,但它需要很多我没有保存的糟糕计算。我正在寻找一个基本上可以自行解决此问题的功能。 (修正了你的话中的“计算错误”。)
  • 它没有按应有的方式呈现。 我会说路径设置不正确。不要让 rectangle.Width 变得小于直径。
  • 或者试试这个:if (radius >= diameter) { path.AddRectangle(bounds); return path; } // top left arc arc.X = bounds.Left - diameter; 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, 0, 90); // bottom left arc arc.X = bounds.Left - diameter; path.AddArc(arc, 90, 90);
  • 这会导致圆角矩形放置在我想要的位置的偏移处。虽然我希望杆保持圆形并且比其自身的直径收缩得更远,但我只需要杆的最小高度就足够了。 if(bounds.Height >= bounds.Width){bounds.Width = bounds.Height;}(仅在宽度小于高度时覆盖。)

标签: c# bitmap discord rectangles system.drawing


【解决方案1】:

这样的事情可能会更好。尝试使用 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, size4, 270, 90);
        result.AddArc(rc.Right - size4, rc.Bottom - size4, size4, size4, 0, 90);
        result.AddArc(rc.Left, rc.Bottom - size4, size4, size4, 90, 90);
        result.AddArc(rc.Left, rc.Top, size4, size4, 180, 90);

        result.CloseFigure();
    }
    else if (rc.Width > 0 && rc.Height > 0)
    {
        result.AddRectangle(rc);
    }

    return result;
}

【讨论】:

  • 虽然这解决了撕裂问题,但我似乎无法像图像那样制作圆角矩形。我只能设法使矩形弯曲一定量。 (更多盒子喜欢)
  • @ViperzSmurfz 很遗憾,我看不到图片,因为该网站在我的工作网络上被屏蔽了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多