在分析我的GDI +项目,我发现下面的 IsLineVisible
函数是一个热门,而绘画和移动我的自定义面板上的对象。
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
更新2:
public bool AreLinesVisible(Point[] p, int width, Rectangle rect)
{
for (var i = 1; i < p.Length; i++)
if (IsLineVisible(p[i - 1], p[i], width, rect))
return true;
return false;
}
更新时间:以包括厚度/宽度。
UPDATED to include thickness/width.
这是完全未经测试code,但它应该给你的的基本概念的作为没有昂贵的framwork一个超快速的解决方案要求:
This is completely untested code, but it should give you the basic idea for a hyper-fast solution with no expensive framwork calls:
public bool IsLineVisible(Point p1, Point p2, int width, Rectangle rect)
{
var a = Math.Atan2(p1.Y - p2.Y, p1.X - p2.X) + Math.PI/2;
var whalf = (width + 1)*0.5;
var dx = (int) Math.Round(whalf*Math.Sin(a));
var dy = (int) Math.Round(whalf*Math.Cos(a));
return IsLineVisible( new Point(p1.X - dx, p1.Y - dy), new Point(p2.X - dx, p2.Y - dy), rect)
|| IsLineVisible( new Point(p1.X + dx, p1.Y + dy), new Point(p2.X + dx, p2.Y + dy), rect);
}
public bool IsLineVisible(Point p1, Point p2, Rectangle rect)
{
if (p1.X > p2.X) // make sure p1 is the leftmost point
return IsLineVisible(p2, p1, rect);
if (rect.Contains(p1) || rect.Contains(p2))
return true; // one or both end-points within the rect -> line is visible
//if both points are simultaneously left or right or above or below -> line is NOT visible
if (p1.X < rect.X && p2.X < rect.X)
return false;
if (p1.X >= rect.Right && p2.X >= rect.Right)
return false;
if (p1.Y < rect.Y && p2.Y < rect.Y)
return false;
if (p1.Y >= rect.Bottom && p2.Y >= rect.Bottom)
return false;
// now recursivley break down the line in two part and see what happens
// (this is an approximation...)
var pMiddle = new Point((p1.X + p2.X)/2, (p1.Y + p2.Y)/2);
return IsLineVisible(p1, new Point(pMiddle.X - 1, pMiddle.Y), rect)
|| IsLineVisible(new Point(pMiddle.X + 1, pMiddle.Y), p2, rect);
}
上一篇:使用播放列表网址获取YouTube视频播放列表、网址、视频、YouTube
下一篇:安卓:适配器类从getView传递按钮点击响应()方法来mainActivity适配器、方法来、按钮、mainActivity