using System.Collections.Generic;
public class Point3D:IEquatable<Point3D>
public double X {get;set;}
public double Y {get;set;}
public double Z {get;set;}
public Point3D(double x, double y, double z)
public bool Equals(Point3D other)
return X == other.X && Y ==other.Y && Z==other.Z;
public Point3D Start{get;set;}
public Point3D End{get;set;}
public Line3D(Point3D start, Point3D end)
public static class GeometryExtensions
public static ISet<Line3D> GetGeometry(this Line3D line, IEnumerable<Line3D> lines, ISet<Line3D> currentGeometry = null)
currentGeometry = currentGeometry??new HashSet<Line3D>();
currentGeometry.Add(line);
foreach(var l in line.GetLinesConnected(lines).Except(currentGeometry))
if(currentGeometry.Add(l))
currentGeometry.UnionWith(l.GetGeometry(lines,currentGeometry));
public static IEnumerable<Line3D> GetLinesConnected(this Line3D line, IEnumerable<Line3D> lines)
return line.Points().SelectMany(p=> p.GetLinesConnected(lines)).Distinct();
private static IEnumerable<Line3D> GetLinesConnected(this Point3D point, IEnumerable<Line3D> lines)
return lines.Where(line=> line.Points().Any(point.Equals));
private static IEnumerable<Point3D> Points(this Line3D line)
return new[] {line.Start, line.End};
public class SetComparer<T>:IEqualityComparer<ISet<T>>
public bool Equals(ISet<T> left, ISet<T> right)
return left.SetEquals(right);
public int GetHashCode(ISet<T> obj)
return obj.Select(x=> x.GetHashCode()).Aggregate((l,r)=> l ^ r);
private static List<Line3D> Items = new List<Line3D>()
new Line3D(new Point3D(-15.7211472701278,2.04684012635302,619.849278950602), new Point3D(-12.0056467082762,4.46365434678632,619.849278950604)),
new Line3D(new Point3D(-8.96899268868424,0.593709288498887,619.849278950608), new Point3D(-12.0056467082762,4.46365434678632,619.849278950604)),
new Line3D(new Point3D(-15.7211472701278,2.04684012635302,619.849278950602), new Point3D(-21.2743629301898,2.45264355105874,619.849278950607)),
new Line3D(new Point3D(4.01452021588041,4.02909342306791,619.849278950608), new Point3D(-4.5902686315683,4.0947788330322,619.849278950607)),
new Line3D(new Point3D(-4.5902686315683,4.0947788330322,619.849278950607), new Point3D(-8.96899268868424,0.593709288498887,619.849278950608))
private static List<Line3D> Items2 = new List<Line3D>()
new Line3D(new Point3D(-14.64,7.20,6.45),new Point3D(-21.92,7.20,-0.86)),
new Line3D(new Point3D(-21.92,7.20,-0.86), new Point3D(-18.95,7.20,-14.87)),
new Line3D(new Point3D(-18.95,7.20,-14.87), new Point3D(-6.49,7.20,-21.78)),
new Line3D(new Point3D(-8.20,-1.34,15.02), new Point3D(-23.45,-1.34,-0.65)),
new Line3D(new Point3D(-23.45,-1.34,-0.65), new Point3D(-17.86,-1.34,-24.46)),
new Line3D(new Point3D(-17.86,-1.34,-24.46), new Point3D(-0.14,-1.34,-33.10)),
new Line3D(new Point3D(-0.14,-1.34,-33.10), new Point3D(4.64,-1.34,-10.67)),
new Line3D(new Point3D(4.64,-1.34,-10.67), new Point3D(-8.20,-1.34,15.02)),
new Line3D(new Point3D(9.98,-3.80,15.02), new Point3D(9.98,16.05,15.02)),
new Line3D(new Point3D(9.98,16.05,15.02), new Point3D(1.23,38.74,15.02))
public static bool AreConnected(Line3D left, Line3D right)
var pointsInvolved = new[] {left.Start,left.End,right.Start,right.End};
return pointsInvolved.Any(lp=> (pointsInvolved.Where(rp => lp.Equals(rp)).Count()>1));
public static void Main()
foreach(var geometry in target.Select(line=> line.GetGeometry(target)).Distinct(new SetComparer<Line3D>()))
Console.Write("Group " + count + ": [");
Console.Write(geometry.Select(line=> target.IndexOf(line).ToString()).Aggregate((l,r)=> l + ", " + r));