221 lines
4.6 KiB
C#
221 lines
4.6 KiB
C#
using System;
|
|
using TriangleNet.Geometry;
|
|
|
|
namespace TriangleNet.Tools
|
|
{
|
|
public class VertexSorter
|
|
{
|
|
private const int RANDOM_SEED = 57113;
|
|
|
|
private Random rand;
|
|
|
|
private Vertex[] points;
|
|
|
|
private VertexSorter(Vertex[] points, int seed)
|
|
{
|
|
this.points = points;
|
|
rand = new Random(seed);
|
|
}
|
|
|
|
public static void Sort(Vertex[] array, int seed = 57113)
|
|
{
|
|
new VertexSorter(array, seed).QuickSort(0, array.Length - 1);
|
|
}
|
|
|
|
public static void Alternate(Vertex[] array, int length, int seed = 57113)
|
|
{
|
|
VertexSorter vertexSorter = new VertexSorter(array, seed);
|
|
int num = length >> 1;
|
|
if (length - num >= 2)
|
|
{
|
|
if (num >= 2)
|
|
{
|
|
vertexSorter.AlternateAxes(0, num - 1, 1);
|
|
}
|
|
vertexSorter.AlternateAxes(num, length - 1, 1);
|
|
}
|
|
}
|
|
|
|
private void QuickSort(int left, int right)
|
|
{
|
|
int num = left;
|
|
int num2 = right;
|
|
int num3 = right - left + 1;
|
|
Vertex[] array = points;
|
|
if (num3 < 32)
|
|
{
|
|
for (int i = left + 1; i <= right; i++)
|
|
{
|
|
Vertex vertex = array[i];
|
|
int num4 = i - 1;
|
|
while (num4 >= left && (array[num4].x > vertex.x || (array[num4].x == vertex.x && array[num4].y > vertex.y)))
|
|
{
|
|
array[num4 + 1] = array[num4];
|
|
num4--;
|
|
}
|
|
array[num4 + 1] = vertex;
|
|
}
|
|
return;
|
|
}
|
|
int num5 = rand.Next(left, right);
|
|
double x = array[num5].x;
|
|
double y = array[num5].y;
|
|
left--;
|
|
right++;
|
|
while (left < right)
|
|
{
|
|
do
|
|
{
|
|
left++;
|
|
}
|
|
while (left <= right && (array[left].x < x || (array[left].x == x && array[left].y < y)));
|
|
do
|
|
{
|
|
right--;
|
|
}
|
|
while (left <= right && (array[right].x > x || (array[right].x == x && array[right].y > y)));
|
|
if (left < right)
|
|
{
|
|
Vertex vertex2 = array[left];
|
|
array[left] = array[right];
|
|
array[right] = vertex2;
|
|
}
|
|
}
|
|
if (left > num)
|
|
{
|
|
QuickSort(num, left);
|
|
}
|
|
if (num2 > right + 1)
|
|
{
|
|
QuickSort(right + 1, num2);
|
|
}
|
|
}
|
|
|
|
private void AlternateAxes(int left, int right, int axis)
|
|
{
|
|
int num = right - left + 1;
|
|
int num2 = num >> 1;
|
|
if (num <= 3)
|
|
{
|
|
axis = 0;
|
|
}
|
|
if (axis == 0)
|
|
{
|
|
VertexMedianX(left, right, left + num2);
|
|
}
|
|
else
|
|
{
|
|
VertexMedianY(left, right, left + num2);
|
|
}
|
|
if (num - num2 >= 2)
|
|
{
|
|
if (num2 >= 2)
|
|
{
|
|
AlternateAxes(left, left + num2 - 1, 1 - axis);
|
|
}
|
|
AlternateAxes(left + num2, right, 1 - axis);
|
|
}
|
|
}
|
|
|
|
private void VertexMedianX(int left, int right, int median)
|
|
{
|
|
int num = right - left + 1;
|
|
int left2 = left;
|
|
int right2 = right;
|
|
Vertex[] array = points;
|
|
if (num == 2)
|
|
{
|
|
if (array[left].x > array[right].x || (array[left].x == array[right].x && array[left].y > array[right].y))
|
|
{
|
|
Vertex vertex = array[right];
|
|
array[right] = array[left];
|
|
array[left] = vertex;
|
|
}
|
|
return;
|
|
}
|
|
int num2 = rand.Next(left, right);
|
|
double x = array[num2].x;
|
|
double y = array[num2].y;
|
|
left--;
|
|
right++;
|
|
while (left < right)
|
|
{
|
|
do
|
|
{
|
|
left++;
|
|
}
|
|
while (left <= right && (array[left].x < x || (array[left].x == x && array[left].y < y)));
|
|
do
|
|
{
|
|
right--;
|
|
}
|
|
while (left <= right && (array[right].x > x || (array[right].x == x && array[right].y > y)));
|
|
if (left < right)
|
|
{
|
|
Vertex vertex = array[left];
|
|
array[left] = array[right];
|
|
array[right] = vertex;
|
|
}
|
|
}
|
|
if (left > median)
|
|
{
|
|
VertexMedianX(left2, left - 1, median);
|
|
}
|
|
if (right < median - 1)
|
|
{
|
|
VertexMedianX(right + 1, right2, median);
|
|
}
|
|
}
|
|
|
|
private void VertexMedianY(int left, int right, int median)
|
|
{
|
|
int num = right - left + 1;
|
|
int left2 = left;
|
|
int right2 = right;
|
|
Vertex[] array = points;
|
|
if (num == 2)
|
|
{
|
|
if (array[left].y > array[right].y || (array[left].y == array[right].y && array[left].x > array[right].x))
|
|
{
|
|
Vertex vertex = array[right];
|
|
array[right] = array[left];
|
|
array[left] = vertex;
|
|
}
|
|
return;
|
|
}
|
|
int num2 = rand.Next(left, right);
|
|
double y = array[num2].y;
|
|
double x = array[num2].x;
|
|
left--;
|
|
right++;
|
|
while (left < right)
|
|
{
|
|
do
|
|
{
|
|
left++;
|
|
}
|
|
while (left <= right && (array[left].y < y || (array[left].y == y && array[left].x < x)));
|
|
do
|
|
{
|
|
right--;
|
|
}
|
|
while (left <= right && (array[right].y > y || (array[right].y == y && array[right].x > x)));
|
|
if (left < right)
|
|
{
|
|
Vertex vertex = array[left];
|
|
array[left] = array[right];
|
|
array[right] = vertex;
|
|
}
|
|
}
|
|
if (left > median)
|
|
{
|
|
VertexMedianY(left2, left - 1, median);
|
|
}
|
|
if (right < median - 1)
|
|
{
|
|
VertexMedianY(right + 1, right2, median);
|
|
}
|
|
}
|
|
}
|
|
}
|