Grasshopper: Get intersection points between a list of lines with C#

The following code will produce a list of points that correspond with the intersection points between an assorted list of lines.

It is written for the C# component in Grasshopper, but can be adapted to a compiled component if desired.

Note the check that 0<a<1 and 0<b<1. This represents the requirement that we want intersections to occur along the length of the line, otherwise we aren’t interested in them. If we are also interested in implied intersections (i.e. where we imagine each line continues to infinity in both directions) then we can discard this ‘if’ statement.

And a note to my future self, this code worked on quick tests but was buggy on a real project, so the code below is for reference only!

  private void RunScript(List<Line> x, ref object A)
  {

    List<Point3d> rtn_pts = new List<Point3d>();
    for (int i = 0; i < x.Count - 1; i++)
    {
      for (int j = i + 1; j < x.Count; j++)
      {
        double a;
        double b;
        Rhino.Geometry.Intersect.Intersection.LineLine(x[i], x[j], out a, out b);
        if(a >= 0 && a <= 1 && b > 0 && b < 1)
        {
          rtn_pts.Add(new Point3d(x[i].PointAt(a)));
        }
      }
    }

    A = rtn_pts;

  }

Mesh line intersections in Grasshopper in C#

Many intersection checks are possible in C# in Grasshopper, although finding them isn’t entirely intuitive.

One task I wanted to do today was to see if a ray of light between one point and another was being blocked by a mesh. This requires a mesh-line intersection check – to check if the ray of light was being blocked by the mesh.

How to calculate an intersection

You can find a lot of intersection methods for different kinds of geometry under Rhino.Geometry.Intersection. The mesh line intersection is a good choice as it is one of the faster intersection checks – especially compared to anything involving surfaces.

To do the intersection check, we need our mesh and our ray. The ray can be a bit challenging to set up – it’s a common mistake to forget to realise that your line start and end points might be touching the mesh, which would lead to positive intersection results. This is why I’ve redefined my line to run from 0.001 to 0.999.

        //collision test
        var ln = new Line(e[em], centre); //ray
        var startpt = new Point3d(ln.PointAt(0.001)); //modify ray so start/end don't intersect
        var endpt = new Point3d(ln.PointAt(0.999));
        ln.From = startpt;
        ln.To = endpt;
        Int32[] intersections; //where intersection locations are held
        Rhino.Geometry.Intersect.Intersection.MeshLine(r, ln, out intersections);

        //calculate emission contribution and add to that receiver
        if(intersections == null)
        {
          //if no intersections, we can assume ray is unimpeded and do our calcs
          double contribution = Math.Cos(alpha) / (dist * dist);
          rtnvals[f] += Math.Max(contribution, 0);
        }