Get a point between two points in Grasshopper with C#

How to get a point a certain ratio between two points in Grasshopper, using the C# component.

The method below allows you to return a point between two input points. Input two Point3d values and a number between 0 and 1.

‘Ratio’ is a value between 0 and 1. Enter 0 and the resultant point will be on top of frompt. Enter 1 and it will be on top of the topt. Enter something between, and the point will also be between. You can also enter a value that is !=[0,1] to extrapolate.

The easiest way to use the method is to paste it into the ‘additional code’ section of the C# component.

C# method

  private void RunScript(Point3d pt1, Point3d pt2, double t, ref object A)
  {

    A = MovePoint(pt1, pt2, t);

  }

  // <Custom additional code> 
  public Point3d MovePoint(Point3d frompt, Point3d topt, double ratio)
  {
    return new Point3d(ratio * (topt.X - frompt.X) + frompt.X, 
      ratio * (topt.Y - frompt.Y) + frompt.Y, 
      ratio * (topt.Z - frompt.Z) + frompt.Z);
  }
  // </Custom additional code> 

Grasshopper C# component points ratio

Points in Rhino viewport from Grasshopper

Check whether points are inside a polyline curve in Grasshopper with C#

Let’s say you have a polyline in Grasshopper. You also have some points, some of them inside the curve and some of them outside. You want to sort the points depending on whether they are inside or outside the curve.

This component allows you to do that. Input your polyline and your points to check. The ‘A’ list will contain the points inside the curve, and the ‘B’ list will contain the points outside the curve.

inside-curve-component

This will then produce the following output:

A check in Grasshopper to test whether points are inside a polyline curve

Download component

The following component is a user object that allows the input of a single polyline.



If you are working with multiple polylines, and want to check that points are inside or outside every polyline at once, have a look at this file instead.

Source code

If you prefer, you can use the source code directly from below. It is formatted for the C# component in Grasshopper, though of course it can be easily generalised.

private void RunScript(List<Point3d> pts, Polyline crv, ref object A, ref object B)
  {

    var inside = new List<Point3d>();
    var outside = new List<Point3d>();

    foreach (Point3d pt in pts)
    {
      if(IsInside(pt, crv))
      {
        inside.Add(pt);
      }
      else outside.Add(pt);
    }
    A = inside;
    B = outside;

  }

  // <Custom additional code> 

  bool IsInside (Point3d pt, Polyline crv)
  {
    Point3d pt1, pt2;
    bool oddNodes = false;

    for (int i = 0; i < crv.SegmentCount; i++) //for each contour line
    {

      pt1 = crv.SegmentAt(i).From; //get start and end pt
      pt2 = crv.SegmentAt(i).To;

      if ( (pt1[1] < pt[1] && pt2[1] >= pt[1] || pt2[1] < pt[1] && pt1[1] >= pt[1]) && (pt1[0] <= pt[0] || pt2[0] <= pt[0]) ) //if pt is between pts in y, and either of pts is before pt in x
        oddNodes ^= ( pt2[0] + (pt[1] - pt2[1]) * (pt1[0] - pt2[0]) / (pt1[1] - pt2[1]) < pt[0] ); //^= is xor
      //end.X + (pt-end).Y   * (start-end).X  /(start-end).Y   <   pt.X
    }


    if (!oddNodes)
    {
      double minDist = 1e10;
      for (int i = 0; i < crv.SegmentCount; i++) {
        Point3d cp = crv.SegmentAt(i).ClosestPoint(pt, true);
        //Point3d cp = mvContour[i].closestPoint(pt);
        //minDist = min(minDist, cp.distance(pt));
        minDist = Math.Min(minDist, cp.DistanceTo(pt));
      }
      if (minDist < 1e-10)
        return true;
    }

    if(oddNodes) return true;

    return false;
  }