/****************************************************************************** * * The MIT License (MIT) * * MIConvexHull, Copyright (c) 2015 David Sehnal, Matthew Campbell * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * *****************************************************************************/ namespace NWH.DWP2.MiConvexHull { /// /// For deferred face addition. /// internal sealed class DeferredFace { /// /// The faces. /// public ConvexFaceInternal Face, Pivot, OldFace; /// /// The indices. /// public int FaceIndex, PivotIndex; } /// /// A helper class used to connect faces. /// internal sealed class FaceConnector { /// /// The edge to be connected. /// public int EdgeIndex; /// /// The face. /// public ConvexFaceInternal Face; /// /// The hash code computed from indices. /// public uint HashCode; /// /// Next node in the list. /// public FaceConnector Next; /// /// Prev node in the list. /// public FaceConnector Previous; /// /// The vertex indices. /// public int[] Vertices; /// /// Ctor. /// /// The dimension. public FaceConnector(int dimension) { Vertices = new int[dimension - 1]; } /// /// Updates the connector. /// /// The face. /// Index of the edge. /// The dim. public void Update(ConvexFaceInternal face, int edgeIndex, int dim) { Face = face; EdgeIndex = edgeIndex; uint hashCode = 23; unchecked { int[] vs = face.Vertices; int i, c = 0; for (i = 0; i < edgeIndex; i++) { Vertices[c++] = vs[i]; hashCode += 31 * hashCode + (uint) vs[i]; } for (i = edgeIndex + 1; i < vs.Length; i++) { Vertices[c++] = vs[i]; hashCode += 31 * hashCode + (uint) vs[i]; } } HashCode = hashCode; } /// /// Can two faces be connected. /// /// a. /// The b. /// The dim. /// true if XXXX, false otherwise. public static bool AreConnectable(FaceConnector a, FaceConnector b, int dim) { if (a.HashCode != b.HashCode) { return false; } int[] av = a.Vertices; int[] bv = b.Vertices; for (int i = 0; i < av.Length; i++) { if (av[i] != bv[i]) { return false; } } return true; } /// /// Connect two faces. /// /// a. /// The b. public static void Connect(FaceConnector a, FaceConnector b) { a.Face.AdjacentFaces[a.EdgeIndex] = b.Face.Index; b.Face.AdjacentFaces[b.EdgeIndex] = a.Face.Index; } } /// /// This internal class manages the faces of the convex hull. It is a /// separate class from the desired user class. /// internal sealed class ConvexFaceInternal { /// /// Gets or sets the adjacent face data. /// public int[] AdjacentFaces; /// /// The furthest vertex. /// public int FurthestVertex; /// /// Index of the face inside the pool. /// public int Index; /// /// Is it present in the list. /// public bool InList; /// /// Is the normal flipped? /// public bool IsNormalFlipped; /// /// Next node in the list. /// public ConvexFaceInternal Next; /// /// Gets or sets the normal vector. /// public double[] Normal; /// /// Face plane constant element. /// public double Offset; //public int UnprocessedIndex; /// /// Prev node in the list. /// public ConvexFaceInternal Previous; /// /// Used to traverse affected faces and create the Delaunay representation. /// public int Tag; /// /// Gets or sets the vertices. /// public int[] Vertices; /// /// Gets or sets the vertices beyond. /// public IndexBuffer VerticesBeyond; /// /// Initializes a new instance of the class. /// /// The dimension. /// The index. /// The beyond list. public ConvexFaceInternal(int dimension, int index, IndexBuffer beyondList) { Index = index; AdjacentFaces = new int[dimension]; VerticesBeyond = beyondList; Normal = new double[dimension]; Vertices = new int[dimension]; } } }