Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net 如何使用visual basic.NET 2绘制非常特定的环形扇区_Vb.net_Math - Fatal编程技术网

Vb.net 如何使用visual basic.NET 2绘制非常特定的环形扇区

Vb.net 如何使用visual basic.NET 2绘制非常特定的环形扇区,vb.net,math,Vb.net,Math,这个问题进一步说明了以前的一个问题。在这个问题上,我得到了一个非常好的答案,它使用了两行代码来执行所有的数学运算。我希望他也能尝试一下这个问题。尽管看起来很像,但我还是没能得到任何数学知识 我现在需要画出完全相同的环形扇形,接受这个问题中的外表面变成了矩形。我加入这个来解释我的意思。您将注意到代表插入函数的矩形的红线。这张图片实际上是我到目前为止尝试的代码生成的屏幕截图。当然,它们中的大多数都是错误的,但例如左上方的环形扇区是正确的。所有环形扇区应在矩形边缘终止,同时补偿间隙。角落案例可能需要3

这个问题进一步说明了以前的一个问题。在这个问题上,我得到了一个非常好的答案,它使用了两行代码来执行所有的数学运算。我希望他也能尝试一下这个问题。尽管看起来很像,但我还是没能得到任何数学知识

我现在需要画出完全相同的环形扇形,接受这个问题中的外表面变成了矩形。我加入这个来解释我的意思。您将注意到代表插入函数的矩形的红线。这张图片实际上是我到目前为止尝试的代码生成的屏幕截图。当然,它们中的大多数都是错误的,但例如左上方的环形扇区是正确的。所有环形扇区应在矩形边缘终止,同时补偿间隙。角落案例可能需要3分

我已经决定发布我到目前为止的代码,所以清教徒们必须闭上眼睛,因为这相当残忍:

<Extension()> Friend Sub AddAnnularSector(
    ByVal aGraphicsPath As GraphicsPath,
    ByVal aCenterPoint As PointR,
    ByVal aInnerRadius As Double,
    ByVal aOuterRectangle As RectangleF,
    ByVal aStartAngle As Double,
    ByVal aSweepAngle As Double,
    ByVal aStartGap As Double,
    ByVal aEndGap As Double)
    'Declare local variables...
    Dim tInnerStartOffset As Double = (Math.Asin(aStartGap / aInnerRadius) * 180.0R) / Math.PI
    Dim tInnerEndOffset As Double = (Math.Asin(aEndGap / aInnerRadius) * 180.0R) / Math.PI
    Dim tTestAngle1 As Double = aStartAngle + aSweepAngle - tInnerEndOffset
    If tTestAngle1 > 360.0R Then tTestAngle1 -= 360.0R
    If tTestAngle1 > 270.0R Then tTestAngle1 = 360.0R - tTestAngle1
    If tTestAngle1 > 180.0R Then tTestAngle1 -= 180.0R
    If tTestAngle1 > 90.0R Then tTestAngle1 = 180.0R - tTestAngle1
    Dim tOuterEndLength As Double = (Math.Min(aOuterRectangle.Width, aOuterRectangle.Height) / 2) / Math.Sin(tTestAngle1.ToRadians)
    Dim tTestAngle2 As Double = aStartAngle + tInnerStartOffset
    If tTestAngle2 > 360.0R Then tTestAngle2 -= 360.0R
    If tTestAngle2 > 270.0R Then tTestAngle2 = 360.0R - tTestAngle2
    If tTestAngle2 > 180.0R Then tTestAngle2 -= 180.0R
    If tTestAngle2 > 90.0R Then tTestAngle2 = 180.0R - tTestAngle2
    Dim tOuterStartLength As Double = (Math.Min(aOuterRectangle.Width, aOuterRectangle.Height) / 2) / Math.Sin(tTestAngle2.ToRadians)
    'Add the annular sector to the figure...
    aGraphicsPath.StartFigure()
    aGraphicsPath.AddArc(CSng(aCenterPoint.X - aInnerRadius), CSng(aCenterPoint.Y - aInnerRadius), CSng(aInnerRadius * 2.0R), CSng(aInnerRadius * 2.0R), CSng(aStartAngle + tInnerStartOffset), CSng(aSweepAngle - (tInnerStartOffset + tInnerEndOffset)))
    aGraphicsPath.AddLines(New PointF() {
        New PointF(CSng((aCenterPoint.X) + (Math.Cos((aStartAngle + aSweepAngle - tInnerEndOffset).ToRadians) * tOuterEndLength)), CSng((aCenterPoint.Y) + (Math.Sin((aStartAngle + aSweepAngle - tInnerEndOffset).ToRadians) * tOuterEndLength))),
        New PointF(CSng((aCenterPoint.X) + (Math.Cos((aStartAngle + tInnerStartOffset).ToRadians) * tOuterStartLength)), CSng((aCenterPoint.Y) + (Math.Sin((aStartAngle + tInnerStartOffset).ToRadians) * tOuterStartLength)))
    })
    aGraphicsPath.CloseFigure()
    Return
