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