/******************************************************************************
*
* 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];
}
}
}