/// <summary> /// This is called by the "ConvexHull" class. /// </summary> /// <typeparam name="TVertex"></typeparam> /// <typeparam name="TFace"></typeparam> /// <param name="data"></param> /// <param name="config">If null, default ConvexHullComputationConfig.GetDefault() is used.</param> /// <returns></returns> internal static ConvexHull <TVertex, TFace> GetConvexHull <TVertex, TFace>(IList <TVertex> data, ConvexHullComputationConfig config) where TFace : ConvexFace <TVertex, TFace>, new() where TVertex : IVertex { config = config ?? new ConvexHullComputationConfig(); var vertices = new IVertex[data.Count]; for (int i = 0; i < data.Count; i++) { vertices[i] = data[i]; } ConvexHullInternal ch = new ConvexHullInternal(vertices, false, config); ch.FindConvexHull(); var hull = new TVertex[ch.ConvexHull.Count]; for (int i = 0; i < hull.Length; i++) { hull[i] = (TVertex)ch.Vertices[ch.ConvexHull[i]]; } return(new ConvexHull <TVertex, TFace> { Points = hull, Faces = ch.GetConvexFaces <TVertex, TFace>() }); }
public static ConvexHull <TVertex, TFace> Create(IList <TVertex> data, ConvexHullComputationConfig config) { if (data == null) { throw new ArgumentNullException("data"); } return(ConvexHullInternal.GetConvexHull <TVertex, TFace>(data, config)); }
/// <summary> /// This is used by the Delaunay triangulation code. /// </summary> /// <typeparam name="TVertex"></typeparam> /// <typeparam name="TFace"></typeparam> /// <param name="data"></param> /// <returns></returns> internal static List <ConvexFaceInternal> GetConvexFacesInternal <TVertex, TFace>(IEnumerable <TVertex> data) where TFace : ConvexFace <TVertex, TFace>, new() where TVertex : IVertex { ConvexHullInternal ch = new ConvexHullInternal(data.Cast <IVertex>()); ch.GetConvexHullInternal <TVertex>(true); return(ch.ConvexFaces); }
/// <summary> /// This is called by the "ConvexHull" class. /// </summary> /// <typeparam name="TVertex"></typeparam> /// <typeparam name="TFace"></typeparam> /// <param name="data"></param> /// <returns></returns> internal static Tuple <IEnumerable <TVertex>, IEnumerable <TFace> > GetConvexHullAndFaces <TVertex, TFace>(IEnumerable <IVertexPosition> data) where TFace : ConvexFace <TVertex, TFace>, new() where TVertex : IVertexPosition { ConvexHullInternal ch = new ConvexHullInternal(data); return(Tuple.Create( ch.GetConvexHullInternal <TVertex>(), ch.GetConvexFacesInternal <TVertex, TFace>())); }
public ObjectManager(ConvexHullInternal hull) { this.Dimension = hull.Dimension; this.Hull = hull; this.FacePool = hull.FacePool; this.FacePoolSize = 0; this.FacePoolCapacity = hull.FacePool.Length; this.FreeFaceIndices = new IndexBuffer(); this.EmptyBufferStack = new SimpleList <IndexBuffer>(); this.DeferredFaceStack = new SimpleList <DeferredFace>(); }
/// <summary> /// Create the manager. /// </summary> /// <param name="hull"></param> public ObjectManager(ConvexHullInternal hull) { this.Dimension = hull.Dimension; this.Hull = hull; this.FacePool = hull.FacePool; this.FacePoolSize = 0; this.FacePoolCapacity = hull.FacePool.Length; this.FreeFaceIndices = new IndexBuffer(); this.EmptyBufferStack = new SimpleList<IndexBuffer>(); this.DeferredFaceStack = new SimpleList<DeferredFace>(); }
/// <summary> /// This is called by the "ConvexHull" class. /// </summary> /// <typeparam name="TVertex"></typeparam> /// <typeparam name="TFace"></typeparam> /// <param name="data"></param> /// <returns></returns> internal static void GetConvexHullAndFaces <TVertex, TFace>(IEnumerable <IVertex> data, out IEnumerable <TVertex> points, out IEnumerable <TFace> faces) where TFace : ConvexFace <TVertex, TFace>, new() where TVertex : IVertex { ConvexHullInternal ch = new ConvexHullInternal(data); points = ch.GetConvexHullInternal <TVertex>(); faces = ch.GetConvexFacesInternal <TVertex, TFace>(); // return Tuple.Create( // ch.GetConvexHullInternal<TVertex>(), // ch.GetConvexFacesInternal<TVertex, TFace>()); }
internal static ConvexHull <TVertex, TFace> GetConvexHull <TVertex, TFace>(IList <TVertex> data, ConvexHullComputationConfig config) where TVertex : IVertex where TFace : ConvexFace <TVertex, TFace>, new() { config ??= new ConvexHullComputationConfig(); IVertex[] vertices = new IVertex[data.Count]; for (int i = 0; i < data.Count; i++) { vertices[i] = data[i]; } ConvexHullInternal internal2 = new ConvexHullInternal(vertices, false, config); internal2.FindConvexHull(); return(new ConvexHull <TVertex, TFace> { Points = internal2.GetHullVertices <TVertex>(data), Faces = internal2.GetConvexFaces <TVertex, TFace>() }); }
/// <summary> /// Computes the Delaunay triangulation. /// </summary> /// <typeparam name="TVertex"></typeparam> /// <typeparam name="TCell"></typeparam> /// <param name="data"></param> /// <param name="config"></param> /// <returns></returns> internal static TCell[] GetDelaunayTriangulation <TVertex, TCell>(IList <TVertex> data, TriangulationComputationConfig config) where TCell : TriangulationCell <TVertex, TCell>, new() where TVertex : IVertex { config = config ?? new TriangulationComputationConfig(); var vertices = new IVertex[data.Count]; for (int i = 0; i < data.Count; i++) { vertices[i] = data[i]; } ConvexHullInternal ch = new ConvexHullInternal(vertices, true, config); ch.FindConvexHull(); ch.PostProcessTriangulation(config); return(ch.GetConvexFaces <TVertex, TCell>()); }
/// <summary> /// Creates the Delaunay triangulation of the input data. /// </summary> /// <param name="data"></param> /// <param name="config">If null, default ConvexHullComputationConfig is used.</param> /// <returns></returns> public static DelaunayTriangulation <TVertex, TCell> Create(IList <TVertex> data, TriangulationComputationConfig config) { if (data == null) { throw new ArgumentNullException("data"); } if (data.Count == 0) { return new DelaunayTriangulation <TVertex, TCell> { Cells = new TCell[0] } } ; config = config ?? new TriangulationComputationConfig(); var cells = ConvexHullInternal.GetDelaunayTriangulation <TVertex, TCell>(data, config); return(new DelaunayTriangulation <TVertex, TCell> { Cells = cells }); }
/// <summary> /// Creates the Delaunay triangulation of the input data. /// Be careful with concurrency, because during the computation, the vertex position arrays get resized. /// </summary> /// <param name="data"></param> /// <returns></returns> public static DelaunayTriangulation <TVertex, TCell> Create(IEnumerable <TVertex> data) { if (data == null) { throw new ArgumentException("data can't be null."); } if (!(data is IList <TVertex>)) { data = data.ToArray(); } if (data.Count() == 0) { return new DelaunayTriangulation <TVertex, TCell> { Cells = Enumerable.Empty <TCell>() } } ; int dimension = data.First().Position.Length; // Resize the arrays and lift the data. foreach (var p in data) { double lenSq = StarMath.norm2(p.Position, dimension, true); var v = p.Position; Array.Resize(ref v, dimension + 1); p.Position = v; p.Position[dimension] = lenSq; } // Find the convex hull var delaunayFaces = ConvexHullInternal.GetConvexFacesInternal <TVertex, TCell>(data); // Resize the data back foreach (var p in data) { var v = p.Position; Array.Resize(ref v, dimension); p.Position = v; } // Remove the "upper" faces for (var i = delaunayFaces.Count - 1; i >= 0; i--) { var candidate = delaunayFaces[i]; if (candidate.Normal[dimension] >= 0) { for (int fi = 0; fi < candidate.AdjacentFaces.Length; fi++) { var f = candidate.AdjacentFaces[fi]; if (f != null) { for (int j = 0; j < f.AdjacentFaces.Length; j++) { if (object.ReferenceEquals(f.AdjacentFaces[j], candidate)) { f.AdjacentFaces[j] = null; } } } } var li = delaunayFaces.Count - 1; delaunayFaces[i] = delaunayFaces[li]; delaunayFaces.RemoveAt(li); } } // Create the "TCell" representation. int cellCount = delaunayFaces.Count; var cells = new TCell[cellCount]; for (int i = 0; i < cellCount; i++) { var face = delaunayFaces[i]; var vertices = new TVertex[dimension + 1]; for (int j = 0; j <= dimension; j++) { vertices[j] = (TVertex)face.Vertices[j].Vertex; } cells[i] = new TCell { Vertices = vertices, Adjacency = new TCell[dimension + 1] }; face.Tag = i; } for (int i = 0; i < cellCount; i++) { var face = delaunayFaces[i]; var cell = cells[i]; for (int j = 0; j <= dimension; j++) { if (face.AdjacentFaces[j] == null) { continue; } cell.Adjacency[j] = cells[face.AdjacentFaces[j].Tag]; } } return(new DelaunayTriangulation <TVertex, TCell> { Cells = cells }); }