logo

CreepyCrawlers

private void RunScript(bool reset, int ptCount, int dimension, bool connect, bool self, bool bounds, double conn_thresh, double moveValue, double searchRad, double aligVal, double sepVal, double cohVal, ref object Creeps, ref object Connectivity, ref object BoundingBox, ref object TrailPoints)
  {

    Random rnd = new Random();
    List<Vector3d> vecs = new List<Vector3d>();
    List<Point3d> returnedvecs = new List<Point3d>();
    
    if(reset){ //we are using the reset to reinitialize all the variables and positions to pass to the class once we are running

      this.moveList = new List<Vector3d>();
      this.startList = new List<Vector3d>();
      this.posTree = new DataTree<Point3d>();
      this.dimensions = dimension;

      if(this.dimensions == 0){
        this.bb = new BoundingBox(-250, -250, 0, 250, 250, 0);
      }else{
        this.bb = new BoundingBox(-250, -250, -250, 250, 250, 500);
      }
      
      for(int i = 0; i < ptCount; i++){

        if(this.dimensions == 0){ //IF WE WANT 2D
          //this.moveVec = new Vector3d(rnd.Next(-1, 2), rnd.Next(-1, 2), 0); //move randomly in any direction 2d
          this.moveVec = new Vector3d(moveValue, 0, 0); //move to the right only
          //this.startPos = new Vector3d(rnd.Next((int) bb.Min[0], (int) bb.Max[0]), rnd.Next((int) bb.Min[1], (int) bb.Max[1]), 0); //spawn randomly inside the bounding area
          this.startPos = new Vector3d((int) bb.Min[0], rnd.Next((int) bb.Min[1], (int) bb.Max[1]), 0); //spawn along the y axis of the bounding area

        }else{ //IF WE WANT 3D
          this.moveVec = new Vector3d(rnd.Next(-1, 2), rnd.Next(-1, 2), 0.5); //move randomly in the xy axis and up in the z axis
          //this.moveVec = new Vector3d(rnd.Next(-1, 2), rnd.Next(-1, 2), rnd.Next(-1, 2)); //move randomly in the xyz axis 
          this.moveVec *= moveValue;
          //this.startPos = new Vector3d(rnd.Next((int) bb.Min[0], (int) bb.Max[0]), rnd.Next((int) bb.Min[1], (int) bb.Max[1]), ((int) bb.Min[2] + (int) bb.Max[2]) / 2); //start on the plane in the middle of the 3d bounds
          this.startPos = new Vector3d(rnd.Next((int) bb.Min[0], (int) bb.Max[0]), rnd.Next((int) bb.Min[1], (int) bb.Max[1]), (int) bb.Min[2]); //start randomly on the lowest plane of the 3d bounds
          //this.startPos = new Vector3d(rnd.Next((int) bb.Min[0], (int) bb.Max[0]), rnd.Next((int) bb.Min[1], (int) bb.Max[1]), rnd.Next((int) bb.Min[2],(int) bb.Max[2])); //start randomly inside the 3d bounds
        }
        this.startList.Add(this.startPos); //add the initial starting positions to the list to pass once we start running
        this.moveList.Add(this.moveVec); //add the initial move vectors to the list to pass once we start running
      }

      Creeps = this.startList;

    }else{

      creepers creeperPts = new creepers(this.startList, this.moveList, bb, this.dimensions, connect, conn_thresh, self, searchRad, aligVal, sepVal, cohVal, this.posTree, moveValue, bounds);
      creeperPts.action();

      this.startList = creeperPts.outputList;
      this.moveList = creeperPts.outputMoveList;

      Creeps = this.startList;
      Connectivity = creeperPts.lineList;
      BoundingBox = this.bb;
      TrailPoints = creeperPts.posTree;
    }
  }

  // <Custom additional code> 

  //-----------------Global Variables---------------------------
  private List<Vector3d> moveList = new List<Vector3d>();
  private List<Vector3d> startList = new List<Vector3d>();
  private DataTree<Point3d>posTree = new DataTree<Point3d>();

  private Vector3d startPos = new Vector3d();
  private Vector3d moveVec;
  private BoundingBox bb;
  private int dimensions;

  public class creepers{
//-----------------Class Variables------------------------------
    private BoundingBox bbox;
    public Vector3d pos = new Vector3d();
    public Vector3d nextVec = new Vector3d();
    public List<Vector3d> posList = new List<Vector3d>();
    public List<Vector3d> posMoveList = new List<Vector3d>();
    public List<Vector3d> outputList = new List<Vector3d>();
    public List<Vector3d> outputMoveList = new List<Vector3d>();
    public List<Line> lineList = new List<Line>();
    public DataTree<Point3d> posTree = new DataTree<Point3d>();

    private bool flag;
    private int dim;
    private bool conn;
    private bool enableBounds;
    private bool self;
    private double ct;
    private double sR;
    private double aValue;
    private double sValue;
    private double cValue;
    private double moveAmp;
//------------------Constructor----------------------------------
    public creepers(List<Vector3d> vecs, List<Vector3d> move, BoundingBox bb, int dimension, bool connect, double connThresh, bool self, double lookArea, double alignVal, double sepVal, double cohVal, DataTree<Point3d> baseTree, double moveVecAmp, bool eb){

      this.posList = vecs;
      this.posMoveList = move;
      this.bbox = bb;
      this.dim = dimension;
      this.conn = connect;
      this.ct = connThresh;
      this.self = self;
      this.sR = lookArea;
      this.aValue = alignVal;
      this.sValue = sepVal;
      this.cValue = cohVal;
      this.posTree = baseTree;
      this.moveAmp = moveVecAmp;
      this.enableBounds = eb;
    }
//-----------Method Creates the Action----------------------------
    public void action(){

      for(int i = 0; i < this.posList.Count; i++){ //go through all the creepers

        this.pos = new Vector3d(); 
        this.nextVec = new Vector3d();
        this.pos = this.posList[i];

        if(this.enableBounds){ //check to see if we enabled the bounding area which causes the creeper to turn around if it hits it
          this.checkLoc(); //call the checkloc method

          if(this.flag){ //if the creeper is on the boundary turn reverse it
            Vector3d temp = this.posMoveList[i];
            if(this.dim == 0){
              if(this.pos.X >= (int) this.bbox.Max[0] || this.pos.X <= (int) this.bbox.Min[0]){
                temp.X *= -1;
              }
              if(this.pos.Y >= (int) this.bbox.Max[1] || this.pos.Y <= (int) this.bbox.Min[1]){
                temp.Y *= -1;
              }
            }else{
              if(this.pos.X >= (int) this.bbox.Max[0] || this.pos.X <= (int) this.bbox.Min[0]){
                temp.X *= -1;
              }
              if(this.pos.Y >= (int) this.bbox.Max[1] || this.pos.Y <= (int) this.bbox.Min[1]){
                temp.Y *= -1;
              }
              if(this.pos.Z >= (int) this.bbox.Max[2] || this.pos.Z <= (int) this.bbox.Min[2]){
                temp.Z *= -1;
              }
            }
            this.posMoveList[i] = temp;
          }
        }
        this.nextVec = this.posMoveList[i]; //set the move vector the current move vector from the list

        if(this.self){ //if we want them to interact with each other then enable the feature in the component
          Affect(); 
        }

        this.pos += this.nextVec; //add the move vec to the current position
        GH_Path pth = new GH_Path(i); //set a new path for the data structure from the current count
        this.posTree.Add((Point3d) this.pos, pth); //add the current position to the data tree at the specified path
        this.outputMoveList.Add(this.nextVec); //add the next move vec to the output list to return replace the move list
        this.outputList.Add(this.pos); //add the new position to the output list to replace the previous current positions

        if(this.conn){ //enable link to see how far each creeper can see this will show you their interaction range
          link();
        }
      }

    }
//-----------Method Computes the interaction----------------------------
    public void Affect(){

      List<Vector3d> otherPtsList = new List<Vector3d>();
      List<Vector3d> otherMoveValues = new List<Vector3d>();
      List<double> allDist = new List<double>();

      for(int i = 0; i < this.posList.Count; i++){

        Point3d othercreeper = (Point3d) this.posList[i];
        double dist = othercreeper.DistanceTo((Point3d) this.pos);

        if(dist > 0 && dist < this.sR){
          otherPtsList.Add(this.posList[i]);
          allDist.Add(dist);
          otherMoveValues.Add(this.posMoveList[i]);
        }
      }
      if(otherPtsList.Count > 0){

        Vector3d staticVec = new Vector3d();
        //----------Align-----------------
        Vector3d alignVec = align(otherPtsList, allDist, otherMoveValues);
        if(alignVec.Length > 0){
          alignVec.Unitize();
        }
        alignVec *= this.aValue;
        //----------Separate-----------------
        Vector3d separateVec = separate(otherPtsList, allDist, otherMoveValues);
        if(separateVec.Length > 0){
          separateVec.Unitize();
        }
        separateVec *= this.sValue;
        //----------Cohesion-----------------
        Vector3d cohesionVec = cohesion(otherPtsList);
        if(cohesionVec.Length > 0){
          cohesionVec.Unitize();
        }
        cohesionVec *= this.cValue;
        //-----------------------------------

        staticVec += alignVec;
        staticVec += separateVec;
        staticVec += cohesionVec;

        this.nextVec += staticVec;
        this.nextVec.Unitize();
        this.nextVec *= this.moveAmp;
      }
    }
//-----------Method Computes the alignment----------------------------
    public Vector3d align(List<Vector3d> otherPtsList, List<double> allDist, List<Vector3d>otherMoveValues){

      Vector3d alignVector = new Vector3d();
      for(int i = 0; i < otherPtsList.Count; i++){
        alignVector += (otherMoveValues[i] *= (this.sR / allDist[i]));
      }
      return alignVector;
    }
//-----------Method Computes the separation----------------------------
    public Vector3d separate(List<Vector3d> otherPtsList, List<double> allDist, List<Vector3d>otherMoveValues){

      Vector3d separateVector = new Vector3d();
      for(int i = 0; i < otherPtsList.Count; i++){
        separateVector += Vector3d.Multiply(Vector3d.Subtract(this.pos, otherPtsList[i]), this.sR / allDist[i]);
      }
      return separateVector;
    }
//-----------Method Computes the cohesion-----------------------------
    public Vector3d cohesion(List<Vector3d> otherPtsList){

      Vector3d cohesionVector = new Vector3d(0, 0, 0);
      for(int i = 0; i < otherPtsList.Count; i++){
        cohesionVector += otherPtsList[i];
      }
      Vector3d scaleVec = Vector3d.Multiply(cohesionVector, (1.00 / otherPtsList.Count));
      Point3d posPoint = (Point3d) this.pos;
      double dist = posPoint.DistanceTo((Point3d) scaleVec);

      return Vector3d.Multiply(Vector3d.Subtract(scaleVec, this.pos), this.sR / dist);
    }
//-----Method Creates visual diagram of the creeper search space------
    public void link(){

      for(int i = 0; i < this.outputList.Count; i++){
        Point3d othercreeper = (Point3d) this.outputList[i];
        double dist = othercreeper.DistanceTo((Point3d) this.pos);

        if(dist > 0 && dist < this.ct){
          Line l = new Line(othercreeper, (Point3d) this.pos);
          lineList.Add(l);
        }
      }
    }
//----Method Checks if the creeper is still in the bounding area-----
    public void checkLoc(){
      flag = new bool();
      if(!this.bbox.Contains((Point3d) this.pos)){
        //Random rnd = new Random(); //use this if you want the creeper to spawn in a new random area instead of turning it around.
        //this.pos = new Vector3d(rnd.Next(-250, 250), rnd.Next(-250, 250), 0); //use this if you want the creeper to spawn in a new random area instead of turning it around.
        this.flag = true;
      }else{
        this.flag = false;
      }
    }
  }
  // </Custom additional code> 
}
Update
  • Share