public void UpdateRTree(Mesh M) { //IEnumerable<int[]> index; //int[] VertexNumbers; //int vN; foreach (Particle p in Particles) { // clear particle neighbours list p.neighbours.Clear(); p.neighFieldPts.Clear(); // Eventhandler function for RTree search EventHandler <RTreeEventArgs> rTreeCallback = (object sender, RTreeEventArgs args) => { p.neighbours.Add(M.Vertices[args.Id]); p.neighFieldPts.Add(new FieldPt(args.Id, scalarField[args.Id])); }; MeshRTree.Search(new Sphere(M.ClosestPoint(p.pos + p.vel * futPosMult), seekRadius), rTreeCallback); // p.SeekNeighbours(seekIntensity); p.SeekColor(seekIntensity); //// query RTree of Mesh vertices for closest point to p.pos (returns an IEnumerable) //index = RTree.Point3dClosestPoints(M.Vertices.ToPoint3dArray(), new List<Point3d>{ p.pos}, 200); //// get enumerator //IEnumerator en = index.GetEnumerator(); //// get first array of indices //en.MoveNext(); //VertexNumbers = (int[]) en.Current; //vN = VertexNumbers[0]; //// update scalar field scalarField[MeshPoints.ClosestPoint(p.pos)] += p.PheroStrength; } foreach (Particle p in Particles) { } if (Particles.Count > 500) { Parallel.ForEach(Particles, p => { p.Update(); }); } else { foreach (Particle p in Particles) { p.Update(); } } }
public void SeekAngVis(double seekIntensity) { acc = Vector3d.Zero; visAng = pSystem.sensAng; Vector3d rotAxis = MeshPoints[currentCPindex].Normal; sensorC = VectorAmp(vel, pSystem.sensDist); sensorL = new Vector3d(sensorC); sensorR = new Vector3d(sensorC); sensorL.Rotate(visAng * 0.5, rotAxis); sensorR.Rotate(visAng * -0.5, rotAxis); int pL, pR, pC; double briL, briR, briC; pC = MeshPoints.ClosestPoint(pos + sensorC); pL = MeshPoints.ClosestPoint(pos + sensorL); pR = MeshPoints.ClosestPoint(pos + sensorR); briC = scalarField[pC]; briL = scalarField[pL]; briR = scalarField[pR]; Vector3d desired = Vector3d.Zero; //if (briL - briR < 0.01) //{ // Random rnd = new Random(); // futPos.Rotate(visAng * (rnd.NextDouble() - 0.5), rotAxis); //} //else // futPos = briL > briR ? futPosL : futPosR; // find brightest sensor Vector3d direction = sensorC; if (briL > briC && briL > briR) { direction = sensorL; } else if (briR > briC) { direction = sensorR; } // find mesh closest point to futpos desired = MeshPoints[MeshPoints.ClosestPoint(pos + direction)].Location - pos; desired.Unitize(); desired *= MaxSpeed; acc = (desired - vel) * seekIntensity; }
// . . . . . . . . . . . . . . . . . . . . . . methods /// <summary> /// Update with Jeff Jones 3-sensors method /// </summary> public void UpdateJones() { /* * How was it parallelized? * Several particles might write their pheromone contribution to the same mesh point, * to avoid simultaneous write to te same location (surest way to get an error, * even using so called "thread-safe" collections - especially if they are made * of structures and not classes): * . each particle saves its own closest point index as an internal field * . the resulting contribution is written in a separate non-parallel loop * that updates the scalar field. */ Parallel.ForEach(Particles, p => { // find mesh closest point index p.currentCPindex = MeshPoints.ClosestPoint(p.pos); // Seek brightest point direction p.SeekAngVis(seekIntensity); }); // write to scalar field foreach (Particle p in Particles) { scalarField[p.currentCPindex] = (float)Math.Min(1.0, scalarField[p.currentCPindex] + p.PheroStrength); } // update particles if (Particles.Count > 50) { Parallel.ForEach(Particles, p => { p.Update(); }); } else { foreach (Particle p in Particles) { p.Update(); } } }
/// <summary> /// Update with RTree method (samples points within a sphere) /// </summary> /// <param name="M"></param> public void UpdateRTree(Mesh M) { foreach (Particle p in Particles) { // clear particle neighbours list p.neighbours.Clear(); p.neighFieldPts.Clear(); // Eventhandler function for RTree search EventHandler <RTreeEventArgs> rTreeCallback = (object sender, RTreeEventArgs args) => { p.neighbours.Add(M.Vertices[args.Id]); p.neighFieldPts.Add(new FieldPt(args.Id, scalarField[args.Id])); }; MeshRTree.Search(new Sphere(M.ClosestPoint(p.pos + p.vel * sensDist), seekRadius), rTreeCallback); // Seek brightest point direction p.SeekColor(seekIntensity); //// update scalar field int cpInd = MeshPoints.ClosestPoint(p.pos); scalarField[cpInd] = (float)Math.Min(1.0, scalarField[cpInd] + p.PheroStrength); } if (Particles.Count > 50) { Parallel.ForEach(Particles, p => { p.Update(); }); } else { foreach (Particle p in Particles) { p.Update(); } } }