top of page

VORONOI TESSELATION

 

In mathematics, a Voronoi diagram is a way of dividing space into a number of regions. A set of points (called seeds, sites, or generators) is specified beforehand and for each seed there will be a corresponding region consisting of all points closer to that seed than to any other. The regions are called Voronoi cells.(wikipedia)

 

download .gh File picture

 

 

DELAUNAY TRIANGULATION

 

In mathematics and computational geometry, a Delaunay triangulation for a set P of points in a plane is a triangulation DT(P) such that no point in P is inside the circumcircle of any triangle in DT(P). Delaunay triangulations maximize the minimum angle of all the angles of the triangles in the triangulation; they tend to avoid skinny triangles.

For a set of points on the same line there is no Delaunay triangulation. For four or more points on the same circle (e.g., the vertices of a rectangle) the Delaunay triangulation is not unique: each of the two possible triangulations that split the quadrangle into two triangles satisfies the "Delaunay condition", i.e., the requirement that the circumcircles of all triangles have empty interiors.

By considering circumscribed spheres, the notion of Delaunay triangulation extends to three and higher dimensions. Generalizations are possible to metrics other than Euclidean. However in these cases a Delaunay triangulation is not guaranteed to exist or be unique.(Wikipedia)

 

download .gh File picture

 

 

  private void RunScript(List<Point3d> pointSet, List<Point3d> boundary, ref object polyLines, ref object curves)
  {

    //CHECK EDGE CONDITIONS
    if(pointSet.Count < 1 || boundary.Count < 1){
      Print("Input PointSet, or Boundary Points, is null");
      return;
    }

 

    //INITIALIZE LISTS TO STORE OUTPUT CURVES AND OUTPUT POLYLINES
    List<Curve> vCurves = new List<Curve>();
    List<Polyline> vPLines = new List<Polyline>();


    List<VoronoiCell> vCells = new List<VoronoiCell>();

    //ITERATE OVER EACH POINT IN THE INPUT POINTSET
    foreach(Point3d p in pointSet) {
  
    //instantiate a voronoi cell for each point
      VoronoiCell vCell = new VoronoiCell(p, boundary);

      foreach(Point3d pt in pointSet) {
     
   //we need to consider all points BUT the point under consideration
        if (pt != p) {
          vCell.sliceCell(pt);
        }
      }
      vPLines.Add(vCell.createPolyline());
      vCurves.Add(vCell.createCrv(3));
    }

    Print("\nNumber of polyLines: " + vPLines.Count);
    Print("Number of OnNurbsCurve: " + vCurves.Count);

 

    //SET THE OUTPUTS
    polyLines = vPLines;
    curves = vCurves;

  }

 

  public class VoronoiCell {
    //VARIABLES
    List<Point3d> vertices;
    Point3d center;


    //CONSTRUCTOR
    public VoronoiCell(Point3d p, List<Point3d> pts) {
      this.center = p;
      this.vertices = pts;
    }


    //METHODS

    // Slice Cell operation
    public void sliceCell(Point3d pt) {
      // list for storing temporary new boundary points
      List<Point3d> tempVertices = new List<Point3d>();
      // list for storing final new boundary points
      List<Point3d> newVertices = new List<Point3d>();
  
    // counter for number of intersection of bisector with current boundary
      int numIntersections = 0;
      // intersection of a boundary segment with bisector
      double intersection;


      //STEP 1: CREATE BISECTOR
      Line segment01 = createBisector(this.center, pt);

 

      //STEP 2: FIND INTERSECTING POINTS
      for (int i = 0; i < this.vertices.Count; i++) {
     
   // create a boundary segment by connecting two sequential points in vertices array
        Line segment02 = new Line(this.vertices[i], this.vertices[(i + 1) % vertices.Count]);
   
     // add first point of segment to new boundary
        tempVertices.Add(this.vertices[i]);
    
    // if a valid intersection found by current boundary segment
        // add the intersection point as a new point to boundary points list

        intersection = intersect2Lines(segment02, segment01);
        if (intersection != -1) {
      
    // a new intersection has been found
          numIntersections++;
          tempVertices.Add(segment02.PointAt(intersection));
        }


      }

 

 

      //STEP 3:UPDATE BOUNDARY VERTICES
      if (numIntersections == 2) {
      
  // two doubles could not be exactly equal
        // so there is an epsillon tolerance for finding distances

        double epsillon = 0.0001;

        // traverse trough all points in new vertices and find points
        // that belongs to this cell and remove others
        // note: points that belongs to this cell is closer or have equal distance to
        // cell center compare to point to slice from "pt"

        foreach(Point3d newVerticesPt in tempVertices) {
          if ((newVerticesPt.DistanceTo(this.center) - newVerticesPt.DistanceTo(pt)) < epsillon) {
            newVertices.Add(newVerticesPt);
          }
        }

        // update current boundary by replacing it with
        // new boundary

        this.vertices = newVertices;
      }
    }

    public Line createBisector(Point3d ptStart, Point3d ptEnd) {
      Point3d newPtEnd = new Point3d();

      Point3d newPtStart = (ptStart + ptEnd ) / 2;
      newPtEnd.X = newPtStart.X - (ptEnd.Y - ptStart.Y);
      newPtEnd.Y = newPtStart.Y + (ptEnd.X - ptStart.X);

      return new Line(newPtStart, newPtEnd);
    }

    /*
    *This method returns a double value representing the intersection
    *of two lines. If the value is equal to -1 the lines do not
    *intersect; otherwise the value represents the parameter to locate
    *the intersecting point.
    */

    public double intersect2Lines(Line line01, Line line02) {
      double D; // Denominator
      double E; // Enumerator

      //line01
      double line01startX = line01.From.X;
      double line01endX = line01.To.X;
      double line01startY = line01.From.Y;
      double line01endY = line01.To.Y;
     
//line02
      double line02startX = line02.From.X;
      double line02endX = line02.To.X;
      double line02startY = line02.From.Y;
      double line02endY = line02.To.Y;

      D = (line02endY - line02startY) * (line01endX - line01startX)
        - (line01endY - line01startY) * (line02endX - line02startX);

      if (D == 0) return -1.0;

      E = (line02endX - line02startX) * (line01startY - line02startY)
        - (line02endY - line02startY) * (line01startX - line02startX);

      //intersection function - parameter to locate the intersecting point with the line range
      double intersection = E / D;
      if (intersection < 0 || intersection > 1) return -1.0;

      return intersection;
    }

    /*
    *This method returns the points maintained by the VoronoiCell stored in an Array. Also the first point of the initial list is also added at the end. This method is called by the createCrv()method in order to get the points for generating a closed curve,
    */

    private Point3d[] get3DPoints() {
      List<Point3d> points = new List<Point3d>();
      points.AddRange(this.vertices);
    
  //repeat the first point to the end of the list
      points.Add(this.vertices[0]);
      return points.ToArray();
    }

    public Curve createCrv(int degree) {

      NurbsCurve nCurve = NurbsCurve.Create(true, degree, this.vertices);

      return nCurve;
    }

    public Polyline createPolyline() {

      // create a closed polyline by connecting cell boundary points
      Polyline boundaryPolyline = new Polyline();
      for(int i = 0; i <= this.vertices.Count; i++) {
        boundaryPolyline.Add(this.vertices[i % this.vertices.Count]);
      }
      return boundaryPolyline;
    }

  }

 

