优化 GDI 的性能功能
在分析我的 GDI+ 项目时,我发现以下 IsLineVisible 函数是在我的自定义面板上绘制和移动对象时“最热门”的函数之一。
有没有可能优化它?
Private Function IsLineVisible(ByVal detectorRectangle As Rectangle,
ByVal pen As Pen,
ByVal ParamArray points() As Point) As Boolean
Using path As New GraphicsPath()
path.AddLines(points)
Return IsPathVisible(detectorRectangle, path, pen)
End Using
End Function
' Helper functions '''''''''''''''''''''''''''''''''''''
Private Function IsPathVisible(ByVal detectorRectangle As Rectangle,
ByVal path As GraphicsPath,
ByVal pen As Pen) As Boolean
If Not path.IsPoint Then
path.Widen(pen)
End If
Return IsPathVisible(detectorRectangle, path)
End Function
Private Function IsPathVisible(ByVal detectorRectangle As Rectangle,
ByVal path As GraphicsPath) As Boolean
Using r As New Region(path)
If r.IsVisible(detectorRectangle) Then
Return True
Else
Return False
End If
End Using
End Function
When profiling my GDI+ project I discovered that the following IsLineVisible
function is one of the "hottest" while the drawing and moving objects on my custom panel.
Is there a possibility to optimize it?
Private Function IsLineVisible(ByVal detectorRectangle As Rectangle,
ByVal pen As Pen,
ByVal ParamArray points() As Point) As Boolean
Using path As New GraphicsPath()
path.AddLines(points)
Return IsPathVisible(detectorRectangle, path, pen)
End Using
End Function
' Helper functions '''''''''''''''''''''''''''''''''''''
Private Function IsPathVisible(ByVal detectorRectangle As Rectangle,
ByVal path As GraphicsPath,
ByVal pen As Pen) As Boolean
If Not path.IsPoint Then
path.Widen(pen)
End If
Return IsPathVisible(detectorRectangle, path)
End Function
Private Function IsPathVisible(ByVal detectorRectangle As Rectangle,
ByVal path As GraphicsPath) As Boolean
Using r As New Region(path)
If r.IsVisible(detectorRectangle) Then
Return True
Else
Return False
End If
End Using
End Function
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
更新2:
更新包括厚度/宽度。
这是完全未经测试的代码,但它应该为您提供超快速解决方案的基本思想,而无需昂贵的框架调用:
UPDATE 2:
UPDATED to include thickness/width.
This is completely untested code, but it should give you the basic idea for a hyper-fast solution with no expensive framwork calls:
我唯一能看到的可能是使用更宽/更厚的
Pen
。这将使该方法减少递归并减少对 Widen 的调用,而不会损失太多效果(我希望是最后一个)。
The only thing I can see is perhaps using a wider/thicker
Pen
.This will let the method recurse less and cut down the calls to
Widen
without losing too much of the effect (I hope on the last one).与其创建一条非常昂贵的 GDI 构造路径,不如循环遍历您的点,将该点与前一个点连接起来,并检查该线是否与您的矩形相交,怎么样?
它的计算成本应该较低,并且能够在与矩形相交的第一段上停止循环。
另一篇文章应该有助于交叉测试。
如何查找直线和矩形?
Instead of creating a path, which is a very expensive GDI construct, how about looping through your points, connecting that point with the previous point, and checking to see if that line intersects with your rectangle?
It should be less computationally expensive, with the bonus of being able to stop the loop on the first segment to intersect the rectangle.
This other post should help with the intersection test.
How to find the intersection point between a line and a rectangle?
无需创建Region;可以使用 GraphicsPath.IsVisible 代替。我将扩大 GraphicsPath 并将其缓存以供重用,每个需要命中测试的对象。
There is no need to create a Region; GraphicsPath.IsVisible can be used instead. I would widen the GraphicsPath and cache it to be reused, per object that needs hit testing.