我会尽力清理代码以展示我的问题。基本上,它是一个八叉树搜索与相交的结合体。相交函数来自SDK(整个项目是Rhino插件)。如果我使用相交调用循环,它比递归搜索快10倍。更奇怪的是,在递归中隔离相交调用的时间较慢,比循环慢8倍。可能有1000种原因导致它表现如此,但我希望我能在代码上犯了一些显而易见的错误,有人可以通过查看代码发现。
这里是缓慢的递归部分:
感谢您的信任!
这里是缓慢的递归部分:
public void NewRayCast()
{
int runs = 500000; //how many rays we cast
Point3d raypos = new Point3d(0, 0, 0); //raystart
Ray3d ray = new Ray3d();
Random r = new Random(); //here we create targets to scatter the ray directions
Vector3d[] targets = new Vector3d[runs];
for (int i = 0; i < runs; i++)
{
targets[i] = new Vector3d(r.NextDouble() * 200 - 100, 500, r.NextDouble() * 200 - 100);
}
for (int i = 0; i < runs; i++)
{
boxes = new List<int>(); // this collects the octree leaves the rays hits
rayline.From = ray.Position;
rayline.To = ray.Position + ray.Direction;
LineBoxer(starter); // this starts the raycasting - starter is a array with 1 value (the scene bounding box)
}
}
public void LineBoxer(int[] check) // Cast a ray against boxes
{
for (int i = 0; i < check.Length; i++) // check only because the first call is with the scene box (1 index)
{
if (octmanB.node[check[i]].closed == false) // if node is a dead end > empty we skip it
{
isect = Rhino.Geometry.Intersect.Intersection.LineBox(rayline, octmanB.node[check[i]].bbox, 0, out ival); // intersection function, changing to an arbitrary bounding box doesnt speed it up either
if (isect == true)
{
if (octmanB.node[check[i]].leaf == false) // continue with recursion
{
LineBoxer(octmanB.node[check[i]].child);
}
else
{
boxes.Add(check[i]); // here we have a leaf
}
}
}
}
}
这里是更快的方法:
public void FasterTestRun()
{
int runs = 500000;
Line line = new Line(new Point3d(1, 1, 1), new Point3d(0, 1000, 0));
BoundingBox box = new BoundingBox(new Point3d(-50, 50, -50), new Point3d(50, 150, 50));
bool isect;
Interval v = new Interval();
Random r = new Random();
Point3d[] targets = new Point3d[runs];
for (int i = 0; i < runs; i++)
{
targets[i] = new Point3d(r.NextDouble() * 20 - 10, 1000, r.NextDouble() * 20 - 10);
}
for (int i = 0; i < runs; i++)
{
line.To = targets[i];
isect = Rhino.Geometry.Intersect.Intersection.LineBox(line, box, 0, out v);
}
}
感谢您的信任!
LineBoxer(ref int[] check)
方法了吗?你也在多次迭代数组,所以要创建一个变量var checkI = check[i];
和var nodeI = octmanB.node[checkI];
! - metadings