I just made a marching cubes algorythm and after 2 days i saw some holes in the mesh.
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class MarchinCubes : MonoBehaviour
{
public int size = 1;
public float surfaceValue = .5f;
public int xOffset = 0;
public int yOffset = 0;
public int zOffset = 0;
public float zoom = 1;
public bool interpolation;
public bool shading;
public bool autoUpdate;
public bool sphereValues;
void Start()
{
xOffset = (int)transform.position.x;
yOffset = (int)transform.position.y;
zOffset = (int)transform.position.z;
Starter();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.U) || autoUpdate)
{
xOffset = (int)transform.position.x;
yOffset = (int)transform.position.y;
zOffset = (int)transform.position.z;
Starter();
Vector3 position = transform.position;
Vector3 newPosition = new Vector3(Mathf.Floor(position.x), Mathf.Floor(position.y), Mathf.Floor(position.z));
transform.position = newPosition;
}
}
void Starter()
{
int pointSize = size + 1;
float[][][] values = sphereValues ? sphere(pointSize) : Perlin(pointSize);
Mesh mesh = CreateMesh(values, pointSize - 1);
mesh.RecalculateNormals();
GetComponent<MeshFilter>().mesh = mesh;
}
float[][][] sphere(int size)
{
float[][][] values = initializeFloatArray(size);
for (int x = 0; x < size; x++)
{
for (int y = 0; y < size; y++)
{
for (int z = 0; z < size; z++)
{
values[x][y][z] = 10 - distance(x, y, z, size / 2, size / 2, size / 2);
}
}
}
return values;
}
float distance(float x, float y, float z, float xCenter, float yCenter, float zCenter)
{
return Mathf.Sqrt(Mathf.Pow(x - xCenter, 2) + Mathf.Pow(y - yCenter, 2) + Mathf.Pow(z - zCenter, 2));
}
float[][][] Perlin(int size)
{
float[][][] values = initializeFloatArray(size);
for (int x = 0; x < size; x++)
{
for (int y = 0; y < size; y++)
{
for (int z = 0; z < size; z++)
{
if (x == 0 || x == size - 1 || y == 0 || y == size - 1 ||z == 0 || z == size - 1)
{
values[x][y][z] = 0;
}
else
{
values[x][y][z] = (GetPerlin(x, y, z, 40f) + GetPerlin(x, y, z, 20f)) / 2;
}
}
}
}
return values;
}
float GetPerlin(int xInt, int yInt, int zInt, float divider)
{
float z = (zInt + zOffset) / divider;
float y = (yInt + yOffset) / divider;
float x = (xInt + xOffset) / divider;
float zy = Mathf.PerlinNoise(x, y);
float zx = Mathf.PerlinNoise(x, z);
float yx = Mathf.PerlinNoise(y, z);
float yz = Mathf.PerlinNoise(y, x);
float xz = Mathf.PerlinNoise(z, x);
float xy = Mathf.PerlinNoise(z, y);
return (xy + xz + yz + yx + zx + zy) / 6;
}
float[][][] initializeFloatArray(int size)
{
float[][][] values = new float[size][][];
for (int x = 0; x < size; x++)
{
values[x] = new float[size][];
for (int i = 0; i < size; i++)
{
values[x][i] = new float[size];
}
}
return values;
}
Mesh CreateMesh(float[][][] values, int size)
{
Vector3[] vertices = initializeVector3Array(size * 2 + 1, size * 2 + 1, size * 2 + 1);
int[] triangles = new int[size * size * size * 3 * 2];
Mesh mesh = new Mesh();
int triangleCount = 0;
for (int x = 0; x < size; x++)
{
for (int y = 0; y < size; y++)
{
for (int z = 0; z < size; z++)
{
int[] triangleTable = table[getTriangleIndex(
new[] {
values[x][y][z],
values[x + 1][y][z],
values[x + 1][y][z + 1],
values[x][y][z + 1],
values[x][y + 1][z],
values[x + 1][y + 1][z],
values[x + 1][y + 1][z + 1],
values[x][y + 1][z + 1]
},
surfaceValue)];
int[] trianglesToAdd = new int[triangleTable.Length];
for (int i = 0; i < triangleTable.Length; i += 3)
{
trianglesToAdd[i] = getVertexIndex(x, y, z, triangleTable[i], size * 2 + 2);
trianglesToAdd[i + 1] = getVertexIndex(x, y, z, triangleTable[i + 1], size * 2 + 2);
trianglesToAdd[i + 2] = getVertexIndex(x, y, z, triangleTable[i + 2], size * 2 + 2);
}
for (int i = 0; i < trianglesToAdd.Length; i++)
{
triangles[triangleCount] = trianglesToAdd[i];
triangleCount++;
}
}
}
}
if (interpolation)
{
vertices = addIndterpolation(vertices, size * 2 + 2, values, surfaceValue);
}
vertices = ScaleVertices(vertices);
if (shading == false)
{
RemakeMeshToDiscrete(vertices, triangles, out vertices, out triangles);
}
mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
mesh.vertices = vertices;
mesh.triangles = triangles;
return mesh;
}
Vector3[] ScaleVertices(Vector3[] vertices)
{
for (int i = 0; i < vertices.Length; i++)
{
vertices[i].x = vertices[i].x / transform.localScale.x;
vertices[i].y = vertices[i].y / transform.localScale.y;
vertices[i].z = vertices[i].z / transform.localScale.z;
}
return vertices;
}
void RemakeMeshToDiscrete(Vector3[] vert, int[] trig, out Vector3[] outVertices, out int[] outTriangles)
{
Vector3[] vertDiscrete = new Vector3[trig.Length];
int[] trigDiscrete = new int[trig.Length];
for (int i = 0; i < trig.Length; i++)
{
vertDiscrete[i] = vert[trig[i]];
trigDiscrete[i] = i;
}
outVertices = vertDiscrete;
outTriangles = trigDiscrete;
}
Vector3[] addIndterpolation(Vector3[] array, int sizeVertices, float[][][] values, float surfaceValue)
{
int sizeValues = values.Length;
for (int x = 0; x < sizeValues - 1; x++)
{
for (int y = 0; y < sizeValues - 1; y++)
{
for (int z = 0; z < sizeValues - 1; z++)
{
int arrayCords = z * 2 + y * sizeVertices * 2 + x * sizeVertices * sizeVertices * 2;
float value = values[x][y][z];
float valueZ = values[x + 1][y][z];
float valueY = values[x][y + 1][z];
float valueX = values[x][y][z + 1];
float interpolationValueX = Mathf.Abs(surfaceValue - value) / (Mathf.Abs(surfaceValue - value) + Mathf.Abs(surfaceValue - valueX));
float interpolationValueY = Mathf.Abs(surfaceValue - value) / (Mathf.Abs(surfaceValue - value) + Mathf.Abs(surfaceValue - valueY));
float interpolationValueZ = Mathf.Abs(surfaceValue - value) / (Mathf.Abs(surfaceValue - value) + Mathf.Abs(surfaceValue - valueZ));
array[arrayCords + 1] += new Vector3(0, 0, interpolationValueX - .5f);
array[arrayCords + sizeVertices] += new Vector3(0, interpolationValueY - .5f, 0);
array[arrayCords + sizeVertices * sizeVertices] += new Vector3(interpolationValueZ - .5f, 0, 0);
}
}
}
return array;
}
int getVertexIndex(int z, int y, int x, int cubeValue, int size)
{
int[][] vertecieValues = new[] {
new []{1, 0, 0 },
new []{2, 0, 1 },
new []{1, 0, 2 },
new []{0, 0, 1 },
new []{1, 2, 0 },
new []{2, 2, 1 },
new []{1, 2, 2 },
new []{0, 2, 1 },
new []{0, 1, 0 },
new []{2, 1, 0 },
new []{2, 1, 2 },
new []{0, 1, 2 }
};
int xReturn = z * 2 * size * size;
int yReturn = y * 2 * size;
int zReturn = x * 2;
return xReturn + vertecieValues[cubeValue][0] * size * size + yReturn + vertecieValues[cubeValue][1] * size + zReturn + vertecieValues[cubeValue][2];
}
int getTriangleIndex(float[] values, float surfaceValue)
{
int index = 0;
for (int i = 0; i < 8; i++)
{
if (values[i] > surfaceValue)
{
index |= 1 << i;
}
}
return index;
}
Vector3[] initializeVector3Array(int Xsize, int Ysize, int Zsize)
{
Vector3[] array = new Vector3[(Xsize + 1) * (Ysize + 1) * (Zsize + 1)];
int count = 0;
for (int x = 0; x < Xsize + 1; x++)
{
for (int y = 0; y < Ysize + 1; y++)
{
for (int z = 0; z < Zsize + 1; z++)
{
array[count] = new Vector3(x / 2f, y / 2f, z / 2f);
count++;
}
}
}
return array;
}
int[][] table = new int[][] {
new int[] { },
new int[] { 8, 3, 0},
new int[] { 9, 0, 1},
new int[] { 8, 3, 1, 8, 1, 9},
new int[] {10, 1, 2},
new int[] { 8, 3, 0, 1, 2,10},
new int[] { 9, 0, 2, 9, 2,10},
new int[] { 3, 2, 8, 2,10, 8, 8,10, 9},
new int[] {11, 2, 3},
new int[] {11, 2, 0,11, 0, 8},
new int[] {11, 2, 3, 0, 1, 9},
new int[] { 2, 1,11, 1, 9,11,11, 9, 8},
new int[] {10, 1, 3,10, 3,11},
new int[] { 1, 0,10, 0, 8,10,10, 8,11},
new int[] { 0, 3, 9, 3,11, 9, 9,11,10},
new int[] { 8,10, 9, 8,11,10},
new int[] { 8, 4, 7},
new int[] { 3, 0, 4, 3, 4, 7},
new int[] { 1, 9, 0, 8, 4, 7},
new int[] { 9, 4, 1, 4, 7, 1, 1, 7, 3},
new int[] {10, 1, 2, 8, 4, 7},
new int[] { 2,10, 1, 0, 4, 7, 0, 7, 3},
new int[] { 4, 7, 8, 0, 2,10, 0,10, 9},
new int[] { 2, 7, 3, 2, 9, 7, 7, 9, 4, 2,10, 9},
new int[] { 2, 3,11, 7, 8, 4},
new int[] { 7,11, 4,11, 2, 4, 4, 2, 0},
new int[] { 3,11, 2, 4, 7, 8, 9, 0, 1},
new int[] { 2, 7,11, 2, 1, 7, 1, 4, 7, 1, 9, 4},
new int[] { 8, 4, 7,11,10, 1,11, 1, 3},
new int[] {11, 4, 7, 1, 4,11, 1,11,10, 1, 0, 4},
new int[] { 3, 8, 0, 7,11, 4,11, 9, 4,11,10, 9},
new int[] { 7,11, 4, 4,11, 9,11,10, 9},
new int[] { 9, 5, 4},
new int[] { 3, 0, 8, 4, 9, 5},
new int[] { 5, 4, 0, 5, 0, 1},
new int[] { 4, 8, 5, 8, 3, 5, 5, 3, 1},
new int[] { 2,10, 1, 9, 5, 4},
new int[] { 0, 8, 3, 5, 4, 9,10, 1, 2},
new int[] {10, 5, 2, 5, 4, 2, 2, 4, 0},
new int[] { 3, 4, 8, 3, 2, 4, 2, 5, 4, 2,10, 5},
new int[] {11, 2, 3, 9, 5, 4},
new int[] { 9, 5, 4, 8,11, 2, 8, 2, 0},
new int[] { 3,11, 2, 1, 5, 4, 1, 4, 0},
new int[] { 8, 5, 4, 2, 5, 8, 2, 8,11, 2, 1, 5},
new int[] { 5, 4, 9, 1, 3,11, 1,11,10},
new int[] { 0, 9, 1, 4, 8, 5, 8,10, 5, 8,11,10},
new int[] { 3, 4, 0, 3,10, 4, 4,10, 5, 3,11,10},
new int[] { 4, 8, 5, 5, 8,10, 8,11,10},
new int[] { 9, 5, 7, 9, 7, 8},
new int[] { 0, 9, 3, 9, 5, 3, 3, 5, 7},
new int[] { 8, 0, 7, 0, 1, 7, 7, 1, 5},
new int[] { 1, 7, 3, 1, 5, 7},
new int[] { 1, 2,10, 5, 7, 8, 5, 8, 9},
new int[] { 9, 1, 0,10, 5, 2, 5, 3, 2, 5, 7, 3},
new int[] { 5, 2,10, 8, 2, 5, 8, 5, 7, 8, 0, 2},
new int[] {10, 5, 2, 2, 5, 3, 5, 7, 3},
new int[] {11, 2, 3, 8, 9, 5, 8, 5, 7},
new int[] { 9, 2, 0, 9, 7, 2, 2, 7,11, 9, 5, 7},
new int[] { 0, 3, 8, 2, 1,11, 1, 7,11, 1, 5, 7},
new int[] { 2, 1,11,11, 1, 7, 1, 5, 7},
new int[] { 3, 9, 1, 3, 8, 9, 7,11,10, 7,10, 5},
new int[] { 9, 1, 0,10, 7,11,10, 5, 7},
new int[] { 3, 8, 0, 7,10, 5, 7,11,10},
new int[] {11, 5, 7,11,10, 5},
new int[] {10, 6, 5},
new int[] { 8, 3, 0,10, 6, 5},
new int[] { 0, 1, 9, 5,10, 6},
new int[] {10, 6, 5, 9, 8, 3, 9, 3, 1},
new int[] { 1, 2, 6, 1, 6, 5},
new int[] { 0, 8, 3, 2, 6, 5, 2, 5, 1},
new int[] { 5, 9, 6, 9, 0, 6, 6, 0, 2},
new int[] { 9, 6, 5, 3, 6, 9, 3, 9, 8, 3, 2, 6},
new int[] { 3,11, 2,10, 6, 5},
new int[] { 6, 5,10, 2, 0, 8, 2, 8,11},
new int[] { 1, 9, 0, 6, 5,10,11, 2, 3},
new int[] { 1,10, 2, 5, 9, 6, 9,11, 6, 9, 8,11},
new int[] {11, 6, 3, 6, 5, 3, 3, 5, 1},
new int[] { 0, 5, 1, 0,11, 5, 5,11, 6, 0, 8,11},
new int[] { 0, 5, 9, 0, 3, 5, 3, 6, 5, 3,11, 6},
new int[] { 5, 9, 6, 6, 9,11, 9, 8,11},
new int[] {10, 6, 5, 4, 7, 8},
new int[] { 5,10, 6, 7, 3, 0, 7, 0, 4},
new int[] { 5,10, 6, 0, 1, 9, 8, 4, 7},
new int[] { 4, 5, 9, 6, 7,10, 7, 1,10, 7, 3, 1},
new int[] { 7, 8, 4, 5, 1, 2, 5, 2, 6},
new int[] { 4, 1, 0, 4, 5, 1, 6, 7, 3, 6, 3, 2},
new int[] { 9, 4, 5, 8, 0, 7, 0, 6, 7, 0, 2, 6},
new int[] { 4, 5, 9, 6, 3, 2, 6, 7, 3},
new int[] { 7, 8, 4, 2, 3,11,10, 6, 5},
new int[] {11, 6, 7,10, 2, 5, 2, 4, 5, 2, 0, 4},
new int[] {11, 6, 7, 8, 0, 3, 1,10, 2, 9, 4, 5},
new int[] { 6, 7,11, 1,10, 2, 9, 4, 5},
new int[] { 6, 7,11, 4, 5, 8, 5, 3, 8, 5, 1, 3},
new int[] { 6, 7,11, 4, 1, 0, 4, 5, 1},
new int[] { 4, 5, 9, 3, 8, 0,11, 6, 7},
new int[] { 9, 4, 5, 7,11, 6},
new int[] {10, 6, 4,10, 4, 9},
new int[] { 8, 3, 0, 9,10, 6, 9, 6, 4},
new int[] { 1,10, 0,10, 6, 0, 0, 6, 4},
new int[] { 8, 6, 4, 8, 1, 6, 6, 1,10, 8, 3, 1},
new int[] { 9, 1, 4, 1, 2, 4, 4, 2, 6},
new int[] { 1, 0, 9, 3, 2, 8, 2, 4, 8, 2, 6, 4},
new int[] { 2, 4, 0, 2, 6, 4},
new int[] { 3, 2, 8, 8, 2, 4, 2, 6, 4},
new int[] { 2, 3,11, 6, 4, 9, 6, 9,10},
new int[] { 0,10, 2, 0, 9,10, 4, 8,11, 4,11, 6},
new int[] {10, 2, 1,11, 6, 3, 6, 0, 3, 6, 4, 0},
new int[] {10, 2, 1,11, 4, 8,11, 6, 4},
new int[] { 1, 4, 9,11, 4, 1,11, 1, 3,11, 6, 4},
new int[] { 0, 9, 1, 4,11, 6, 4, 8,11},
new int[] {11, 6, 3, 3, 6, 0, 6, 4, 0},
new int[] { 8, 6, 4, 8,11, 6},
new int[] { 6, 7,10, 7, 8,10,10, 8, 9},
new int[] { 9, 3, 0, 6, 3, 9, 6, 9,10, 6, 7, 3},
new int[] { 6, 1,10, 6, 7, 1, 7, 0, 1, 7, 8, 0},
new int[] { 6, 7,10,10, 7, 1, 7, 3, 1},
new int[] { 7, 2, 6, 7, 9, 2, 2, 9, 1, 7, 8, 9},
new int[] { 1, 0, 9, 3, 6, 7, 3, 2, 6},
new int[] { 8, 0, 7, 7, 0, 6, 0, 2, 6},
new int[] { 2, 7, 3, 2, 6, 7},
new int[] { 7,11, 6, 3, 8, 2, 8,10, 2, 8, 9,10},
new int[] {11, 6, 7,10, 0, 9,10, 2, 0},
new int[] { 2, 1,10, 7,11, 6, 8, 0, 3},
new int[] { 1,10, 2, 6, 7,11},
new int[] { 7,11, 6, 3, 9, 1, 3, 8, 9},
new int[] { 9, 1, 0,11, 6, 7},
new int[] { 0, 3, 8,11, 6, 7},
new int[] {11, 6, 7},
new int[] {11, 7, 6},
new int[] { 0, 8, 3,11, 7, 6},
new int[] { 9, 0, 1,11, 7, 6},
new int[] { 7, 6,11, 3, 1, 9, 3, 9, 8},
new int[] { 1, 2,10, 6,11, 7},
new int[] { 2,10, 1, 7, 6,11, 8, 3, 0},
new int[] {11, 7, 6,10, 9, 0,10, 0, 2},
new int[] { 7, 6,11, 3, 2, 8, 8, 2,10, 8,10, 9},
new int[] { 2, 3, 7, 2, 7, 6},
new int[] { 8, 7, 0, 7, 6, 0, 0, 6, 2},
new int[] { 1, 9, 0, 3, 7, 6, 3, 6, 2},
new int[] { 7, 6, 2, 7, 2, 9, 2, 1, 9, 7, 9, 8},
new int[] { 6,10, 7,10, 1, 7, 7, 1, 3},
new int[] { 6,10, 1, 6, 1, 7, 7, 1, 0, 7, 0, 8},
new int[] { 9, 0, 3, 6, 9, 3, 6,10, 9, 6, 3, 7},
new int[] { 6,10, 7, 7,10, 8,10, 9, 8},
new int[] { 8, 4, 6, 8, 6,11},
new int[] {11, 3, 6, 3, 0, 6, 6, 0, 4},
new int[] { 0, 1, 9, 4, 6,11, 4,11, 8},
new int[] { 1, 9, 4,11, 1, 4,11, 3, 1,11, 4, 6},
new int[] {10, 1, 2,11, 8, 4,11, 4, 6},
new int[] {10, 1, 2,11, 3, 6, 6, 3, 0, 6, 0, 4},
new int[] { 0, 2,10, 0,10, 9, 4,11, 8, 4, 6,11},
new int[] { 2,11, 3, 6, 9, 4, 6,10, 9},
new int[] { 3, 8, 2, 8, 4, 2, 2, 4, 6},
new int[] { 2, 0, 4, 2, 4, 6},
new int[] { 1, 9, 0, 3, 8, 2, 2, 8, 4, 2, 4, 6},
new int[] { 9, 4, 1, 1, 4, 2, 4, 6, 2},
new int[] { 8, 4, 6, 8, 6, 1, 6,10, 1, 8, 1, 3},
new int[] { 1, 0,10,10, 0, 6, 0, 4, 6},
new int[] { 8, 0, 3, 9, 6,10, 9, 4, 6},
new int[] {10, 4, 6,10, 9, 4},
new int[] { 9, 5, 4, 7, 6,11},
new int[] { 4, 9, 5, 3, 0, 8,11, 7, 6},
new int[] { 6,11, 7, 4, 0, 1, 4, 1, 5},
new int[] { 6,11, 7, 4, 8, 5, 5, 8, 3, 5, 3, 1},
new int[] { 6,11, 7, 1, 2,10, 9, 5, 4},
new int[] {11, 7, 6, 8, 3, 0, 1, 2,10, 9, 5, 4},
new int[] {11, 7, 6,10, 5, 2, 2, 5, 4, 2, 4, 0},
new int[] { 7, 4, 8, 2,11, 3,10, 5, 6},
new int[] { 4, 9, 5, 6, 2, 3, 6, 3, 7},
new int[] { 9, 5, 4, 8, 7, 0, 0, 7, 6, 0, 6, 2},
new int[] { 4, 0, 1, 4, 1, 5, 6, 3, 7, 6, 2, 3},
new int[] { 7, 4, 8, 5, 2, 1, 5, 6, 2},
new int[] { 4, 9, 5, 6,10, 7, 7,10, 1, 7, 1, 3},
new int[] { 5, 6,10, 0, 9, 1, 8, 7, 4},
new int[] { 5, 6,10, 7, 0, 3, 7, 4, 0},
new int[] {10, 5, 6, 4, 8, 7},
new int[] { 5, 6, 9, 6,11, 9, 9,11, 8},
new int[] { 0, 9, 5, 0, 5, 3, 3, 5, 6, 3, 6,11},
new int[] { 0, 1, 5, 0, 5,11, 5, 6,11, 0,11, 8},
new int[] {11, 3, 6, 6, 3, 5, 3, 1, 5},
new int[] { 1, 2,10, 5, 6, 9, 9, 6,11, 9,11, 8},
new int[] { 1, 0, 9, 6,10, 5,11, 3, 2},
new int[] { 6,10, 5, 2, 8, 0, 2,11, 8},
new int[] { 3, 2,11,10, 5, 6},
new int[] { 9, 5, 6, 3, 9, 6, 3, 8, 9, 3, 6, 2},
new int[] { 5, 6, 9, 9, 6, 0, 6, 2, 0},
new int[] { 0, 3, 8, 2, 5, 6, 2, 1, 5},
new int[] { 1, 6, 2, 1, 5, 6},
new int[] {10, 5, 6, 9, 3, 8, 9, 1, 3},
new int[] { 0, 9, 1, 5, 6,10},
new int[] { 8, 0, 3,10, 5, 6},
new int[] {10, 5, 6},
new int[] {11, 7, 5,11, 5,10},
new int[] { 3, 0, 8, 7, 5,10, 7,10,11},
new int[] { 9, 0, 1,10,11, 7,10, 7, 5},
new int[] { 3, 1, 9, 3, 9, 8, 7,10,11, 7, 5,10},
new int[] { 2,11, 1,11, 7, 1, 1, 7, 5},
new int[] { 0, 8, 3, 2,11, 1, 1,11, 7, 1, 7, 5},
new int[] { 9, 0, 2, 9, 2, 7, 2,11, 7, 9, 7, 5},
new int[] {11, 3, 2, 8, 5, 9, 8, 7, 5},
new int[] {10, 2, 5, 2, 3, 5, 5, 3, 7},
new int[] { 5,10, 2, 8, 5, 2, 8, 7, 5, 8, 2, 0},
new int[] { 9, 0, 1,10, 2, 5, 5, 2, 3, 5, 3, 7},
new int[] { 1,10, 2, 5, 8, 7, 5, 9, 8},
new int[] { 1, 3, 7, 1, 7, 5},
new int[] { 8, 7, 0, 0, 7, 1, 7, 5, 1},
new int[] { 0, 3, 9, 9, 3, 5, 3, 7, 5},
new int[] { 9, 7, 5, 9, 8, 7},
new int[] { 4, 5, 8, 5,10, 8, 8,10,11},
new int[] { 3, 0, 4, 3, 4,10, 4, 5,10, 3,10,11},
new int[] { 0, 1, 9, 4, 5, 8, 8, 5,10, 8,10,11},
new int[] { 5, 9, 4, 1,11, 3, 1,10,11},
new int[] { 8, 4, 5, 2, 8, 5, 2,11, 8, 2, 5, 1},
new int[] { 3, 2,11, 1, 4, 5, 1, 0, 4},
new int[] { 9, 4, 5, 8, 2,11, 8, 0, 2},
new int[] {11, 3, 2, 9, 4, 5},
new int[] { 3, 8, 4, 3, 4, 2, 2, 4, 5, 2, 5,10},
new int[] {10, 2, 5, 5, 2, 4, 2, 0, 4},
new int[] { 0, 3, 8, 5, 9, 4,10, 2, 1},
new int[] { 2, 1,10, 9, 4, 5},
new int[] { 4, 5, 8, 8, 5, 3, 5, 1, 3},
new int[] { 5, 0, 4, 5, 1, 0},
new int[] { 3, 8, 0, 4, 5, 9},
new int[] { 9, 4, 5},
new int[] { 7, 4,11, 4, 9,11,11, 9,10},
new int[] { 3, 0, 8, 7, 4,11,11, 4, 9,11, 9,10},
new int[] {11, 7, 4, 1,11, 4, 1,10,11, 1, 4, 0},
new int[] { 8, 7, 4,11, 1,10,11, 3, 1},
new int[] { 2,11, 7, 2, 7, 1, 1, 7, 4, 1, 4, 9},
new int[] { 3, 2,11, 4, 8, 7, 9, 1, 0},
new int[] { 7, 4,11,11, 4, 2, 4, 0, 2},
new int[] { 2,11, 3, 7, 4, 8},
new int[] { 2, 3, 7, 2, 7, 9, 7, 4, 9, 2, 9,10},
new int[] { 4, 8, 7, 0,10, 2, 0, 9,10},
new int[] { 2, 1,10, 0, 7, 4, 0, 3, 7},
new int[] {10, 2, 1, 8, 7, 4},
new int[] { 9, 1, 4, 4, 1, 7, 1, 3, 7},
new int[] { 1, 0, 9, 8, 7, 4},
new int[] { 3, 4, 0, 3, 7, 4},
new int[] { 8, 7, 4},
new int[] { 8, 9,10, 8,10,11},
new int[] { 0, 9, 3, 3, 9,11, 9,10,11},
new int[] { 1,10, 0, 0,10, 8,10,11, 8},
new int[] {10, 3, 1,10,11, 3},
new int[] { 2,11, 1, 1,11, 9,11, 8, 9},
new int[] {11, 3, 2, 0, 9, 1},
new int[] {11, 0, 2,11, 8, 0},
new int[] {11, 3, 2},
new int[] { 3, 8, 2, 2, 8,10, 8, 9,10},
new int[] { 9, 2, 0, 9,10, 2},
new int[] { 8, 0, 3, 1,10, 2},
new int[] {10, 2, 1},
new int[] { 8, 1, 3, 8, 9, 1},
new int[] { 9, 1, 0},
new int[] { 8, 0, 3},
new int[] {}
};
}
I know the code is really messy but the problem probably is in the CreateMesh method or in the triangulation table.
Does someone know why the hole is appearing there?
I have the triangulation table from the internet.
Thanks.
I got it fixed with a new triangulation table. Thanks for your help.
The below code returns all distinct combinations based on the logic that 1,2,3 = 3,2,1 = 2,3,1, so it only returns 1 instance of that set of numbers.
However, I want to change that logic so that it returns ALL instances of all number sets.
What do I need to do to the LINQ query below "GetPowerSet" in order to make that happen?
public void GetPowersets()
{
List<int> ints = new List<int>()
{
1,2,2,3,3
};
var results = GetPowerSet(ints);
List<String> combinations = new List<String>();
foreach (var result in results)
{
StringBuilder sb = new StringBuilder();
foreach (var intValue in result.OrderBy(x => x))
{
sb.Append(intValue + ",");
}
combinations.Add(sb.ToString());
}
string c1 = string.Join("|", combinations.ToArray()).Replace(",|", "|");
//c1 = "|1|2|1,2|2|1,2|2,2|1,2,2|3|1,3|2,3|1,2,3|2,3|1,2,3|2,2,3|1,2,2,3|3|1,3|2,3|1,2,3|2,3|1,2,3|2,2,3|1,2,2,3|3,3|1,3,3|2,3,3|1,2,3,3|2,3,3|1,2,3,3|2,2,3,3|1,2,2,3,3,"
}
public IEnumerable<IEnumerable<int>> GetPowerSet(List<int> list)
{
return from m in Enumerable.Range(0, 1 << list.Count)
select
from i in Enumerable.Range(0, list.Count)
where (m & (1 << i)) != 0
select list[i];
}
This is the end result I am trying to achieve: (no duplicate rows of combinations: duplicate = 3,2,1 and 3,2,1 are the same thing. but 1,2,3 and 3,2,1 are NOT the same thing and both should be in the end result)
1
2
3
1,2
1,3
2,1
2,3
2,2
3,1
3,2
3,3
1,2,3
1,2,2
1,3,2
1,3,3
2,1,3
2,1,2
2,3,1
2,3,2
2,3,3
2,2,1
2,2,3
3,1,2
3,1,3
3,2,1
3,2,2
3,2,3
3,3,1
3,3,2
1,2,3,2
1,2,3,3
1,2,2,3
1,3,2,2
1,3,2,3
1,3,3,2
2,1,3,2
2,1,3,3
2,1,2,3
2,3,1,2
2,3,1,3
2,3,2,1
2,3,2,3
2,3,3,1
2,3,3,2
2,2,1,3
2,2,3,1
2,2,3,3
3,1,2,2
3,1,2,3
3,1,3,2
3,2,1,2
3,2,1,3
3,2,2,1
3,2,2,3
3,2,3,1
3,2,3,2
3,3,1,2
3,3,2,1
3,3,2,2
1,2,3,2,3
1,2,3,3,2
1,2,2,3,3
1,3,2,2,3
1,3,2,3,2
1,3,3,2,2
2,1,3,2,3
2,1,3,3,2
2,1,2,3,3
2,3,1,2,3
2,3,1,3,2
2,3,2,1,3
2,3,2,3,1
2,3,3,1,2
2,3,3,2,1
2,2,1,3,3
2,2,3,1,3
2,2,3,3,1
3,1,2,2,3
3,1,2,3,2
3,1,3,2,2
3,2,1,2,3
3,2,1,3,2
3,2,2,1,3
3,2,2,3,1
3,2,3,1,2
3,2,3,2,1
3,3,1,2,2
3,3,2,1,2
3,3,2,2,1
The "foreach" way of doing this, which tends to cause a "Out Of Memory Exception" once the number set gets too large (I anticipate LINQ shouldn't have this problem) is below. This works as I want it to, returning the result set I want. But it is slow and has performance issues. I'm also open to suggestions on how to make it better.
public List<List<int>> GetAllCombinationsOfAllSizes(List<int> ints)
{
List<List<int>> returnResult = new List<List<int>>();
var distinctInts = ints.Distinct().ToList();
for (int j = 0; j < distinctInts.Count(); j++)
{
var number = distinctInts[j];
var newList = new List<int>();
newList.Add(number);
returnResult.Add(newList);
var listMinusOneObject = ints.Select(x => x).ToList();
listMinusOneObject.Remove(listMinusOneObject.Where(x => x == number).First());
if (listMinusOneObject.Count() > 0)
{
_GetAllCombinationsOfAllSizes(listMinusOneObject, newList, ref returnResult);
}
}
return returnResult;
}
public void _GetAllCombinationsOfAllSizes(List<int> ints, List<int> growingList, ref List<List<int>> returnResult)
{
var distinctInts = ints.Distinct().ToList();
for (int j = 0; j < distinctInts.Count(); j++)
{
var number = distinctInts[j];
var newList = growingList.ToList();
newList.Add(number);
returnResult.Add(newList);
var listMinusOneObject = ints.Select(x => x).ToList();
listMinusOneObject.Remove(listMinusOneObject.Where(x => x == number).First());
if (listMinusOneObject.Count() > 0)
{
_GetAllCombinationsOfAllSizes(listMinusOneObject, newList, ref returnResult);
}
}
}
The ANSWER I am looking for is: how to achieve this result set I want , but using LINQ and C# to do it, in a way that is faster and more efficient than the current "foreach" way I have posted?
NEW UPDATE (removed old code, performance is better than OP's code, yielded output)
static IEnumerable<int[]> EnumeratePermutations2(int[] ints)
{
Dictionary<int, int> intCounts = ints.GroupBy(n => n)
.ToDictionary(g => g.Key, g => g.Count());
int[] distincts = intCounts.Keys.ToArray();
foreach (int[] permutation in EnumeratePermutations2(new int[0], intCounts, distincts))
yield return permutation;
}
static IEnumerable<int[]> EnumeratePermutations2(int[] prefix, Dictionary<int, int> intCounts, int[] distincts)
{
foreach (int n in distincts)
{
int[] newPrefix = new int[prefix.Length + 1];
Array.Copy(prefix, newPrefix, prefix.Length);
newPrefix[prefix.Length] = n;
yield return newPrefix;
intCounts[n]--;
int[] newDistincts = intCounts[n] > 0
? distincts
: distincts.Where(x => x != n).ToArray();
foreach (int[] permutation in EnumeratePermutations2(newPrefix, intCounts, newDistincts))
yield return permutation;
intCounts[n]++;
}
}
I didn't touch your GetPowerSet, but instead created a SetComparer to filter the repetitions.
public class SetComparer : IEqualityComparer<IEnumerable<int>>
{
public bool Equals(IEnumerable<int> x, IEnumerable<int> y)
{
return Object.ReferenceEquals(x, y) || (x != null && y != null && x.SequenceEqual(y));
}
public int GetHashCode(IEnumerable<int> set)
{
if (set == null) return 0;
//if you only want one of these 1,2,3 vs 3,2,1
//plug .OrderBy(x => x) before the Aggregate
return set.Aggregate(19, (s,i) => s * 31 + i);
}
}
Just chain .Distinct(new SetComparer()) to the results or at the end of your GetPowerSet select statement.
Based on the question.
Your solution does return all result sets including duplicates. Your solutions does not exclude duplicates. Your Example output does exclude some duplicates but you list 89 sets of data.
There should only be 64 with duplicates as I understand how combinations work which is 2 ^ List.Count() = 2 ^ 6 = 64 combinations
Revised Answer
I believe this is close to what you want. I created a short solution but I think it can be re factored and enhanced for speed. The following Link has some good Set Classes which I think should be used: http://www.codeproject.com/Articles/23391/Set-Collections-for-C
The other thing I would use is the TPL Library which will allow you to speed up the processing. Link: http://msdn.microsoft.com/en-us/library/dd460717(v=vs.110).aspx
My Result Set resulted in 190 sets. With the following code it took about 1.5 minutes to run.
Main Program
void Main()
{
var setList = new List<int>() {1,1,2,3,3,3};
var setSize = setList.Count();
var basePowerSet = PowerSet.Generate(setList);
var results = PowerSet.PS;
// Results generated in 1 Minute 23 seconds with no errors.
var sortedSets = new SortedSet<string>();
foreach( var item in results)
{
sortedSets.Add(item.ToString2());
}
foreach( var item in sortedSets)
{
Console.WriteLine(item);
}
}
PowerSet Library
public static class PowerSet
{
// List with no Exact Duplicates but with Permutations
public static List<List<int>> PS = new List<List<int>>();
// This Method Generates the power set with No Exact Duplicates
// and stores the values into the Property PS.
public static List<List<int>> Generate(List<int> setList)
{
// Generate Base Data to use for final results
var setSize = setList.Count();
var basePowerSet = from m in Enumerable.Range(0, 1 << setSize)
select
from i in Enumerable.Range(0, setSize)
where (m & (1 << i)) != 0
select setList[i];
// Temporary Result Set with Duplicates
var results = new List<List<int>>();
// Step thru each set and generate list of Permutations for each
// Power Set generated above.
foreach( var item in basePowerSet )
{
var size = item.Count();
var positions = from m in Enumerable.Range(0, size)
select m;
var lItem = item.ToList();
// If the set has 2 or more elements in the set then generate Permutations
switch(size)
{
case 0:
case 1:
break;
default:
// Permutations generated from Linq Extension defined
// in Method Permute()
var posList = positions.Permute().ToList();
// remove first item which is a duplicate.
posList.RemoveAt(0);
// Generate new Lists based on all possiable
// combinations of the data in the set.
var x = new List<List<int>>();
foreach(var p in posList)
{
var y = new List<int>();
foreach(var v in p)
{
//v.Dump("xxxx");
y.Add(lItem[v]);
}
x.Add(y);
// Add New Permutation but
// Do not add a duplicate set.
AddNonDuplicate(x);
}
break;
}
// Add to Temp Results;
results.Add(item.ToList());
// Remove Duplicates
AddNonDuplicate(results);
}
return results;
}
// Custom Method used to compare values in a set to the
// Final Result Set named PS.
public static void AddNonDuplicate(List<List<int>> list )
{
//list.Dump();
if(list.Count() == 0)
return;
foreach(var item in list)
{
bool found = false;
var mySize = PS.Count();
if(mySize <= 0)
PS.Add(item);
else
foreach(var psItem in PS)
{
if( item.ToString2() == psItem.ToString2() )
found = true;
}
if(!found)
PS.Add(item);
}
}
}
Extension Library
// My Extension Methods
public static class MyExt
{
public static IEnumerable<IEnumerable<T>> Permute<T>(this IEnumerable<T> list)
{
if (list.Count() == 1)
return new List<IEnumerable<T>> { list };
return list
.Select((a, i1) =>
Permute(list.Where((b, i2) => i2 != i1))
.Select(b => (new List<T> { a }).Union(b)))
.SelectMany(c => c);
}
public static string ToString2<T>(this List<T> list)
{
StringBuilder results = new StringBuilder("{ ");
var size = list.Count();
var pos = 1;
foreach( var i in list )
{
results.Append(i.ToString());
if(pos++!=size)
results.Append(", ");
}
results.Append(" }");
return results.ToString().Trim(',');
}
}
Results
{ }
{ 1 }
{ 1, 1 }
{ 1, 1, 2 }
{ 1, 1, 2, 3 }
{ 1, 1, 2, 3, 3 }
{ 1, 1, 2, 3, 3, 3 }
{ 1, 1, 3 }
{ 1, 1, 3, 2 }
{ 1, 1, 3, 2, 3 }
{ 1, 1, 3, 2, 3, 3 }
{ 1, 1, 3, 3 }
{ 1, 1, 3, 3, 2 }
{ 1, 1, 3, 3, 2, 3 }
{ 1, 1, 3, 3, 3 }
{ 1, 1, 3, 3, 3, 2 }
{ 1, 2 }
{ 1, 2, 1 }
{ 1, 2, 1, 3 }
{ 1, 2, 1, 3, 3 }
{ 1, 2, 1, 3, 3, 3 }
{ 1, 2, 3 }
{ 1, 2, 3, 1 }
{ 1, 2, 3, 1, 3 }
{ 1, 2, 3, 1, 3, 3 }
{ 1, 2, 3, 3 }
{ 1, 2, 3, 3, 1 }
{ 1, 2, 3, 3, 1, 3 }
{ 1, 2, 3, 3, 3 }
{ 1, 2, 3, 3, 3, 1 }
{ 1, 3 }
{ 1, 3, 1 }
{ 1, 3, 1, 2 }
{ 1, 3, 1, 2, 3 }
{ 1, 3, 1, 2, 3, 3 }
{ 1, 3, 1, 3 }
{ 1, 3, 1, 3, 2 }
{ 1, 3, 1, 3, 2, 3 }
{ 1, 3, 1, 3, 3 }
{ 1, 3, 1, 3, 3, 2 }
{ 1, 3, 2 }
{ 1, 3, 2, 1 }
{ 1, 3, 2, 1, 3 }
{ 1, 3, 2, 1, 3, 3 }
{ 1, 3, 2, 3 }
{ 1, 3, 2, 3, 1 }
{ 1, 3, 2, 3, 1, 3 }
{ 1, 3, 2, 3, 3 }
{ 1, 3, 2, 3, 3, 1 }
{ 1, 3, 3 }
{ 1, 3, 3, 1 }
{ 1, 3, 3, 1, 2 }
{ 1, 3, 3, 1, 2, 3 }
{ 1, 3, 3, 1, 3 }
{ 1, 3, 3, 1, 3, 2 }
{ 1, 3, 3, 2 }
{ 1, 3, 3, 2, 1 }
{ 1, 3, 3, 2, 1, 3 }
{ 1, 3, 3, 2, 3 }
{ 1, 3, 3, 2, 3, 1 }
{ 1, 3, 3, 3 }
{ 1, 3, 3, 3, 1 }
{ 1, 3, 3, 3, 1, 2 }
{ 1, 3, 3, 3, 2 }
{ 1, 3, 3, 3, 2, 1 }
{ 2 }
{ 2, 1 }
{ 2, 1, 1 }
{ 2, 1, 1, 3 }
{ 2, 1, 1, 3, 3 }
{ 2, 1, 1, 3, 3, 3 }
{ 2, 1, 3 }
{ 2, 1, 3, 1 }
{ 2, 1, 3, 1, 3 }
{ 2, 1, 3, 1, 3, 3 }
{ 2, 1, 3, 3 }
{ 2, 1, 3, 3, 1 }
{ 2, 1, 3, 3, 1, 3 }
{ 2, 1, 3, 3, 3 }
{ 2, 1, 3, 3, 3, 1 }
{ 2, 3 }
{ 2, 3, 1 }
{ 2, 3, 1, 1 }
{ 2, 3, 1, 1, 3 }
{ 2, 3, 1, 1, 3, 3 }
{ 2, 3, 1, 3 }
{ 2, 3, 1, 3, 1 }
{ 2, 3, 1, 3, 1, 3 }
{ 2, 3, 1, 3, 3 }
{ 2, 3, 1, 3, 3, 1 }
{ 2, 3, 3 }
{ 2, 3, 3, 1 }
{ 2, 3, 3, 1, 1 }
{ 2, 3, 3, 1, 1, 3 }
{ 2, 3, 3, 1, 3 }
{ 2, 3, 3, 1, 3, 1 }
{ 2, 3, 3, 3 }
{ 2, 3, 3, 3, 1 }
{ 2, 3, 3, 3, 1, 1 }
{ 3 }
{ 3, 1 }
{ 3, 1, 1 }
{ 3, 1, 1, 2 }
{ 3, 1, 1, 2, 3 }
{ 3, 1, 1, 2, 3, 3 }
{ 3, 1, 1, 3 }
{ 3, 1, 1, 3, 2 }
{ 3, 1, 1, 3, 2, 3 }
{ 3, 1, 1, 3, 3 }
{ 3, 1, 1, 3, 3, 2 }
{ 3, 1, 2 }
{ 3, 1, 2, 1 }
{ 3, 1, 2, 1, 3 }
{ 3, 1, 2, 1, 3, 3 }
{ 3, 1, 2, 3 }
{ 3, 1, 2, 3, 1 }
{ 3, 1, 2, 3, 1, 3 }
{ 3, 1, 2, 3, 3 }
{ 3, 1, 2, 3, 3, 1 }
{ 3, 1, 3 }
{ 3, 1, 3, 1 }
{ 3, 1, 3, 1, 2 }
{ 3, 1, 3, 1, 2, 3 }
{ 3, 1, 3, 1, 3 }
{ 3, 1, 3, 1, 3, 2 }
{ 3, 1, 3, 2 }
{ 3, 1, 3, 2, 1 }
{ 3, 1, 3, 2, 1, 3 }
{ 3, 1, 3, 2, 3 }
{ 3, 1, 3, 2, 3, 1 }
{ 3, 1, 3, 3 }
{ 3, 1, 3, 3, 1 }
{ 3, 1, 3, 3, 1, 2 }
{ 3, 1, 3, 3, 2 }
{ 3, 1, 3, 3, 2, 1 }
{ 3, 2 }
{ 3, 2, 1 }
{ 3, 2, 1, 1 }
{ 3, 2, 1, 1, 3 }
{ 3, 2, 1, 1, 3, 3 }
{ 3, 2, 1, 3 }
{ 3, 2, 1, 3, 1 }
{ 3, 2, 1, 3, 1, 3 }
{ 3, 2, 1, 3, 3 }
{ 3, 2, 1, 3, 3, 1 }
{ 3, 2, 3 }
{ 3, 2, 3, 1 }
{ 3, 2, 3, 1, 1 }
{ 3, 2, 3, 1, 1, 3 }
{ 3, 2, 3, 1, 3 }
{ 3, 2, 3, 1, 3, 1 }
{ 3, 2, 3, 3 }
{ 3, 2, 3, 3, 1 }
{ 3, 2, 3, 3, 1, 1 }
{ 3, 3 }
{ 3, 3, 1 }
{ 3, 3, 1, 1 }
{ 3, 3, 1, 1, 2 }
{ 3, 3, 1, 1, 2, 3 }
{ 3, 3, 1, 1, 3 }
{ 3, 3, 1, 1, 3, 2 }
{ 3, 3, 1, 2 }
{ 3, 3, 1, 2, 1 }
{ 3, 3, 1, 2, 1, 3 }
{ 3, 3, 1, 2, 3 }
{ 3, 3, 1, 2, 3, 1 }
{ 3, 3, 1, 3 }
{ 3, 3, 1, 3, 1 }
{ 3, 3, 1, 3, 1, 2 }
{ 3, 3, 1, 3, 2 }
{ 3, 3, 1, 3, 2, 1 }
{ 3, 3, 2 }
{ 3, 3, 2, 1 }
{ 3, 3, 2, 1, 1 }
{ 3, 3, 2, 1, 1, 3 }
{ 3, 3, 2, 1, 3 }
{ 3, 3, 2, 1, 3, 1 }
{ 3, 3, 2, 3 }
{ 3, 3, 2, 3, 1 }
{ 3, 3, 2, 3, 1, 1 }
{ 3, 3, 3 }
{ 3, 3, 3, 1 }
{ 3, 3, 3, 1, 1 }
{ 3, 3, 3, 1, 1, 2 }
{ 3, 3, 3, 1, 2 }
{ 3, 3, 3, 1, 2, 1 }
{ 3, 3, 3, 2 }
{ 3, 3, 3, 2, 1 }
{ 3, 3, 3, 2, 1, 1 }