End Sub
你会注意到上一个问题的OuterRadius是如何变成了一个矩形的。此外,绘制的内弧与绘制的前一个外弧完全相同

编辑1:只是把代码剪掉一点,让它更清晰

编辑2:这是一张实际需要的图片,与上面只显示当前结果的图片不同

浅青色-实际将添加到GraphicsPath的图形。 深青色-图形中被外直角切割的部分。 绿色-外直角的尺寸,包括其中心点。 黄色-内半径的尺寸,包括其中心点。 粉红色-在先前对函数的调用中添加的数字,具有不同的输入,仅供参考。 编辑3:这显示了我认为是一个快速的数学解决方案

谢谢

对于wdthRect=250、hgtRect=200、INNERRR=65、startA=280.0、角度=30.0、间隙=10.0R,漂移器

这行代码:

Reg2.Intersect(Reg1)
实际上是蓝色和红色的交叉点

编辑

你的价值观:


我有一个想法,但它需要一些测试。如果你想提出建议,我有时间测试。矩形的宽度和高度相等,并且与内圈具有相同的中心?没有矩形可以有任何宽度/高度,但函数使用两者中最小的一个来形成正方形。圆心和圆是一样的。这意味着你是直接画的。我需要把它放在一个路径中,稍后在其他地方传递,没有任何区域信息。若你们看一下你们对我之前的答案的第二版,你们会发现我们必须自己做数学,因为它进入了一条路径。路径图形必须完全自我维持,创建它的函数必须删除所有不必要的位。我担心这可能是不可能的……据我所知,某个区域不支持反别名,因此它以后会绘制得非常难看,并且无法将该区域转换回GraphicsPath。我会玩一下代码,但希望渺茫。我也这么想,但正如你从我的代码中看到的,我几乎让它工作了。示例图像是使用该函数创建的路径绘制的。我只是不确定我的数学智慧是否能更进一步。我甚至不知道它为什么不能正常工作。如果你不喜欢,我会百分之百理解。我会发布另一张图片来展示我真正需要的东西,这样你就会看到我已经把它淡化了多少。我将你的代码粘贴到我的项目中,但它还没有画出任何东西。使用IsVisible是我从未想过的事情。我将删除你的绘图代码,看看剩下的代码是否行不通。我一有机会就会回来报到。感谢您的努力..绘图环ar2新点300I,300I,600I,600I,185I,185.0F,15.0F,5.0R
Reg2.Intersect(Reg1)
Private Function DrawAnnular2(ByVal pntC As Point, ByVal wdthRect As Integer, ByVal hgtRect As Integer, ByVal innerR As Integer, ByVal startA As Single, ByVal angle As Single, ByVal gap As Double) As GraphicsPath
    Dim g As Graphics
    Dim pth As New GraphicsPath
    Dim pthRct As New GraphicsPath
    Dim pthFinal As New GraphicsPath
    Dim fe, theta, dbl As Double
    Dim outerR, wdth As Integer
    Dim rect As Rectangle
    Dim lst1 As New List(Of Integer)
    Dim lst2 As New List(Of Integer)
    Dim lst3 As New List(Of Integer)
    Dim lst4 As New List(Of Integer)
    Dim i As Integer
    Dim lstBl(3) As Boolean
    Dim position As Integer

    lstBl(0) = False
    lstBl(1) = False
    lstBl(2) = False
    lstBl(3) = False

    wdth = Math.Min(wdthRect, hgtRect)

    outerR = CInt(Math.Sqrt(2.0R * (CDbl(wdth) / 2.0R) * (CDbl(wdth) / 2.0R))) 'πυθαγόρειο θεώρημα

    rect.X = CInt(CDbl(pntC.X) - CDbl(wdth) / 2.0R)
    rect.Y = CInt(CDbl(pntC.Y) - CDbl(wdth) / 2.0R)
    rect.Width = wdth
    rect.Height = wdth
    pthRct.AddRectangle(rect)

    '////////////////////////////////////////////////////////
    g = Me.CreateGraphics
    g.SmoothingMode = SmoothingMode.AntiAlias

    gap /= 2.0R

    dbl = gap / CDbl(outerR)

    theta = Math.Asin(dbl) * 180.0R / Math.PI

    fe = theta

    If CDbl(angle) - 2.0R * fe >= 360.0R Then
        pthFinal.AddEllipse(pntC.X - innerR, pntC.Y - innerR, 2 * innerR, 2 * innerR)
        pthFinal.AddRectangle(rect)

        g.FillPath(Brushes.Aqua, pthFinal)
        g.DrawPath(Pens.Red, pthRct)

        pthRct.Dispose()
        pth.Dispose()
        g.Dispose()

        Return pthFinal
    End If

    pth.AddArc(pntC.X - outerR, pntC.Y - outerR, 2 * outerR, 2 * outerR, startA + CSng(fe), angle - CSng(2.0R * fe)) 'Outer

    dbl = gap / CDbl(innerR)

    theta = Math.Asin(dbl) * 180.0R / Math.PI

    fe = theta

    pth.AddArc(pntC.X - innerR, pntC.Y - innerR, 2 * innerR, 2 * innerR, startA + angle - CSng(fe), -(angle - CSng(2.0R * fe))) 'Inner

    '////////////////////////////////////////////////////////////


    For i = rect.X To rect.X + wdth
        If pth.IsVisible(i, rect.Y) Then
            If lst1.Count <> 0 Then
                If i <> lst1(lst1.Count - 1) + 1 Then
                    lstBl(0) = True
                    position = lst1.Count
                End If
            End If

            lst1.Add(i)
        End If
    Next

    For i = rect.Y To rect.Y + wdth
        If pth.IsVisible(rect.X + wdth, i) Then
            If lst2.Count <> 0 Then
                If i <> lst2(lst2.Count - 1) + 1 Then
                    lstBl(1) = True
                    position = lst2.Count
                End If
            End If

            lst2.Add(i)
        End If
    Next

    For i = rect.X To rect.X + wdth
        If pth.IsVisible(i, rect.Y + wdth) Then
            If lst3.Count <> 0 Then
                If i <> lst3(lst3.Count - 1) + 1 Then
                    lstBl(2) = True
                    position = lst3.Count
                End If
            End If

            lst3.Add(i)
        End If
    Next

    For i = rect.Y To rect.Y + wdth
        If pth.IsVisible(rect.X, i) Then
            If lst4.Count <> 0 Then
                If i <> lst4(lst4.Count - 1) + 1 Then
                    lstBl(3) = True
                    position = lst4.Count
                End If
            End If

            lst4.Add(i)
        End If
    Next


    'If lstBl(0) = True Or lstBl(1) = True Or lstBl(2) = True Or lstBl(3) = True Then
        'It is a rare case that i have to work on, when angle is too large
        'MsgBox(lstBl(0).ToString + " " + lstBl(1).ToString + " " + lstBl(2).ToString + " " + lstBl(3).ToString + " ")

        'Application.Exit()
    'End If

    'TextBox1.Text = lst1.Count.ToString + " " + lst2.Count.ToString + " " + lst3.Count.ToString + " " + " " + lst4.Count.ToString

    pthFinal.AddArc(pntC.X - innerR, pntC.Y - innerR, 2 * innerR, 2 * innerR, startA + angle - CSng(fe), -(angle - CSng(2.0R * fe))) 'Inner

    If CDbl(startA) + fe >= 225.0R And CDbl(startA) + fe <= 315.0R Then '1
        If lst1.Count <> 0 Then
            If lstBl(0) = True Then
                pthFinal.AddLine(lst1(position), rect.Y, lst1(lst1.Count - 1), rect.Y)
            Else
                pthFinal.AddLine(lst1(0), rect.Y, lst1(lst1.Count - 1), rect.Y)
            End If
        End If
        If lst2.Count <> 0 Then
            pthFinal.AddLine(lst1(lst1.Count - 1), rect.Y, rect.X + wdth, lst2(lst2.Count - 1))
        End If
        If lst3.Count <> 0 Then
            pthFinal.AddLine(rect.X + wdth, lst2(lst2.Count - 1), lst3(0), rect.Y + wdth)
        End If
        If lst4.Count <> 0 Then
            pthFinal.AddLine(lst3(0), rect.Y + wdth, rect.X, lst4(0))
        End If
        If lstBl(0) = True Then
            pthFinal.AddLine(rect.X, lst4(0), lst1(position - 1), rect.Y)
        End If
    ElseIf (CDbl(startA) + fe > 315.0R And CDbl(startA) + fe <= 360.0R) Or _
           (CDbl(startA) + fe >= 0.0R And CDbl(startA) + fe <= 45.0R) Then '2

        If lst2.Count <> 0 Then
            If lstBl(1) = True Then
                pthFinal.AddLine(rect.X + wdth, lst2(position), rect.X + wdth, lst2(lst2.Count - 1))
            Else
                pthFinal.AddLine(rect.X + wdth, lst2(0), rect.X + wdth, lst2(lst2.Count - 1))
            End If
        End If
        If lst3.Count <> 0 Then
            pthFinal.AddLine(rect.X + wdth, lst2(lst2.Count - 1), lst3(0), rect.Y + wdth)
        End If
        If lst4.Count <> 0 Then
            pthFinal.AddLine(lst3(0), rect.Y + wdth, rect.X, lst4(0))
        End If
        If lst1.Count <> 0 Then
            pthFinal.AddLine(rect.X, lst4(0), lst1(lst1.Count - 1), rect.Y)
        End If
        If lstBl(1) = True Then
            pthFinal.AddLine(lst1(lst1.Count - 1), rect.Y, rect.X + wdth, lst2(position - 1))
        End If
    ElseIf CDbl(startA) + fe > 45.0R And CDbl(startA) + fe <= 135.0R Then '3
        If lst3.Count <> 0 Then
            If lstBl(2) = True Then
                pthFinal.AddLine(lst3(position - 1), rect.Y + wdth, lst3(0), rect.Y + wdth)
            Else
                pthFinal.AddLine(lst3(lst3.Count - 1), rect.Y + wdth, lst3(0), rect.Y + wdth)
            End If
        End If
        If lst4.Count <> 0 Then
            pthFinal.AddLine(lst3(0), rect.Y + wdth, rect.X, lst3(0))
        End If
        If lst1.Count <> 0 Then
            pthFinal.AddLine(rect.X, lst3(0), lst1(lst1.Count - 1), rect.Y)
        End If
        If lst2.Count <> 0 Then
            pthFinal.AddLine(lst1(lst1.Count - 1), rect.Y, rect.X + wdth, lst2(lst2.Count - 1))
        End If
        If lstBl(2) = True Then
            pthFinal.AddLine(rect.X + wdth, lst2(lst2.Count - 1), lst3(position), rect.Y + wdth)
        End If
    Else '4
        If lst4.Count <> 0 Then
            If lstBl(3) = True Then
                pthFinal.AddLine(rect.X, lst4(position - 1), rect.X, lst4(0))
            Else
                pthFinal.AddLine(rect.X, lst4(lst4.Count - 1), rect.X, lst4(0))
            End If
        End If
        If lst1.Count <> 0 Then
            pthFinal.AddLine(rect.X, lst4(0), lst1(lst1.Count - 1), rect.Y)
        End If
        If lst2.Count <> 0 Then
            pthFinal.AddLine(lst1(lst1.Count - 1), rect.Y, rect.X + wdth, lst2(lst2.Count - 1))
        End If
        If lst3.Count <> 0 Then
            pthFinal.AddLine(rect.X + wdth, lst2(lst2.Count - 1), lst3(0), rect.Y + wdth)
        End If
        If lstBl(3) = True Then
            pthFinal.AddLine(lst3(0), rect.Y + wdth, rect.X, lst4(position))
        End If
    End If


    'g.FillPath(Brushes.Blue, pth)
    g.FillPath(Brushes.Aqua, pthFinal)
    g.DrawPath(Pens.Red, pthRct)

    pthRct.Dispose()
    pth.Dispose()
    g.Dispose()

    Return pthFinal
End Function