Beispiel #1
0
        /// <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>()
            });
        }
Beispiel #2
0
 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));
 }
Beispiel #3
0
        /// <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);
        }
Beispiel #4
0
        /// <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>()));
        }
Beispiel #5
0
 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>();
 }
Beispiel #6
0
        /// <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>();
        }
Beispiel #7
0
        /// <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>());
        }
Beispiel #8
0
        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>()
            });
        }
Beispiel #9
0
        /// <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
            });
        }
Beispiel #11
0
        /// <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
            });
        }