internal bool ConnectedTo(Segment s) { foreach (Segment seg in A.Segments) { if (seg.Equals(this)) continue; if (seg.Equals(s)) return true; if (seg.ConnectedTo(s)) return true; } foreach (Segment seg in B.Segments) { if (seg.Equals(this)) continue; if (seg.Equals(s)) return true; if (seg.ConnectedTo(s)) return true; } return false; }
/// <summary> /// Create the segment list and the final segments /// </summary> private void CalculateSegments() { //disconnect everything foreach (GraphPoint p in points) p.Segments.Clear(); segments.Clear(); //this will be the final number of segments (n-1) int totalFinalSegments = points.Count - 1; int finalSegments = 0; //create all segments points.ForEach(delegate(GraphPoint p) { Segment minSegment = null; GraphPoint minPoint = null; double minDistance = double.MaxValue; //iterate through all the points to create the segments points.Where(x => !x.Equals(p)).ToList().ForEach(delegate(GraphPoint p1) { Segment s = new Segment(p, p1); //this is the smallest distance we've found so far if (s.Distance < minDistance) { minPoint = p1; minDistance = s.Distance; minSegment = s; } //make sure we have the right reference to the segment in the list if (!segments.Contains(minSegment)) segments.Add(minSegment); else minSegment = segments.Single(x => x.Equals(minSegment)); }); //make sure the points exist and aren't already connected if (minPoint != null && !p.ConnectedTo(minPoint) && !minSegment.IsFinal) { minSegment.MakeFinal(); finalSegments++; } }); //only loop until we know we have the right number of segments if (finalSegments < totalFinalSegments) { //order all segments by distance ascending segments.Sort((seg1, seg2) => seg1.Distance.CompareTo(seg2.Distance)); //keep looping until we've gotten all the segments we expect to get while (finalSegments < totalFinalSegments) { //only get those that aren't connected, or we already know would create a cycle foreach (Segment s in segments.Where(x => !x.IsFinal && !x.IsRedundant)) { //we have the right number so stop looping if (finalSegments >= totalFinalSegments) break; //call recursive function to see if the two points are already connected if (!s.A.ConnectedTo(s.B)) { s.MakeFinal(); finalSegments++; } else //these points are connected by other final segments and would create a cycle, so don't check them anymore s.MakeRedundant(); } } } }