首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用visual basic .NET绘制非常具体的环形扇区

如何使用visual basic .NET绘制非常具体的环形扇区
EN

Stack Overflow用户
提问于 2014-09-08 10:35:02
回答 1查看 618关注 0票数 0

来了..。我需要在VisualBasic.NET中使用GraphicsPath绘制几个环形扇区。

例如,我会输入环形扇形的外径和内径/半径,以及起始和结束度/辐射度。然后,函数必须返回一个GraphicsPath,该GraphicsPath可以简单地作为封闭形状添加到另一个GraphicsPath中。这似乎很容易做到,但我需要它保持一个5像素之间的环形扇区之间的差距。

我会解释更多..。例如,如果我输入0度作为起点,360度作为结束点,它必须返回一个环形扇区,该扇区从X度开始(其中X是从0度偏移的2.5像素),以Y度结束(其中Y是从360度偏移的-2.5像素)。环形扇形的内外曲线都必须符合上述要求。它基本上就像我画了两条平行线,5像素通过圆心进入的程度,并使用这些线作为开始和结束点的弧线。这必须适用于任何进入的学位。

这篇文章:SVG donut slice as path element (annular sector)几乎解决了这个问题,但它将所有环形扇区从中心点(不像皮片)画向外,如果每次以1度将它们分开,则连续的外部环之间的间隙会越来越大(另外,这是用于SVG的)。

我包括一张图片,解释我想说得更好的东西:https://onedrive.live.com/redir?resid=79292E5BC057FE03!112&authkey=!AMnkq0bjbsH4BwU&v=3&ithint=photo%2cjpg

这个问题由valter解决。向下滚动到,在他的代码答案中编辑2

这个图片:(https://onedrive.live.com/redir?resid=79292E5BC057FE03!113&authkey=!AGxrnpf8MiiEX48&v=3&ithint=photo%2cjpg)显示了他的解决方案可以实现什么。

下面的代码用于创建用于绘制图像中的饼图和环形扇区的GraphicsPath。在编写本报告时,不支持这种负的sweepA (扫描角)。

代码语言:javascript
运行
复制
Dim p As GraphicsPath = New GraphicsPath()
p.AddPie(160.0F, 160.0F, 280.0F, 280.0F, 300.0F, 90.0F)
p.AddPath(DrawAnnular(New Point(300I, 300I), 100I, 70I, 300.0F, 90.0F, 5.0R), False)
p.AddPath(DrawAnnular(New Point(300I, 300I), 100I, 70I, 30.0F, 80.0F, 5.0R), False)
p.AddPath(DrawAnnular(New Point(300I, 300I), 135I, 105I, 300.0F, 90.0F, 5.0R), False)
p.AddPath(DrawAnnular(New Point(300I, 300I), 135I, 105I, 30.0F, 80.0F, 5.0R), False)

谢谢

漂流者

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-09-08 20:00:48

pntC是中心。outerR和innerR是半径。startA和endA是角度。角度由x轴顺时针测量。

代码语言:javascript
运行
复制
Private Sub DrawAnnular(ByVal pntC As Point, ByVal outerR As Integer, ByVal innerR As Integer, ByVal startA As Integer, ByVal endA As Integer)
    Dim g As Graphics
    Dim mypen As New Pen(Color.FromKnownColor(KnownColor.Control), 1) 'the form back color
    Dim mybrush As New SolidBrush(Color.FromKnownColor(KnownColor.Control)) 'the form back color

    g = Me.CreateGraphics
    g.SmoothingMode = SmoothingMode.AntiAlias

    g.FillPie(Brushes.Black, pntC.X - outerR, pntC.Y - outerR, 2 * outerR, 2 * outerR, startA, -startA + endA) 'Outer
    g.FillPie(mybrush, pntC.X - innerR, pntC.Y - innerR, 2 * innerR, 2 * innerR, startA, -startA + endA) 'Inner

    g.DrawPie(mypen, pntC.X - outerR, pntC.Y - outerR, 2 * outerR, 2 * outerR, startA, -startA + endA) 'Outer
    g.DrawPie(mypen, pntC.X - innerR, pntC.Y - innerR, 2 * innerR, 2 * innerR, startA, -startA + endA) 'Inner

    g.Dispose()
End Sub

编辑

这是一个如何找到带间隙的GraphicPath的例子。

代码语言:javascript
运行
复制
Dim pth As New GraphicsPath

pth.AddArc(outArc)

pth.AddLine(D, C)

pth.AddArc(innArc)

pth.AddLine(A, B)

这就是你的道路。让我们找到A,B(同样的逻辑适用于C,D):

代码语言:javascript
运行
复制
ε1 : y = a * x + b
ε1': y = a * x + (b +- 2,5) we keep the minus in this example

A已知(x轴的ε1的角度),b可以计算(ε1属于ε1):

代码语言:javascript
运行
复制
pntC.Υ = a * pntC.X + b

现在我们必须找到具有外圆(B)和内圆(A)的ε1‘的截取点:

代码语言:javascript
运行
复制
Solve these equations for x, y (point B)

circle: (x - pntC.X) * (x - pntC.X) + (y - pntC.Y) * (y - pntC.Y) = outerR * outerR
ε1'   : y = a * x + (b - 2,5)

Solve these equations for x, y (point A)

circle: (x - pntC.X) * (x - pntC.X) + (y - pntC.Y) * (y - pntC.Y) = innerR * innerR
ε1'   : y = a * x + (b - 2,5)

现在我们需要计算outArc,innArc。outArc (同样的逻辑适用于innerArc):

代码语言:javascript
运行
复制
pth.AddArc(outArc): pth.AddArc(pntC.X - outerR, pntC.Y - outerR, 2 * outerR, 2 * outerR, startA + φ, endA - startA - 2 * φ)

计算φ(OBB‘三角):

代码语言:javascript
运行
复制
sinφ = OB'/OB => sinφ = 2,5 / outerR

最后一件事。由于表单坐标与实际坐标相反(仅用于Y轴),所以在使用pntC进行计算之前,将其转换为实坐标:

代码语言:javascript
运行
复制
real: pntC.Yr = (Form client Height) - pntC.Y

当你计算A,B,C,D时,把它转换成形式(r表示实的):

代码语言:javascript
运行
复制
A.Y = (Form client Height) - A.Yr
B.Y = (Form client Height) - B.Yr
C.Y = (Form client Height) - C.Yr
D.Y = (Form client Height) - D.Yr

编辑2

有差距:

代码语言:javascript
运行
复制
Private Sub DrawAnnular(ByVal pntC As Point, ByVal outerR As Integer, ByVal innerR As Integer, ByVal startA As Single, ByVal sweepA As Single, ByVal gap As Double)
    Dim g As Graphics
    Dim pth As New GraphicsPath
    Dim fe, dbl As Double 'fe is "φ"

    gap = gap / 2.0R

    g = Me.CreateGraphics
    g.SmoothingMode = SmoothingMode.AntiAlias

    dbl = gap / CDbl(outerR)
    fe = Math.Asin(dbl) * 180.0R / Math.PI

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

    dbl = gap / CDbl(innerR)
    fe= Math.Asin(dbl) * 180.0R / Math.PI

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

    g.FillPath(Brushes.Black, pth)

    pth.Dispose()
    g.Dispose()
End Sub

瓦尔特

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25722300

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档