vb.net 如何在VB.NET中绘制圆弧

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19779568/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 15:43:01  来源:igfitidea点击:

How to draw circular arcs in VB.NET

vb.netgeometric-arc

提问by shad0w_wa1k3r

I have to generate the following figure according to user fed values. How do I go about drawing the arcs (B-C-F as in figure, circular in nature) given their start point & end point (B & F respectively) & the height from the segment BF? I can do some geometric calculations & get the radius & all, but how do I draw the arc?

我必须根据用户输入的值生成下图。给定起点和终点(分别为 B 和 F)以及线段 BF 的高度,我该如何绘制圆弧(图中的 BCF,本质上是圆形)?我可以做一些几何计算并获得半径和所有,但我如何绘制弧线?

enter image description here

在此处输入图片说明

I have tried using the Graphics.DrawCurve()method, but it doesn't work as expected. How can I make this method work for circular arcs? Any other workaround is also welcome.

我已经尝试使用该Graphics.DrawCurve()方法,但它没有按预期工作。如何使此方法适用于圆弧?也欢迎任何其他解决方法。

回答by Idle_Mind

From my comment:

从我的评论:

If you have computed the necessary radius to generate the curve, then simply draw the entire circle with Graphics.DrawEllipse(), but use Graphics.SetClip() and pass a rectangle using the points B and F as a side and computing the other two points using the height C. This will clip the entire circle to just the part visible within that rectangle. Then call Graphics.ResetClip() and draw the rest of the lines. Repeat the SetClip() trick to draw the curve at the bottom as well.

如果您已经计算了生成曲线所需的半径,那么只需使用 Graphics.DrawEllipse() 绘制整个圆,但使用 Graphics.SetClip() 并使用点 B 和 F 作为边传递一个矩形并计算其他两个使用高度 C 的点。这会将整个圆剪辑到该矩形内可见的部分。然后调用 Graphics.ResetClip() 并绘制其余的线。重复 SetClip() 技巧以在底部绘制曲线。

Here's a proof of concept for the top curve thru B, C, and F.

这是通过 B、C 和 F 的顶部曲线的概念证明。

I used the formulas provided by Donna Roberts at Investigative Circle Activity Using Three Points.

我使用了 Donna Roberts 在Investigative Circle Activity Using Three Points 中提供的公式。

Here's a screenshot:

这是一个屏幕截图:

Partial Circle thru Three Points

通过三点的部分圆

...and the code that produced it:

...以及产生它的代码:

Public Class Form1

    Private B As New Point(50, 100)
    Private F As New Point(250, 100)
    Private DistanceFromBF As Integer = 50

    Private Sub Form1_Paint(sender As System.Object, e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
        If B.Y = F.Y Then
            Dim C As New Point(B.X + (F.X - B.X) / 2, B.Y - DistanceFromBF)
            Dim ctr As Point
            Dim rad As Double
            CircleFromPointsOnCircumference(B, C, F, ctr, rad)

            Dim rc As New Rectangle(ctr, New Size(1, 1))
            rc.Inflate(rad, rad)
            e.Graphics.DrawRectangle(Pens.Black, rc)

            Dim clip As New Rectangle(New Point(B.X, B.Y - DistanceFromBF), New Size(F.X - B.X, DistanceFromBF))
            e.Graphics.SetClip(clip)
            e.Graphics.DrawEllipse(Pens.Green, rc)

            e.Graphics.ResetClip()
            DrawPoint(B, e.Graphics, Color.Red)
            DrawPoint(C, e.Graphics, Color.Red)
            DrawPoint(F, e.Graphics, Color.Red)
            DrawPoint(ctr, e.Graphics, Color.Green)
        End If
    End Sub

    Private Sub DrawPoint(ByVal pt As Point, ByVal G As Graphics, ByVal clr As Color)
        Dim rc As New Rectangle(pt, New Size(1, 1))
        rc.Inflate(3, 3)
        Using brsh As New SolidBrush(clr)
            G.FillEllipse(brsh, rc)
        End Using
    End Sub

    Private Sub CircleFromPointsOnCircumference(ByVal ptA As Point, ByVal ptB As Point, ByVal ptC As Point, ByRef Center As Point, ByRef Radius As Double)
        Dim mR As Double = CDbl(ptA.Y - ptB.Y) / CDbl(ptA.X - ptB.X)
        Dim mT As Double = CDbl(ptC.Y - ptB.Y) / CDbl(ptC.X - ptB.X)
        Dim X As Double = (mR * mT * (ptC.Y - ptA.Y) + mR * (ptB.X + ptC.X) - mT * (ptA.X + ptB.X)) / CDbl(2) * (mR - mT)
        Dim Y As Double = CDbl(-1) / mR * (X - CDbl(ptA.X + ptB.X) / CDbl(2)) + (CDbl(ptA.Y + ptB.Y) / CDbl(2))
        Center = New Point(X, Y)
        Radius = Math.Sqrt(Math.Pow(ptA.X - Center.X, 2) + Math.Pow(ptA.Y - Center.Y, 2))
    End Sub

End Class

回答by shad0w_wa1k3r

Got it! Thanks @Mitch & @Idle_Mind

知道了!谢谢@Mitch & @Idle_Mind

Using the builtin DrawArcmethod of Graphics

使用内置DrawArc方法Graphics

Friend Function draw_tank() As Boolean

    ' Create pen. 
    Dim blackPen As New Pen(Color.Black, 3)

    ' Create rectangle to bound ellipse. 
    Dim rect As New Rectangle(100, 100, 200, 200)
    ' Keeping the width & length same (200) we get a circle

    ' Create start and sweep angles on ellipse. 
    Dim startAngle As Single = 225.0F
    Dim sweepAngle As Single = 90.0F

    ' Draw arc to screen.
    Dim myarc As Graphics = Me.CreateGraphics
    myarc.DrawArc(blackPen, rect, startAngle, sweepAngle)

    Return True
End Function

Suggestions/Improvements welcome.

欢迎提出建议/改进。

Note - This isn't the actual function from my code.

注意 - 这不是我的代码中的实际功能。