Rhino Script : C# Coding in Grasshopper

Rhino Script : C# Coding in Grasshopper

  private void RunScript(List<Point3d> pointSet, List<Point3d> boundary, ref object polyLines, ref object curve)
  {
    circumCircle c;
    List<Point3d> triangles = new List<Point3d>();
    pointSet.AddRange(boundary);
    for (int i = 0; i < pointSet.Count - 2;i++){
      for (int j = i + 1; j < pointSet.Count - 1;j++){
        for (int k = j + 1; k < pointSet.Count;k++){
          c = new circumCircle(pointSet[i], pointSet[j], pointSet[k]);
          bool pointValid = true;
          for (int l = 0; l < pointSet.Count && pointValid;l++){
            if (l != i && l != j && l != k)
            {
              if (c.IsPointInside(pointSet[l]))
              {
                pointValid = false;
              }
            }
          }
          if (pointValid)
          {
            triangles.Add(pointSet[i]);
            triangles.Add(pointSet[j]);
            triangles.Add(pointSet[k]);
            triangles.Add(pointSet[i]);
          }
        }
      }
    }
    List<Polyline> poly = new List<Polyline>();
    List<Curve> vCurves = new List<Curve>();
    Polyline boundaryPolyline = new Polyline();
    List<Point3d> boundaryPoints = new List<Point3d>();
    for(int i = 0; i < triangles.Count / 4; i++) {
      boundaryPolyline = new Polyline();
      boundaryPoints = new List<Point3d>();
      for (int j = 0;j < 4;j++){
        boundaryPolyline.Add(triangles[i * 4 + j]);
        boundaryPoints.Add(triangles[i * 4 + j]);
      }
      vCurves.Add(NurbsCurve.Create(true, 3, boundaryPoints));
      poly.Add(boundaryPolyline);
    }
    polyLines = poly;
    curve = vCurves;
  }

 

  public class circumCircle {
    Point3d p1,p2,p3,center;
    double r;
    public circumCircle(Point3d p1, Point3d p2, Point3d p3){
      this.p1 = p1;
      this.p2 = p2;
      this.p3 = p3;

    public Line createBisector(Point3d ptStart, Point3d ptEnd) {
      Point3d newPtEnd = new Point3d();

      Point3d newPtStart = (ptStart + ptEnd ) / 2;
      newPtEnd.X = newPtStart.X - 10 * (ptEnd.Y - ptStart.Y);
      newPtEnd.Y = newPtStart.Y + 10 * (ptEnd.X - ptStart.X);
      newPtStart.X = newPtEnd.X + 20 * (ptEnd.Y - ptStart.Y);
      newPtStart.Y = newPtEnd.Y - 20 * (ptEnd.X - ptStart.X);


      return new Line(newPtStart, newPtEnd);
    }

    public double intersect2Lines(Line line01, Line line02) {
      double D; //
Denominator
      double E; // Enumerator

      //line01
      double line01startX = line01.From.X;
      double line01endX = line01.To.X;
      double line01startY = line01.From.Y;
      double line01endY = line01.To.Y;
  
    //line02
      double line02startX = line02.From.X;
      double line02endX = line02.To.X;
      double line02startY = line02.From.Y;
      double line02endY = line02.To.Y;

      D = (line02endY - line02startY) * (line01endX - line01startX)
        - (line01endY - line01startY) * (line02endX - line02startX);

      if (D == 0) return -1.0;

      E = (line02endX - line02startX) * (line01startY - line02startY)
        - (line02endY - line02startY) * (line01startX - line02startX);

      //intersection function - parameter to locate the intersecting point with the line range
      double intersection = E / D;
      if (intersection < 0 || intersection > 1) return -1.0;

      return intersection;
    }

    public Curve createCrv(int degree, List<Point3d> vertices) {

      NurbsCurve nCurve = NurbsCurve.Create(true, degree, vertices);

      return nCurve;
    }
  }

 

BOID FLOCKING

 

Boids is an artificial life program which simulates the flocking behavior of birds. As with most artificial life simulations, Boid is an example of emergent behavior; the complexity of Boids arises from the interaction of individual agents adhering to a set of simple rules.

These rules are:

separation: steer to avoid crowding local flockmates

alignment: steer towards the average heading of local flockmates

cohesion: steer to move toward the average position (center of mass) of local flockmates.

(wikipedia)

 

download .gh File Picture

  private void RunScript(List<On3dPoint> P, List<On3dVector> D, double W, double L, double H, int S, ref object B_Loc, ref object B_Dir)
  {
    Print("Number of Flocking Boids:{0}\n\n", P.Count);
    if(P.Count != D.Count) return;

    // Add an initial set of boids into the system
    if(flock == null)
    {
      Print("Flock is null");
      flock = new Flock();
      for (int i = 0; i < P.Count; i++)
      {
        flock.addBoid(new Boid(P[i], D[i], 50.0, 5, W, L, H));
      }
    }

    flock.run();

    B_Loc = flock.getBoidsLocs();
    B_Dir = flock.getBoidsDirs();

  }

  Flock flock = null;// = new Flock();
  static public Random ran = new Random();

  public class Boid
  {
    public On3dPoint loc;
    public On3dVector vel;
    On3dVector acc;
    double r;
    double maxforce;    // Maximum steering force
    double maxspeed;    // Maximum speed
    double width;
    double length;
    double height;

    public Boid(On3dPoint lc, On3dVector v, double mf, double ms, double wd, double len, double ht)
    {
      loc = lc;
      acc = new On3dVector(0, 0, 0);
      vel = v;
      r = 2.0;
      maxforce = mf;
      maxspeed = ms;
      width = wd;
      length = len;
      height = ht;
    }

    public void run(List<Boid> boids) {
      flock(boids);
      update();
      borders();
    }

    // We accumulate a new acceleration each time based on three rules
    void flock(List<Boid> boids)
    {
      On3dVector sep = separate(boids);   // Separation
      On3dVector ali = align(boids);      // Alignment
      On3dVector coh = cohesion(boids);   // Cohesion

      // Arbitrarily weight these forces
      //sep.mult(1.5); ali.mult(1.0); coh.mult(1.0);

      sep *= (1.5);
      ali *= (1 );
      coh *= (1 );

      // Add the force vectors to acceleration
      acc += (sep);
      acc += (ali);
      acc += (coh);
    }

    // Method to update location
    void update() {
     
// Update velocity
      vel += (acc);

      // Limit speed
      if(vel.Length() > maxspeed)// Limit to maximum steering force
      {
        vel.Unitize();
        vel *= maxspeed;
      }

      loc += (vel);
 
     // Reset accelertion to 0 each cycle
      acc *= (0);
    }

    // Wraparound
    void borders() {
      if (loc.x < -r) loc.x = width + r;
      if (loc.y < -r) loc.y = length + r;
      if( loc.z < -r) loc.z = height + r;
      if (loc.x > width + r) loc.x = -r;
      if (loc.y > length + r) loc.y = -r;
      if( loc.z > height + r) loc.z = -r;
    }

    void render()
    {

    }

    // Separation
    // Method checks for nearby boids and steers away

    public On3dVector separate(List<Boid> boids)
    {
      double desiredseparation = 10.0;//20.0;
      On3dVector steer = new On3dVector(0, 0, 0);
      int count = 0;
     
// For every boid in the system, check if it's too close
      foreach( Boid b in boids)
      {
        double d = loc.DistanceTo(b.loc);
        if((d > 0) && (d < desiredseparation))
        {
      
    // Calculate vector pointing away from neighbor
          On3dVector diff = loc - b.loc;
          diff.Unitize();
          diff /= d; // Weight by distance

          steer += diff;
          count++;
        }
      }

      if (count > 0) {
        steer /= count;
      }

      // As long as the vector is greater than 0
      if (steer.Length() > 0) {
       
// Implement Reynolds: Steering = Desired - Velocity
        steer.Unitize();
        steer *= maxspeed;
        steer -= vel;

        if(steer.Length() > maxforce)// Limit to maximum steering force
        {
          steer.Unitize();
          steer *= maxforce;
        }
      }

      return steer;
    }

 

    // Alignment
    // For every nearby boid in the system, calculate the average velocity

    public On3dVector align(List<Boid> boids)
    {
      double neighbordist = 15;//25.0;
      On3dVector steer = new On3dVector(0, 0, 0);
      int count = 0;
      foreach( Boid b in boids)
      {
        double d = loc.DistanceTo(b.loc);
    
    // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself)
        if((d > 0) && (d < neighbordist))
        {
          steer += b.vel;
          count++;
        }
      }

      if (count > 0) { // Average -- divide by how many
        steer /= count;
      }

      // As long as the vector is greater than 0
      if(steer.Length() > 0)
      {
        steer.Unitize();
        steer *= maxspeed;
        steer -= vel;

        if(steer.Length() > maxforce)
        {
          steer.Unitize();
          steer *= maxforce;
        }
      }
      return steer;
    }

    // Cohesion
    // For the average location (i.e. center) of all nearby boids,
    // calculate steering vector towards that location

    public On3dVector cohesion(List<Boid> boids)
    {
      double neighbordist = 5;//25.0;
  
    // Start with empty vector to accumulate all locations
      On3dVector sum = new On3dVector(0, 0, 0);

      int count = 0;
      foreach(Boid b in boids)
      {
        double d = loc.DistanceTo(b.loc);
        if((d > 0) && (d < neighbordist))
        {
          sum += b.loc;
          count++;
        }
      }

      if(count > 0)
      {
        sum /= count;
        return steer(sum, false);
      }

      return sum;
    }
    public On3dVector steer(On3dVector target, bool slowdown) {
      On3dVector steer;  // The steering vector
      On3dVector desired = new On3dVector(target.x - loc.x, target.y - loc.y, target.z - loc.z);
      double d = desired.Length();

      // Distance from the target is the magnitude of the vector

      // If the distance is greater than 0, calc steering (otherwise return zero vector)
      if (d > 0)
      {
      
  // Normalize desired
        desired.Unitize();
       
// Two options for desired vector magnitude (1 -- based on distance, 2 -- maxspeed)
        if ((slowdown) && (d < 100.0)) desired *= (maxspeed * (d / 100.0)); // This damping is somewhat arbitrary
        else desired *= (maxspeed);

        // Steering = Desired minus Velocity
        steer = new On3dVector(desired.x - vel.x, desired.y - vel.y, desired.z - vel.z);

        if(steer.Length() > maxforce)// Limit to maximum steering force
        {
          steer.Unitize();
          steer *= maxforce;
        }
      }
      else
      {
        steer = new On3dVector(0, 0, 0);
      }
      return steer;
    }

  }

  public class Flock
  {
    List<Boid> boids;

    public Flock()
    {
      boids = new List<Boid>();
    }

    public void run()
    {
    
  // Passing the entire list of boids to each boid individually
      foreach(Boid b in boids)
        b.run(boids);
    }

    public void addBoid(Boid b)
    {
      boids.Add(b);
    }

    public List<On3dPoint> getBoidsLocs()
    {
      List<On3dPoint> locs = new List<On3dPoint>();

      foreach(Boid b in boids)
      {
        locs.Add(b.loc);
      }

      return locs;
    }

    public List<On3dVector> getBoidsDirs()
    {
      List<On3dVector> dirs = new List<On3dVector>();
      foreach(Boid b in boids)
        dirs.Add(b.vel);

      return dirs;
    }

  }

Rhino Script : C# Coding in Grasshopper

RECURSIVE TRIANGULAR SUBDIVISION

 

Rhino Script : C# Coding in Grasshopper

  private void RunScript(List<Point3d> pointList, int num, double H, ref object A, ref object B)
  {
   
//CREATE A SURFACE OUT OF THE THREE POINT
    Brep originalSurf = Brep.CreateFromCornerPoints(pointList[0], pointList[1], pointList[2], doc.ModelAbsoluteTolerance);

    //MAKE A LIST AND ADD THE ORIGINAL SURFACE TO IT
    List<Brep> surfaceList = new List<Brep>();
    surfaceList.Add(originalSurf);

    //GET THE MIDPOINTS OF THE EDGES OF THE ORIGINAL SURFACE
    findEdgeMidPoints(originalSurf);

    //RECURSIVELY SUBDIVIDE THE ORIGINAL SURFACE
    List<Brep> subSurfaces = divideTriangles(surfaceList, H, num);

    //REFERENCE OUTPUT VARIABLES
    A = originalSurf;
    B = subSurfaces;
  }

  /*
  * THIS METHOD RECURSIVELY SUBDIVIDES AN INPUT TRIANGULAR SURFACE
  * BY FINDING THE MIDPOINTS OF THE EDGES
  */

  public List<Brep> divideTriangles(List<Brep> subSrf, double height, int N) {
    //DEFINE A STOPPING CONDITION
    if (N == 0) {
      return subSrf;
    }

    //RECURSIVE PART
    N--;
  
  //make a list to add the new subsurfaces
    List<Brep> newSubSrf = new List<Brep>();

    //for every sub surface of the input list
    foreach (Brep srf in subSrf) {
     
//call the method that gets the midpoints of the edges of the surface
      //and fills triangles by connection the midpoints to the endpoints of
      //the edges

      List<Brep> tempSrfList = findEdgeMidPointsSubsurfaces(srf, height);
      newSubSrf.AddRange(tempSrfList);
    }
    return divideTriangles(newSubSrf, height / 2, N);
  }

 

    public List<Point3d> findEdgeMidPoints(Brep surface) {
    //1. GET THE EDGES FROM THE BREP
    Curve[] edges = surface.DuplicateEdgeCurves();
    List<Point3d> midPoints = new List<Point3d>();

    //2. ITERATE OVER THE EDGES AND FIND MIDPOINTS
    for(int i = 0; i < edges.Length; i++) {
  
    //2a. GET THE EDGE
      Curve thisEdge = edges[i];
  
    //2B. GET THE MIDPOINT
      Point3d midPoint = thisEdge.PointAt(thisEdge.GetLength() / 2);
    
  //2C STORE IT IN THE LIST
      midPoints.Add(midPoint);
    }
    return midPoints;
  }

  public List<Brep> findEdgeMidPointsSubsurfaces(Brep surface, double height) {

    //1. GET THE EDGES FROM THE BREP
    Curve[] edges = surface.DuplicateEdgeCurves();

    //2. MAKE A LIST TO ADD THE NEW SUBSURFACES
    List<Brep> subSurfaces = new  List<Brep>();

    //3. GET THE NORMAL OF THE ORIGINAL FACE
    Vector3d normal = surface.Faces[0].NormalAt(0, 0);

    //4. ITERATE OVER THE EDGES AND FIND MIDPOINTS
    for(int i = 0; i < edges.Length; i++) {
    
  //GET THE ith EDGE
      Curve thisEdge = edges[i];
  
    //GET THE MIDPOINT OF THAT EDGE
      Point3d thisMidPoint = thisEdge.PointAt(thisEdge.GetLength() / 2);
   
   //MOVE THE POINT ALONG THE NORMAL VECTOR
      thisMidPoint = thisMidPoint + normal * height;

      //GET THE (i+1)th EDGE
      Curve otherEdge = edges[(i + 1) % edges.Length];
     
//GET THE MIDPOINT OF THAT EDGE
      Point3d otherMidPoint = otherEdge.PointAt(otherEdge.GetLength() / 2);
     
//MOVE THE POINT ALONG THE NORMAL VECTOR
      otherMidPoint = otherMidPoint + normal * height;

      //FIND THE ENDPOINT OF THE APPROPRIATE EDGE
      Point3d endPoint = thisEdge.PointAtEnd;

      //MAKE A SURFACE OUT OF THE TWO MIDPOINTS AND THE ENDPOINT OF THE iTH EDGE
      Brep subSurf = Brep.CreateFromCornerPoints(thisMidPoint, endPoint, otherMidPoint, doc.ModelAbsoluteTolerance);
      subSurfaces.Add(subSurf);

    }
    return subSurfaces;
  }

SURFACE SUBDIVISION BY MULTIPLE ATTRACTORS

 

  private void RunScript(Surface S, List<Point3d> Pts, int uNum, int vNum, ref object subSurface)
  {

    //Lists of x values and y values of attractors in seperate lists
    List<double> Pts_x=new List<double>(),Pts_y = new List<double>();
    foreach (Point3d pt in Pts) {
      Pts_x.Add(pt.X);
      Pts_y.Add(pt.Y);
    }

    //Calculating the intervals between grids
    double vInterval = S.Domain(1).Length / vNum;
    double uInterval = S.Domain(0).Length / uNum;

    //defining u and v in the grid
    List<double> uList = new List<double>(),vList = new List<double>();
    for (int i = 0;i < uNum ;i++){
      uList.Add(S.Domain(0).Min + uInterval * i);
    }
    for (int i = 0;i < vNum;i++){
      vList.Add(S.Domain(1).Min + vInterval * i);
    }

    //subSurf is the output of the script
    List<Brep> subSurf = new List<Brep>();
    Brep surf;

    //finding domain values for both x and y
    List<double> iso_u = new List<double>(),iso_v = new List<double>();
    iso_u = isoCrvGen(Pts_x, uList);
    iso_v = isoCrvGen(Pts_y, vList);

    //Calculate the subsurface by having the domain values
    Point3d p1,p2,p3,p4;
    for (int i = 0;i < iso_u.Count - 1;i++){
      for (int j = 0;j < iso_v.Count - 1;j++){
        p1 = S.PointAt(iso_u[i] * uNum, iso_v[j] * vNum);
        p2 = S.PointAt(iso_u[i + 1] * uNum, iso_v[j] * vNum);
        p3 = S.PointAt(iso_u[i] * uNum, iso_v[j + 1] * vNum);
        p4 = S.PointAt(iso_u[i + 1] * uNum, iso_v[j + 1] * vNum);

 

Rhino Script : C# Coding in Grasshopper

        //creating each subsurface by the four points and adding it to the final subsurface list
        surf = Brep.CreateFromCornerPoints(p1, p3, p4, p2, doc.ModelAbsoluteTolerance);
        subSurf.Add(surf);
      }
    }

    //OUTPUT
    subSurface = subSurf;

  }

  //<Custom additional code>

  //Here is a method which we do most of the calculations to get the domains
  private List<double> isoCrvGen(List<double> Pts, List<double> list){
    List<double> mathAdd = new List<double>();
    try{
      foreach(double k in list){
        double tempdist = 0;
        for(int i = 0;i < Pts.Count;i++){

          // Here we may have divide by zero so we add try catch to catch this exception
          tempdist += 1 / Math.Abs((Pts[i] - k));
        }
        mathAdd.Add(tempdist);
      }
      for(int i = 0;i < mathAdd.Count - 1;i++){
        mathAdd[i + 1] = mathAdd[i] + mathAdd[i + 1];
      }
      mathAdd[0] = 0;

      double m = mathAdd[mathAdd.Count - 1] - mathAdd[0];
      for(int i = 0;i < mathAdd.Count;i++){
        mathAdd[i] = mathAdd[i] / m;
      }
    }catch{
      Console.Write("Divide by Zero");
    }
    return mathAdd;
  }

PARAMETRIC SCRIPTING

 

These examples are done in

"Parametric Design" Course,

Special Thanks to Professor Ramesh Krishnamurti

Fall 2012 

 

 

 

bottom of page