圆角矩形半径计算

时间:2014-03-27 19:08:52

标签: vb.net winforms math graphics

我有以下代码来绘制圆角矩形。

我想使用#34; RoundnessPercent"而不是使用半径。

enter image description here

(但形状来自同一个矩形,但使用不同的"圆度百分比"值。

但是,我无法正常使用我的函数计算其余部分。 我看到各种各样的arkward圆形外观......

有数学理解的人能看看我的功能吗?

非常感谢!

Public Function RoundedRect(ByVal uRect As Rectangle, ByVal uPercent As Integer) As GraphicsPath

    Debug.Assert(uRect.Width > 0)
    Debug.Assert(uRect.Height > 0)

    Dim iMinimum As Integer
    If uRect.Width > uRect.Height Then
        iMinimum = uRect.Height
    Else
        iMinimum = uRect.Width
    End If

    Dim iRadius As Integer = ((iMinimum * uPercent) / 100) 'I think this where I introduce a flaw

    Dim nPath As New GraphicsPath
    nPath.AddLine(uRect.Left + iRadius, uRect.Top, uRect.Right - iRadius, uRect.Top)
    nPath.AddArc(Rectangle.FromLTRB(uRect.Right - iRadius, uRect.Top, uRect.Right, uRect.Top + iRadius), -90, 90)
    nPath.AddLine(uRect.Right, uRect.Top + iRadius, uRect.Right, uRect.Bottom - iRadius)
    nPath.AddArc(Rectangle.FromLTRB(uRect.Right - iRadius, uRect.Bottom - iRadius, uRect.Right, uRect.Bottom), 0, 90)
    nPath.AddLine(uRect.Right - iRadius, uRect.Bottom, uRect.Left + iRadius, uRect.Bottom)
    nPath.AddArc(Rectangle.FromLTRB(uRect.Left, uRect.Bottom - iRadius, uRect.Left + iRadius, uRect.Bottom), 90, 90)
    nPath.AddLine(uRect.Left, uRect.Bottom - iRadius, uRect.Left, uRect.Top + iRadius)
    nPath.AddArc(Rectangle.FromLTRB(uRect.Left, uRect.Top, uRect.Left + iRadius, uRect.Top + iRadius), 180, 90)
    nPath.CloseFigure()

    Return nPath

End Function

我得到的是这个(在更改建议之后):

enter image description here

2 个答案:

答案 0 :(得分:1)

这就是我重新设计AddArc坐标的方法,基本上是调整角矩形的大小:

Dim factor As Decimal = uPercent / 100

Dim nPath As New GraphicsPath
nPath.StartFigure()
nPath.AddArc(New Rectangle(uRect.Right - (uRect.Width * factor),
                           uRect.Top,
                           uRect.Width * factor,
                           uRect.Height * factor), -90, 90)
nPath.AddArc(New Rectangle(uRect.Right - (uRect.Width * factor),
                           uRect.Bottom - (uRect.Height * factor),
                           uRect.Width * factor,
                           uRect.Height * factor), 0, 90)
nPath.AddArc(New Rectangle(uRect.Left,
                           uRect.Bottom - (uRect.Height * factor),
                           uRect.Width * factor,
                           uRect.Height * factor), 90, 90)
nPath.AddArc(New Rectangle(uRect.Left,
                           uRect.Top,
                           uRect.Width * factor,
                           uRect.Height * factor), 180, 90)
nPath.CloseFigure()
Return nPath

我的结果使用99%:

enter image description here

我在这里恢复了最小尺寸:

Public Function RoundedRect(ByVal uRect As Rectangle, ByVal uPercent As Integer) As GraphicsPath
  Dim minSize As Integer = Math.Min(uRect.Width, uRect.Height) * (uPercent / 100)
  Dim nPath As New GraphicsPath
  nPath.StartFigure()
  nPath.AddArc(New Rectangle(uRect.Right - minSize, uRect.Top, minSize, minSize), -90, 90)
  nPath.AddArc(New Rectangle(uRect.Right - minSize, uRect.Bottom - minSize, minSize, minSize), 0, 90)
  nPath.AddArc(New Rectangle(uRect.Left, uRect.Bottom - minSize, minSize, minSize), 90, 90)
  nPath.AddArc(New Rectangle(uRect.Left, uRect.Top, minSize, minSize), 180, 90)
  nPath.CloseFigure()
  Return nPath
End Function

enter image description here

答案 1 :(得分:0)

这是解决方案:

Public Function RoundedRect(ByVal uRect As Rectangle, ByVal uPercent As Integer) As GraphicsPath

    Debug.Assert(uRect.Width > 0)
    Debug.Assert(uRect.Height > 0)

    Dim iMinimum As Integer
    If uRect.Width > uRect.Height Then
        iMinimum = uRect.Height
    Else
        iMinimum = uRect.Width
    End If

    Dim iRadius As Integer = iMinimum * (uPercent / 100)
    iRadius = Math.Max(iRadius, 1)

    Dim nPath As New GraphicsPath
    nPath.AddLine(uRect.Left + (iRadius \ 2), uRect.Top, uRect.Right - (iRadius \ 2), uRect.Top) 'top line
    nPath.AddArc(Rectangle.FromLTRB(uRect.Right - iRadius, uRect.Top, uRect.Right, uRect.Top + iRadius), -90, 90)
    nPath.AddLine(uRect.Right, uRect.Top + (iRadius \ 2), uRect.Right, uRect.Bottom - (iRadius \ 2)) 'right line
    nPath.AddArc(Rectangle.FromLTRB(uRect.Right - iRadius, uRect.Bottom - iRadius, uRect.Right, uRect.Bottom), 0, 90)
    nPath.AddLine(uRect.Right - (iRadius \ 2), uRect.Bottom, uRect.Left + (iRadius \ 2), uRect.Bottom) 'bottom line
    nPath.AddArc(Rectangle.FromLTRB(uRect.Left, uRect.Bottom - iRadius, uRect.Left + iRadius, uRect.Bottom), 90, 90)
    nPath.AddLine(uRect.Left, uRect.Bottom - (iRadius \ 2), uRect.Left, uRect.Top + (iRadius \ 2)) 'left line
    nPath.AddArc(Rectangle.FromLTRB(uRect.Left, uRect.Top, uRect.Left + iRadius, uRect.Top + iRadius), 180, 90)
    nPath.CloseFigure()

    Return nPath

End Function