//method for finding neighbouring agents
        private List <BristlebotAgent> FindNeighbours(BristlebotAgent agent)
        {
            List <BristlebotAgent> neighbours = new List <BristlebotAgent>();

            foreach (BristlebotAgent neighbour in Agents)
            {
                if (neighbour != agent && neighbour.Position.DistanceTo(agent.Position) < NeighbourhoodRadius)
                {
                    neighbours.Add(neighbour);
                }
            }
            return(neighbours);
        }
        //Constructor
        public BristlebotSystem(int agentCount, AgentEnvironment iAgentEnvironment)
        {
            Agents = new List <BristlebotAgent>();

            //TO DO check here if you have an environment or not
            if (iAgentEnvironment == null)
            {
                defaultEnv = new AgentEnvironment(Plane.WorldXY, defaultEnvSize, defaultEnvSize, defaultEnvSize);
                AgentEnvX  = defaultEnv.EnvWidth;
                AgentEnvY  = defaultEnv.EnvHeight;
                AgentEnvZ  = defaultEnv.EnvDepth;
                for (int i = 0; i < agentCount; i++)
                {
                    BristlebotAgent agent = new BristlebotAgent(
                        Util.GetRandomPoint(0.0, AgentEnvX, 0.0, AgentEnvY, 0.0, AgentEnvZ),
                        Util.GetRandomUnitVector() * 4.0,
                        defaultEnv);
                    agent.BristlebotSystem = this;
                    Agents.Add(agent);
                }
            }
            else
            {
                defaultEnv = iAgentEnvironment;
                AgentEnvX  = defaultEnv.EnvWidth;
                AgentEnvY  = defaultEnv.EnvHeight;
                AgentEnvZ  = defaultEnv.EnvDepth;
                for (int i = 0; i < agentCount; i++)
                {
                    BristlebotAgent agent = new BristlebotAgent(
                        Util.GetRandomPoint(0.0, AgentEnvX, 0.0, AgentEnvY, 0.0, AgentEnvZ),
                        Util.GetRandomUnitVectorXY() * 4.0,
                        defaultEnv);

                    agent.BristlebotSystem = this;
                    Agents.Add(agent);
                }
            }
        }
 //make the compute desired velocity into a function so that we can run it in parallel
 private void ComputeAgentDesiredVelocty(BristlebotAgent agent)
 {
 }
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            // code for reading input parameters
            //declare input parameters
            bool     iReset  = false;
            bool     iPlay   = false;
            Point3d  initPos = new Point3d(0, 0, 0);
            Vector3d initVel = new Vector3d(0.5, 0.5, 1);

            AgentEnvironment iAgentEnvironment = new AgentEnvironment(Plane.WorldXY, 50.0, 50.0, 0);
            BristlebotAgent  iBristlebot       = new BristlebotAgent(initPos, initVel);
            int    iCount    = 10;
            double iTimeStep = 0.01;

            double        iNeighbourhoodRadius = 1;
            double        iSeparationDistance  = 1.0;
            List <Circle> iRepellers           = new List <Circle>();

            bool iUseParallel = false;
            bool iUseRTree    = false;

            //read in input parameters
            DA.GetData("Reset", ref iReset);                             //0
            DA.GetData("Play", ref iPlay);                               //1
            DA.GetData("Environment", ref iAgentEnvironment);            //2
            DA.GetData("BristlebotAgent", ref iAgentEnvironment);        //2
            DA.GetData("Count", ref iCount);                             //4
            DA.GetData("Timestep", ref iTimeStep);                       //5
            DA.GetData("NeighbourhoodRadius", ref iNeighbourhoodRadius); //6

            DA.GetData("SeparationDistance", ref iSeparationDistance);   //10
            DA.GetDataList("Repellers", iRepellers);                     //11
            DA.GetData("UseCoresInParallel", ref iUseParallel);          //12
            DA.GetData("UseR-TreeSearch", ref iUseRTree);                //13


            if (iReset || bristlebotSystem == null)
            {
                bristlebotSystem = new BristlebotSystem(iCount, iAgentEnvironment);
            }
            else
            {
                bristlebotSystem.NeighbourhoodRadius = iNeighbourhoodRadius;

                bristlebotSystem.Repellers   = iRepellers;
                bristlebotSystem.UseParallel = iUseParallel;

                if (iUseRTree)
                {
                    bristlebotSystem.updateUsingRTree();
                }
                else
                {
                    bristlebotSystem.Update();
                }
                if (iPlay)
                {
                    ExpireSolution(true);
                }
            }

            List <GH_Point>  positions  = new List <GH_Point>();
            List <GH_Vector> velocities = new List <GH_Vector>();

            foreach (BristlebotAgent agent in bristlebotSystem.Agents)
            {
                positions.Add(new GH_Point(agent.Position));
                velocities.Add(new GH_Vector(agent.Velocity));
            }

            DA.SetDataList("Positions", positions);
            DA.SetDataList("Velocities", velocities);
        }