mirror of
https://gitgud.io/AbstractConcept/rimworld-animation-studio.git
synced 2024-08-15 00:43:27 +00:00
Initial commit
This commit is contained in:
commit
3c7cc0c973
8391 changed files with 704313 additions and 0 deletions
|
@ -0,0 +1,286 @@
|
|||
// -----------------------------------------------------------------------
|
||||
// <copyright file="AdjacencyMatrix.cs" company="">
|
||||
// Original Matlab code by John Burkardt, Florida State University
|
||||
// Triangle.NET code by Christian Woltering, http://triangle.codeplex.com/
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
namespace UnityEngine.U2D.Animation.TriangleNet
|
||||
.Tools
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// The adjacency matrix of the mesh.
|
||||
/// </summary>
|
||||
internal class AdjacencyMatrix
|
||||
{
|
||||
// Number of adjacency entries.
|
||||
int nnz;
|
||||
|
||||
// Pointers into the actual adjacency structure adj. Information about row k is
|
||||
// stored in entries pcol(k) through pcol(k+1)-1 of adj. Size: N + 1
|
||||
int[] pcol;
|
||||
|
||||
// The adjacency structure. For each row, it contains the column indices
|
||||
// of the nonzero entries. Size: nnz
|
||||
int[] irow;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of columns (nodes of the mesh).
|
||||
/// </summary>
|
||||
public readonly int N;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the column pointers.
|
||||
/// </summary>
|
||||
public int[] ColumnPointers
|
||||
{
|
||||
get { return pcol; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the row indices.
|
||||
/// </summary>
|
||||
public int[] RowIndices
|
||||
{
|
||||
get { return irow; }
|
||||
}
|
||||
|
||||
public AdjacencyMatrix(Mesh mesh)
|
||||
{
|
||||
this.N = mesh.vertices.Count;
|
||||
|
||||
// Set up the adj_row adjacency pointer array.
|
||||
this.pcol = AdjacencyCount(mesh);
|
||||
this.nnz = pcol[N];
|
||||
|
||||
// Set up the adj adjacency array.
|
||||
this.irow = AdjacencySet(mesh, this.pcol);
|
||||
|
||||
SortIndices();
|
||||
}
|
||||
|
||||
public AdjacencyMatrix(int[] pcol, int[] irow)
|
||||
{
|
||||
this.N = pcol.Length - 1;
|
||||
|
||||
this.nnz = pcol[N];
|
||||
|
||||
this.pcol = pcol;
|
||||
this.irow = irow;
|
||||
|
||||
if (pcol[0] != 0)
|
||||
{
|
||||
throw new ArgumentException("Expected 0-based indexing.", "pcol");
|
||||
}
|
||||
|
||||
if (irow.Length < nnz)
|
||||
{
|
||||
throw new ArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the bandwidth of an adjacency matrix.
|
||||
/// </summary>
|
||||
/// <returns>Bandwidth of the adjacency matrix.</returns>
|
||||
public int Bandwidth()
|
||||
{
|
||||
int band_hi;
|
||||
int band_lo;
|
||||
int col;
|
||||
int i, j;
|
||||
|
||||
band_lo = 0;
|
||||
band_hi = 0;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
{
|
||||
for (j = pcol[i]; j < pcol[i + 1]; j++)
|
||||
{
|
||||
col = irow[j];
|
||||
band_lo = Math.Max(band_lo, i - col);
|
||||
band_hi = Math.Max(band_hi, col - i);
|
||||
}
|
||||
}
|
||||
|
||||
return band_lo + 1 + band_hi;
|
||||
}
|
||||
|
||||
#region Adjacency matrix
|
||||
|
||||
/// <summary>
|
||||
/// Counts adjacencies in a triangulation.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This routine is called to count the adjacencies, so that the
|
||||
/// appropriate amount of memory can be set aside for storage when
|
||||
/// the adjacency structure is created.
|
||||
///
|
||||
/// The triangulation is assumed to involve 3-node triangles.
|
||||
///
|
||||
/// Two nodes are "adjacent" if they are both nodes in some triangle.
|
||||
/// Also, a node is considered to be adjacent to itself.
|
||||
/// </remarks>
|
||||
int[] AdjacencyCount(Mesh mesh)
|
||||
{
|
||||
int n = N;
|
||||
int n1, n2, n3;
|
||||
int tid, nid;
|
||||
|
||||
int[] pcol = new int[n + 1];
|
||||
|
||||
// Set every node to be adjacent to itself.
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
pcol[i] = 1;
|
||||
}
|
||||
|
||||
// Examine each triangle.
|
||||
foreach (var tri in mesh.triangles)
|
||||
{
|
||||
tid = tri.id;
|
||||
|
||||
n1 = tri.vertices[0].id;
|
||||
n2 = tri.vertices[1].id;
|
||||
n3 = tri.vertices[2].id;
|
||||
|
||||
// Add edge (1,2) if this is the first occurrence, that is, if
|
||||
// the edge (1,2) is on a boundary (nid <= 0) or if this triangle
|
||||
// is the first of the pair in which the edge occurs (tid < nid).
|
||||
nid = tri.neighbors[2].tri.id;
|
||||
|
||||
if (nid < 0 || tid < nid)
|
||||
{
|
||||
pcol[n1] += 1;
|
||||
pcol[n2] += 1;
|
||||
}
|
||||
|
||||
// Add edge (2,3).
|
||||
nid = tri.neighbors[0].tri.id;
|
||||
|
||||
if (nid < 0 || tid < nid)
|
||||
{
|
||||
pcol[n2] += 1;
|
||||
pcol[n3] += 1;
|
||||
}
|
||||
|
||||
// Add edge (3,1).
|
||||
nid = tri.neighbors[1].tri.id;
|
||||
|
||||
if (nid < 0 || tid < nid)
|
||||
{
|
||||
pcol[n3] += 1;
|
||||
pcol[n1] += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// We used PCOL to count the number of entries in each column.
|
||||
// Convert it to pointers into the ADJ array.
|
||||
for (int i = n; i > 0; i--)
|
||||
{
|
||||
pcol[i] = pcol[i - 1];
|
||||
}
|
||||
|
||||
pcol[0] = 0;
|
||||
for (int i = 1; i <= n; i++)
|
||||
{
|
||||
pcol[i] = pcol[i - 1] + pcol[i];
|
||||
}
|
||||
|
||||
return pcol;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets adjacencies in a triangulation.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This routine can be used to create the compressed column storage
|
||||
/// for a linear triangle finite element discretization of Poisson's
|
||||
/// equation in two dimensions.
|
||||
/// </remarks>
|
||||
int[] AdjacencySet(Mesh mesh, int[] pcol)
|
||||
{
|
||||
int n = this.N;
|
||||
|
||||
int[] col = new int[n];
|
||||
|
||||
// Copy of the adjacency rows input.
|
||||
Array.Copy(pcol, col, n);
|
||||
|
||||
int i, nnz = pcol[n];
|
||||
|
||||
// Output list, stores the actual adjacency information.
|
||||
int[] list = new int[nnz];
|
||||
|
||||
// Set every node to be adjacent to itself.
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
list[col[i]] = i;
|
||||
col[i] += 1;
|
||||
}
|
||||
|
||||
int n1, n2, n3; // Vertex numbers.
|
||||
int tid, nid; // Triangle and neighbor id.
|
||||
|
||||
// Examine each triangle.
|
||||
foreach (var tri in mesh.triangles)
|
||||
{
|
||||
tid = tri.id;
|
||||
|
||||
n1 = tri.vertices[0].id;
|
||||
n2 = tri.vertices[1].id;
|
||||
n3 = tri.vertices[2].id;
|
||||
|
||||
// Add edge (1,2) if this is the first occurrence, that is, if
|
||||
// the edge (1,2) is on a boundary (nid <= 0) or if this triangle
|
||||
// is the first of the pair in which the edge occurs (tid < nid).
|
||||
nid = tri.neighbors[2].tri.id;
|
||||
|
||||
if (nid < 0 || tid < nid)
|
||||
{
|
||||
list[col[n1]++] = n2;
|
||||
list[col[n2]++] = n1;
|
||||
}
|
||||
|
||||
// Add edge (2,3).
|
||||
nid = tri.neighbors[0].tri.id;
|
||||
|
||||
if (nid < 0 || tid < nid)
|
||||
{
|
||||
list[col[n2]++] = n3;
|
||||
list[col[n3]++] = n2;
|
||||
}
|
||||
|
||||
// Add edge (3,1).
|
||||
nid = tri.neighbors[1].tri.id;
|
||||
|
||||
if (nid < 0 || tid < nid)
|
||||
{
|
||||
list[col[n1]++] = n3;
|
||||
list[col[n3]++] = n1;
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public void SortIndices()
|
||||
{
|
||||
int k1, k2, n = N;
|
||||
|
||||
int[] list = this.irow;
|
||||
|
||||
// Ascending sort the entries for each column.
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
k1 = pcol[i];
|
||||
k2 = pcol[i + 1];
|
||||
Array.Sort(list, k1, k2 - k1);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue