private static FuzzySet Merge(FuzzySet fs1, FuzzySet fs2, Func <double, double, double> MergeFt) { // New Fuzzy set FuzzySet result = new FuzzySet(Math.Min(fs1.Min, fs2.Min), Math.Max(fs1.Max, fs2.Max)); // Creation of iterators on lists + initialization List <Point2D> .Enumerator enum1 = fs1.Points.GetEnumerator(); List <Point2D> .Enumerator enum2 = fs2.Points.GetEnumerator(); enum1.MoveNext(); enum2.MoveNext(); Point2D oldPt1 = enum1.Current; // Relative positions of fuzzy sets (to know when they intersect) int relativePosition = 0; int newRelativePosition = Math.Sign(enum1.Current.Y - enum2.Current.Y); // Loop while there are points in the two collections Boolean endOfList1 = false; Boolean endOfList2 = false; while (!endOfList1 && !endOfList2) { // New x values double x1 = enum1.Current.X; double x2 = enum2.Current.X; // New current position relativePosition = newRelativePosition; newRelativePosition = Math.Sign(enum1.Current.Y - enum2.Current.Y); if (relativePosition != newRelativePosition && relativePosition != 0 && newRelativePosition != 0) { // Positions have changed, so we have to compute the intersection and add it // Compute the points coordinates double x = (x1 == x2 ? oldPt1.X : Math.Min(x1, x2)); double xPrime = Math.Max(x1, x2); // Intersection double slope1 = (fs1.DegreeAtValue(xPrime) - fs1.DegreeAtValue(x)) / (xPrime - x); double slope2 = (fs2.DegreeAtValue(xPrime) - fs2.DegreeAtValue(x)) / (xPrime - x); double delta = (fs2.DegreeAtValue(x) - fs1.DegreeAtValue(x)) / (slope1 - slope2); // Add point result.Add(x + delta, fs1.DegreeAtValue(x + delta)); // Go on if (x1 < x2) { oldPt1 = enum1.Current; endOfList1 = !(enum1.MoveNext()); } else if (x1 > x2) { endOfList2 = !(enum2.MoveNext()); } } else if (x1 == x2) { // The two points are on the same X, so we take the good value (eg min or max) result.Add(x1, MergeFt(enum1.Current.Y, enum2.Current.Y)); oldPt1 = enum1.Current; endOfList1 = !(enum1.MoveNext()); endOfList2 = !(enum2.MoveNext()); } else if (x1 < x2) { // Fs1 point is first, we add the value (eg min or max) between the enum1 point and the degree for fs2 result.Add(x1, MergeFt(enum1.Current.Y, fs2.DegreeAtValue(x1))); oldPt1 = enum1.Current; endOfList1 = !(enum1.MoveNext()); } else { // This time, it's fs2 first result.Add(x2, MergeFt(fs1.DegreeAtValue(x2), enum2.Current.Y)); endOfList2 = !(enum2.MoveNext()); } } // Add end points if (!endOfList1) { while (!endOfList1) { result.Add(enum1.Current.X, MergeFt(0, enum1.Current.Y)); endOfList1 = !enum1.MoveNext(); } } else if (!endOfList2) { while (!endOfList2) { result.Add(enum2.Current.X, MergeFt(0, enum2.Current.Y)); endOfList2 = !enum2.MoveNext(); } } return(result); }