Crv Crv Intersections - Compare all curves against all curves in a list C#

I am missing something here…
I have list of curves and I want to compare every curves against every other curve. I thought creating a nested loop and offsetting the second list would accomplish this; however, I am returning erroneous results.

  private void RunScript(List<Circle> crvLst, ref object A, ref object B)
  {
    List<bool> inxs = new List<bool>();
    List<Curve> outCrvs = new List<Curve>();

    for (int i = 0; i < crvLst.Count - 1; i++)
    {
      for (int j = i + 1; j < crvLst.Count; j++)
      {
        //check for intersections
        bool intx = Curve.PlanarCurveCollision(crvLst[i].ToNurbsCurve(),
          crvLst[j].ToNurbsCurve(), Plane.WorldXY, 0.001);

        inxs.Add(intx);

        //add to list if crvs do not intersect
        if(inxs[i] == false)
          outCrvs.Add(crvLst[i].ToNurbsCurve());
      }
    }

    A = outCrvs; //non-intersecting crvs
    B = inxs; //all bool results

ccx_confusion.gh (18.1 KB)

Many pairs will result in False, and only a handful in True. Why not only report the intersection, i.e. true, results?

Also, you’re accessing intx[i] inside the j-loop.

@menno Thanks for the reply.

I moved the intx[i] outside of the j-loop and am now getting an ‘index out of range error’. I believe the problem lies in this line:

    if(inxs[i] == true)
      outCrvs.Add(crvLst[i].ToNurbsCurve());

The correct curves are not being added to the new list. I moved this statement to the scope of the i-loop and changed checked for true bool values and get 78 intersections which seems right. However, all curves were on top of each other which confirms my suspicion that the above line is written wrong. Keeping the statement in the scope of the j-loop returns all false values.

Thank you.

It does not return all false values, it returns true where it should be true.

I guess it depends on what your ultimate goal is. If it is to find all curves that do not intersect with any other curve, use the following code (note that I have use the fact that you’re looking at circles, so you don’t need Curve.PlanarCurveCollision(...) and can just look at location of circle centers and compare the sum of radii.

image

private void RunScript(List<Circle> crvLst, ref object A, ref object B)
{
List<bool> inxs = new List<bool>();
List<Circle> outCrvs = new List<Circle>();

for (int i = 0; i < crvLst.Count; i++)
{
  Circle ci = crvLst[i];
  double ri = ci.Radius;

  bool intersects = false;
  for (int j = 0; j < crvLst.Count; j++)
  {
	if (i == j) continue;
	
	Circle cj = crvLst[j];
	double rj = cj.Radius;

	double distCenters = ci.Center.DistanceTo(cj.Center);

	if (distCenters < ri + rj) // fast test to see if circles intersect
	{
	  // the circles intersect;
	  intersects = true;
	  break;
	}
  }
  if (!intersects)
  {
	outCrvs.Add(ci);
  }
}

A = outCrvs; //non-intersecting crvs
B = inxs; //all bool results
}

@menno - Yes, this is the ultimate goal. This is an interesting approach using radii and DistanceTo. A coworker of mine came up with similar code structure, but different logic to achieve the same result. I’ll post it tomorrow or so when I get to work.

Thanks for the help. This is very clear.