//agent move in the same direction of the neighbours public static Vector3d Alignment(List <IFlockAgent> neighbours, Vector3d desiredVelocity, FlockSystem flockSystem) { Vector3d alignment = Vector3d.Zero; foreach (IFlockAgent neighbour in neighbours) { alignment += neighbour.Velocity; } // We divide by the number of neighbours to actually get their average velocity alignment /= neighbours.Count; desiredVelocity += flockSystem.AlignmentStrength * alignment; return(desiredVelocity); }
//agent move towards the center of the neighbours public static Vector3d Cohesion(List <IFlockAgent> neighbours, Point3d Position, Vector3d desiredVelocity, FlockSystem flockSystem) { Point3d centre = Point3d.Origin; foreach (IFlockAgent neighbour in neighbours) { centre += neighbour.Position; } // We divide by the number of neighbours to actually get their centre of mass centre /= neighbours.Count; Vector3d cohesion = centre - Position; desiredVelocity += flockSystem.CohesionStrength * cohesion; return(desiredVelocity); }
//agent move away from neighbours if it gets too close public static Vector3d Separation(List <IFlockAgent> neighbours, Point3d Position, Vector3d desiredVelocity, FlockSystem flockSystem) { Vector3d separation = Vector3d.Zero; foreach (IFlockAgent neighbour in neighbours) { double distanceToNeighbour = Position.DistanceTo(neighbour.Position); if (distanceToNeighbour < flockSystem.SeparationDistance) { Vector3d getAway = Position - neighbour.Position; /* We scale the getAway vector by inverse of distanceToNeighbour to make * the getAway vector bigger as the agent gets closer to its neighbour */ separation += getAway / (getAway.Length * distanceToNeighbour); } } desiredVelocity += flockSystem.SeparationStrength * separation; return(desiredVelocity); }
protected override void SolveInstance(IGH_DataAccess DA) { // =============================================================================================== // Read input parameters // =============================================================================================== bool iReset = true; bool iPlay = false; bool i3D = false; int iCount = 0; double iTimestep = 0.0; double iNeighbourhoodRadius = 0.0; double iAlignment = 0.0; double iCohesion = 0.0; double iSeparation = 0.0; double iSeparationDistance = 0.0; List <Circle> iRepellers = new List <Circle>(); bool iUseParallel = false; bool iUseRTree = false; //bool iUseKDTree = false; //Brep AgentBox = new Brep(); if (!DA.GetData("Reset", ref iReset)) { return; } if (!DA.GetData("Play", ref iPlay)) { return; } if (!DA.GetData("3D", ref i3D)) { return; } if (!DA.GetData("Count", ref iCount)) { return; } if (!DA.GetData("Timestep", ref iTimestep)) { return; } if (!DA.GetData("Neighbourhood Radius", ref iNeighbourhoodRadius)) { return; } if (!DA.GetData("Alignment", ref iAlignment)) { return; } if (!DA.GetData("Cohesion", ref iCohesion)) { return; } if (!DA.GetData("Separation", ref iSeparation)) { return; } if (!DA.GetData("Separation Distance", ref iSeparationDistance)) { return; } if (!DA.GetDataList("Repellers", iRepellers)) { return; } if (!DA.GetData("Use Parallel", ref iUseParallel)) { return; } if (!DA.GetData("Use R-Tree", ref iUseRTree)) { return; } //if (!DA.GetData("Use KD-Tree", ref iUseKDTree)) return; //if (!DA.GetData("BoundingBox", ref AgentBox)) return; // =============================================================================================== // Validate Data // =============================================================================================== if (iAlignment < 0.0) { AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Cohesion>Seperation for flocking"); return; } if (iCohesion < 0.0) { AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Cohesion>Seperation for flocking"); return; } if (iSeparation < 0.0) { AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Cohesion>Seperation for flocking"); return; } // =============================================================================================== // Read input parameters // =============================================================================================== if (iReset || flockSystem == null) { flockSystem = new FlockSystem(iCount, i3D); } else { // =============================================================================================== // Assign the input parameters to the corresponding variables in the "flockSystem" object // =============================================================================================== flockSystem.Timestep = iTimestep; flockSystem.NeighbourhoodRadius = iNeighbourhoodRadius; flockSystem.AlignmentStrength = iAlignment; flockSystem.CohesionStrength = iCohesion; flockSystem.SeparationStrength = iSeparation; flockSystem.SeparationDistance = iSeparationDistance; flockSystem.Repellers = iRepellers; flockSystem.UseParallel = iUseParallel; flockSystem.UseRTree = iUseRTree; // =============================================================================== // Update the flock // =============================================================================== if (iUseRTree) { flockSystem.UpdateUsingRTree(); } else { flockSystem.Update(); } if (iPlay) { ExpireSolution(true); } } // =============================================================================== // Output the agent positions and velocities so we can see them on display // =============================================================================== List <GH_Point> positions = new List <GH_Point>(); List <GH_Vector> velocities = new List <GH_Vector>(); foreach (FlockAgent agent in flockSystem.Agents) { positions.Add(new GH_Point(agent.Position)); velocities.Add(new GH_Vector(agent.Velocity)); } DA.SetDataList("Positions", positions); DA.SetDataList("Velocities", velocities); }