来了..。我需要在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
(扫描角)。
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)
谢谢
漂流者
发布于 2014-09-08 20:00:48
pntC是中心。outerR和innerR是半径。startA和endA是角度。角度由x轴和顺时针测量。
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的例子。
Dim pth As New GraphicsPath
pth.AddArc(outArc)
pth.AddLine(D, C)
pth.AddArc(innArc)
pth.AddLine(A, B)
这就是你的道路。让我们找到A,B(同样的逻辑适用于C,D):
ε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):
pntC.Υ = a * pntC.X + b
现在我们必须找到具有外圆(B)和内圆(A)的ε1‘的截取点:
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):
pth.AddArc(outArc): pth.AddArc(pntC.X - outerR, pntC.Y - outerR, 2 * outerR, 2 * outerR, startA + φ, endA - startA - 2 * φ)
计算φ(OBB‘三角):
sinφ = OB'/OB => sinφ = 2,5 / outerR
最后一件事。由于表单坐标与实际坐标相反(仅用于Y轴),所以在使用pntC进行计算之前,将其转换为实坐标:
real: pntC.Yr = (Form client Height) - pntC.Y
当你计算A,B,C,D时,把它转换成形式(r表示实的):
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
有差距:
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
瓦尔特
https://stackoverflow.com/questions/25722300
复制相似问题