Trimming Problem

I’m trying to make a function that can trim out a section of a curve that overlaps itself, and I’m having two issues:

 for (int i = 0; i < c.Count; i++)
	            {
	            	List<Point3d> intersectionEventPoints = new List<Point3d>();
	            	List<Point3d> intersectionPoints = new List<Point3d>();
	            	List<double> intersectionParameters = new List<double>();
					Rhino.Geometry.Intersect.CurveIntersections intersectionEvents = Rhino.Geometry.Intersect.Intersection.CurveSelf(c[i], 0.0);
					
					foreach (var e in intersectionEvents)
					{
						intersectionEventPoints.Add(e.PointA);
					}
					Write("intersectionEventPoints.Count: ", intersectionEventPoints.Count);
					if (intersectionEventPoints.Count != 0)
					{
						intersectionPoints.Add(intersectionEventPoints[0]);
						
						for (int e = 1; e < intersectionEventPoints.Count; e++)
						{
							if (intersectionEventPoints[e] == intersectionEventPoints[e-1] && intersectionPoints.IndexOf(intersectionEventPoints[e]) == -1)
							{
								intersectionPoints.Add(intersectionEventPoints[e]);
							}
						}
						
						for (int e = 0; e < intersectionPoints.Count; e++)
						{
							double t = 0.0;
							
							if (c[i].ClosestPoint(intersectionPoints[e], out t, .00000001))
							{
								intersectionParameters.Add(t);
								doc.Objects.AddPoint(c[i].PointAt(t));
							}
						}
						Write("int points count: ", intersectionPoints.Count);
						Write("# parameter count: ", intersectionParameters.Count);
						Write("end parameter: ", intersectionParameters[intersectionParameters.Count - 1]);
						if (true)
						{
							c[i].Trim(0.0, intersectionParameters[intersectionParameters.Count - 1]);
						}
					}
	
	                //if there are intersection points
	                    //extract intersection pts (if there's more than one point)
	                        //add first intersection point to list
	                            //for intersecrion pts count
	                                //if next point does not equal pt before
	                                    //add it to list
	                    //if the end point of the curve appears in the curve more than once
	                        //trim curve from last intersection to end point
	            }
	        }

(c is my list of curves)
When I call “doc.Objects.AddPoint(c[i].PointAt(t))”, it should plot the point at the intersection where the curve overlaps. However, the point goes a little beyond that (I included the rhino file). That’s the first problem, I want the code to plot the point at the correct position. My second problem is calling the Trim method at the end. From what I understand, calling “c[i].Trim(0.0, intersectionParameters[intersectionParameters.Count - 1])” should trim anything outside the interval, but nothing happens to the curve (or at least nothing that I can see).

There is a third, smaller issue, not so important, but (using the curve in the file) when I call:

Write("end parameter: ", intersectionParameters[intersectionParameters.Count - 1])

it gives me a value of 0.0841803174131271, which seems a bit off, because the circle consists of about 70 control points, and if t is less than .1 I’m assuming the point would be close to the start, not after a full round of the circle. The reason I don’t see this as a big issue, though, is because the point of intersection appears in (relatively) the right place.

Thank you for any help!

Here’s the file:
Problem 2.3dm (20.7 KB)

I think the problem is that the start and end control points do not lie exactly on the curve, there is like 1e-6 mm distance between.
Why not use the code below - I have tested it for the case you have posted.

protected Result RunCommand(RhinoDoc doc, RunMode mode) 
{
    ObjRef cRef;
    Result res = RhinoGet.GetOneObject("Select self-intersecting curve", false, ObjectType.Curve, out cRef);
    if (res != Result.Success || null == cRef)
        return res;

    Curve crv = cRef.Curve();
    // to prevent finding the start point as closest point, make a subcurve so that the 
    // point at start is relatively far removed from the original start point compared to the closest
    // point on the curve
    Curve subCurveFromStart = crv.ToNurbsCurve(new Interval(crv.Domain.T0 + 0.01*crv.Domain.Length, crv.Domain.T1));
            
    double t;
    if (subCurveFromStart.ClosestPoint(crv.PointAtStart, out t))
    {
        Curve trimFromStart = crv.ToNurbsCurve(new Interval(crv.Domain.T0, t));
        if (!trimFromStart.IsClosed && trimFromStart.IsClosable(double.MaxValue))
            trimFromStart.MakeClosed(double.MaxValue);
        doc.Objects.AddCurve(trimFromStart);
    }

    doc.Views.Redraw();
    return Result.Success;
}

This is amazing, thanks! It provides an alternative to the Trim method, and it also has a better way of rooting out the intersection points.

Is there a way to find overlap points rather than intersection points? In the Rhino file I sent a couple posts ago, the code sent me the self intersection of the curve close to the start point and trims the excess curve, resulting in a closed curve. However, it doesn’t work with a curve like this:

Problem 3.3dm (30.1 KB)

When I used your algorithm by itself, or combined its idea with my original algorithm, on that curve in “Problem 3” it took out the top left petal. What I understood from this is that our algorithms don’t count for overlapping points, just the self-intersecting ones.

What I’m thinking is to take into account all the self-intersecting points (in “Problem 3”, the only point would be {0,0} ) and find every point at “d” distance after it (I would get I think 7 points, 2 of them repeated twice and 1 of them repeated thrice) , and trim the curve after the first repeated point.

Is this an effective algorithm to solve my problem? If not, what would you suggest I do to make it better? Thanks for all your help!