internal override void Compute(List <Node> allNodes) { List <Point> vertices = new List <Point>(); foreach (int i in NodeIndices) { vertices.Add(allNodes[i].Position.ToPoint()); } Mesh = Mesh.ByVerticesAndIndices(vertices, faces); for (int i = 0; i < NodeCount; i++) { Moves[i] = Triple.Zero; } int faceCount = faces.Count / 3; try { float currentVolume = (float)Mesh.Volume; currentVolumeInversed = 1f / currentVolume; } catch { // ignored } for (int i = 0; i < faceCount; i++) { int iA = faces[i * 3 + 0]; int iB = faces[i * 3 + 1]; int iC = faces[i * 3 + 2]; Triple A = allNodes[NodeIndices[iA]].Position; Triple B = allNodes[NodeIndices[iB]].Position; Triple C = allNodes[NodeIndices[iC]].Position; Triple n = (B - A).Cross(C - A); Triple force = VolumePressureConstant * currentVolumeInversed * n * 0.16666666666666f; Moves[iA] += force; Moves[iB] += force; Moves[iC] += force; } Weights.FillArray(Weight); }
public static Dictionary <string, object> AuxeticRotatingTriangles(int xCount = 5, int yCount = 5, double thickness = 0.0) { List <Goal> shapeMatchingGoals = new List <Goal>(); List <Goal> mergeGoals = new List <Goal>(); List <GeometryBinder> meshBinders = new List <GeometryBinder>(); List <GeometryBinder> lineBinders = new List <GeometryBinder>(); List <Point> vertices = new List <Point>(); List <int> indices = new List <int>(); double offset = 0.001; double cos30 = Math.Cos(Math.PI / 6.0); for (int j = 0; j < yCount; j++) { for (int i = 0; i < xCount; i++) { double xOffset = 2 * i + 1; double yOffset = 2 * j * cos30 + cos30; Triple M = new Triple(xOffset, yOffset, 0.0); List <Triple> v = new List <Triple>(); for (int k = 0; k < 6; k++) { v.Add(new Triple(xOffset + Math.Cos(k * Math.PI / 3.0), yOffset + Math.Sin(k * Math.PI / 3.0), 0.0)); } for (int k = 0; k < 5; k++) { shapeMatchingGoals.Add(ProcessTriangle(M, v[k], v[k + 1], k % 2 == 0, offset, thickness, vertices, indices)); } shapeMatchingGoals.Add(ProcessTriangle(M, v[5], v[0], false, offset, thickness, vertices, indices)); M = new Triple(xOffset + 1, yOffset, 0.0); if (i < xCount - 1) { shapeMatchingGoals.Add(ProcessTriangle( M, new Triple(xOffset + 1.5, yOffset + cos30, 0.0), new Triple(xOffset + 0.5, yOffset + cos30, 0.0), false, offset, thickness, vertices, indices)); shapeMatchingGoals.Add(ProcessTriangle( M, new Triple(xOffset + 0.5, yOffset - cos30, 0.0), new Triple(xOffset + 1.5, yOffset - cos30, 0.0), true, offset, thickness, vertices, indices)); } } } meshBinders.Add(new MeshBinder(Mesh.ByVerticesAndIndices(vertices, indices), new Color(.3f, .6f, .8f, 1f))); //======================================================================================= // Line Binders //======================================================================================= for (int j = 0; j < yCount; j++) { for (int i = 0; i < xCount * 2; i++) { double xOffset = i; double yOffset = 2 * j * cos30 + cos30; Triple M = new Triple(xOffset, yOffset, 0.0); List <Triple> v = new List <Triple>(); for (int k = 1; k < 6; k += 2) { v.Add(new Triple(xOffset + offset * Math.Cos(k * Math.PI / 3.0), yOffset + offset * Math.Sin(k * Math.PI / 3.0), 0.0)); } lineBinders.Add(new LineBinder(v[0], v[1])); lineBinders.Add(new LineBinder(v[1], v[2])); lineBinders.Add(new LineBinder(v[2], v[0])); mergeGoals.Add(new MergeGoal(v, 0.1f)); } } for (int j = 0; j <= yCount; j++) { for (int i = 0; i < xCount * 2; i++) { double xOffset = i + 0.5; double yOffset = 2 * j * cos30; Triple M = new Triple(xOffset, yOffset, 0.0); List <Triple> v = new List <Triple>(); for (int k = 1; k < 6; k += 2) { v.Add(new Triple(xOffset + offset * Math.Cos(k * Math.PI / 3.0), yOffset + offset * Math.Sin(k * Math.PI / 3.0), 0.0)); } lineBinders.Add(new LineBinder(v[0], v[1])); lineBinders.Add(new LineBinder(v[1], v[2])); lineBinders.Add(new LineBinder(v[2], v[0])); mergeGoals.Add(new MergeGoal(v, 0.1f)); } } return(new Dictionary <string, object> { { "shapeMatchingGoals", shapeMatchingGoals }, { "mergeGoals", mergeGoals }, { "meshBinders", meshBinders }, { "lineBinders", lineBinders }, }); }
public static Dictionary <string, object> AuxeticRotatingSquares(int xCount = 5, int yCount = 5, double thickness = 0.0) { List <Goal> shapeMatchingGoals = new List <Goal>(); List <GeometryBinder> meshBinders = new List <GeometryBinder>(); List <GeometryBinder> lineBinders = new List <GeometryBinder>(); List <Point> vertices = new List <Point>(); List <int> indices = new List <int>(); double offset = 0.001; List <Triple> targetShape = new List <Triple>() { new Triple(0, 0, 0), new Triple(1, 0, 0), new Triple(1, 1, 0), new Triple(0, 1, 0), }; if (thickness > 0.0) { for (int i = 0; i < 4; i++) { targetShape.Add(targetShape[i] + thickness * Triple.BasisZ); } } for (int i = 0; i < xCount; i++) { for (int j = 0; j < yCount; j++) { double k = 0.0; List <Triple> tileVertices = new List <Triple>(); if ((i + j) % 2 == 0) { tileVertices = new List <Triple>() { new Triple(i, j + offset, k), new Triple(i + 1f - offset, j, k), new Triple(i + 1f, j + 1f - offset, k), new Triple(i + offset, j + 1f, k), } } ; else { tileVertices = new List <Triple>() { new Triple(i + offset, j, k), new Triple(i + 1f, j + offset, k), new Triple(i + 1f - offset, j + 1f, k), new Triple(i, j + 1f - offset, k), }; } if (thickness > 0.0) { for (int ii = 0; ii < 4; ii++) { tileVertices.Add(tileVertices[ii] + thickness * Triple.BasisZ); } } shapeMatchingGoals.Add(new ShapeMatchingGoal(tileVertices, targetShape)); vertices.Add(tileVertices[0].ToPoint()); vertices.Add(tileVertices[1].ToPoint()); vertices.Add(tileVertices[2].ToPoint()); vertices.Add(tileVertices[3].ToPoint()); int n = vertices.Count - 4; indices.AddRange(new [] { n, n + 1, n + 2, n, n + 2, n + 3 }); } } List <Goal> lengthGoals = new List <Goal>(); for (int i = 1; i < xCount; i++) { for (int j = 0; j <= yCount; j++) { if ((i + j) % 2 == 1) { lengthGoals.Add(new LengthGoal( new Triple(i - offset, j, 0), new Triple(i + offset, j, 0))); lineBinders.Add(new LineBinder( new Triple(i - offset, j, 0), new Triple(i + offset, j, 0))); } } } for (int i = 0; i <= xCount; i++) { for (int j = 1; j < yCount; j++) { if ((i + j) % 2 == 0) { lengthGoals.Add(new LengthGoal( new Triple(i, j - offset, 0), new Triple(i, j + offset, 0))); lineBinders.Add(new LineBinder( new Triple(i, j - offset, 0), new Triple(i, j + offset, 0))); } } } meshBinders.Add(new MeshBinder(Mesh.ByVerticesAndIndices(vertices, indices), new Color(.3f, .6f, .8f, 1f))); return(new Dictionary <string, object> { { "shapeMatchingGoals", shapeMatchingGoals }, { "lengthGoals", lengthGoals }, { "meshBinders", meshBinders }, { "lineBinders", lineBinders }, }); }
public static Dictionary <string, object> PlaneMesh( [DefaultArgument("CoordinateSystem.ByOriginVectors(Point.Origin(), Vector.XAxis(), Vector.YAxis())")] CoordinateSystem cs, [DefaultArgument("20.0")] double lengthX, [DefaultArgument("20.0")] double lengthY, [DefaultArgument("20")] int divX, [DefaultArgument("20")] int divY, [DefaultArgument("true")] bool alternatingDiagons) { if (divX < 1 || divY < 0) { throw new Exception("divX and divY must be larger than 0"); } List <Point> vertices = new List <Point>((divX + 1) * (divY + 1)); Vector2Collection textureCoordinates = new Vector2Collection(); for (int j = 0; j <= divY; j++) { for (int i = 0; i <= divX; i++) { vertices.Add( Point.ByCartesianCoordinates( cs, ((double)i / divX - 0.5f) * lengthX, ((double)j / divY - 0.5f) * lengthY)); textureCoordinates.Add(new Vector2((float)i / (float)(divX), 1f - (float)j / (float)(divY))); } } List <int> indices = new List <int>(); List <List <int> > quadFaceVertexIndices = new List <List <int> >(); for (int j = 0; j < divY; j++) { for (int i = 0; i < divX; i++) { int a = i + j * (divX + 1); int b = i + 1 + j * (divX + 1); int c = i + 1 + (j + 1) * (divX + 1); int d = i + (j + 1) * (divX + 1); quadFaceVertexIndices.Add(new List <int> { a, b, c, d }); if (alternatingDiagons) { if ((i + j) % 2 == 0) { indices.Add(a); indices.Add(b); indices.Add(c); indices.Add(a); indices.Add(c); indices.Add(d); } else { indices.Add(a); indices.Add(b); indices.Add(d); indices.Add(b); indices.Add(c); indices.Add(d); } } else { indices.Add(a); indices.Add(b); indices.Add(c); indices.Add(a); indices.Add(c); indices.Add(d); } } } return(new Dictionary <string, object>() { { "mesh", Mesh.ByVerticesAndIndices(vertices, indices) }, { "quadFaceVertexIndices", quadFaceVertexIndices }, { "textureCoordinates", new TextureCoordinateSet(textureCoordinates) }, }); }
public static Dictionary <string, object> AuxeticRotatingSquares(int xCount = 5, int yCount = 5, double thickness = 0.0) { List <Goal> shapeMatchingGoals = new List <Goal>(); List <GeometryBinder> meshBinders = new List <GeometryBinder>(); List <GeometryBinder> lineBinders = new List <GeometryBinder>(); List <Point> vertices = new List <Point>(); List <int> indices = new List <int>(); double offset = 0.001; for (int i = 0; i < xCount; i++) { for (int j = 0; j < yCount; j++) { double k = 0.0; List <Triple> triples = new List <Triple>(); if ((i + j) % 2 == 0) { triples = new List <Triple>() { new Triple(i, j + offset, k), new Triple(i + 1f - offset, j, k), new Triple(i + 1f, j + 1f - offset, k), new Triple(i + offset, j + 1f, k), } } ; else { triples = new List <Triple>() { new Triple(i + offset, j, k), new Triple(i + 1f, j + offset, k), new Triple(i + 1f - offset, j + 1f, k), new Triple(i, j + 1f - offset, k), }; } if (thickness > 0.0) { for (int ii = 0; ii < 4; ii++) { triples.Add(triples[ii] + thickness * Triple.BasisZ); } } shapeMatchingGoals.Add(new ShapeMatchingGoal(triples, triples)); //goals.Add(new OnPlaneGoal(triples, Plane.XY())); vertices.Add(triples[0].ToPoint()); vertices.Add(triples[1].ToPoint()); vertices.Add(triples[2].ToPoint()); vertices.Add(triples[3].ToPoint()); int n = vertices.Count - 4; indices.AddRange(new [] { n, n + 1, n + 2, n, n + 2, n + 3 }); } } List <Goal> lengthGoals = new List <Goal>(); for (int i = 1; i < xCount; i++) { for (int j = 0; j <= yCount; j++) { if ((i + j) % 2 == 1) { lengthGoals.Add(new LengthGoal( new Triple(i - offset, j, 0), new Triple(i + offset, j, 0))); lineBinders.Add(new LineBinder( new Triple(i - offset, j, 0), new Triple(i + offset, j, 0))); } } } for (int i = 0; i <= xCount; i++) { for (int j = 1; j < yCount; j++) { if ((i + j) % 2 == 0) { lengthGoals.Add(new LengthGoal( new Triple(i, j - offset, 0), new Triple(i, j + offset, 0))); lineBinders.Add(new LineBinder( new Triple(i, j - offset, 0), new Triple(i, j + offset, 0))); } } } meshBinders.Add(new MeshBinder(Mesh.ByVerticesAndIndices(vertices, indices), new Color(.3f, .6f, .8f, 1f))); List <Triple> allTriples = new List <Triple>(); foreach (Point point in vertices) { allTriples.Add(point.ToTriple()); } return(new Dictionary <string, object> { { "shapeMatchingGoals", shapeMatchingGoals }, { "lengthGoals", lengthGoals }, //{"onSurfaceGoal", surface == null ? null : new OnSurfaceGoal(allTriples, surface, 1f)}, { "onSurfaceGoal", null }, { "meshBinders", meshBinders }, { "lineBinders", lineBinders }, }); }
public static Dictionary <string, object> Shearing(int xCount = 5, int yCount = 5, double k = 0.2, double thickness = 0.5) { shapeMatchingGoals = new List <ShapeMatchingGoal>(); vertices = new List <Point>(); indices = new List <int>(); polylineBinders = new List <PolylineBinder>(); for (int i = 0; i < xCount; i++) { for (int j = 0; j < yCount; j++) { if ((i + j) % 2 == 0) { CreateUnit(new List <Triple>() { new Triple(i, j + k, 0f), new Triple(i, j, 0f), new Triple(i + 1f - k, j, 0f), new Triple(i, j + k, thickness), new Triple(i, j, thickness), new Triple(i + 1f - k, j, thickness), }); CreateUnit(new List <Triple>() { new Triple(i + 1f - k, j, 0f), new Triple(i + 1f, j, 0f), new Triple(i + 1f, j + 1f - k, 0f), new Triple(i + 1f - k, j, thickness), new Triple(i + 1f, j, thickness), new Triple(i + 1f, j + 1f - k, thickness), }); CreateUnit(new List <Triple>() { new Triple(i + 1f, j + 1f - k, 0f), new Triple(i + 1f, j + 1f, 0f), new Triple(i + k, j + 1f, 0f), new Triple(i + 1f, j + 1f - k, thickness), new Triple(i + 1f, j + 1f, thickness), new Triple(i + k, j + 1f, thickness), }); CreateUnit(new List <Triple>() { new Triple(i + k, j + 1f, 0f), new Triple(i, j + 1f, 0f), new Triple(i, j + k, 0f), new Triple(i + k, j + 1f, thickness), new Triple(i, j + 1f, thickness), new Triple(i, j + k, thickness), }); } else { if (i == 0 || i == xCount - 1 || j == 0 || j == yCount - 1) { CreateUnit(new List <Triple>() { new Triple(i, j + 1f - k, 0f), new Triple(i, j, 0f), new Triple(i + k, j, 0f), new Triple(i, j + 1f - k, thickness), new Triple(i, j, thickness), new Triple(i + k, j, thickness), }); CreateUnit(new List <Triple>() { new Triple(i + k, j, 0f), new Triple(i + 1f, j, 0f), new Triple(i + 1f, j + k, 0f), new Triple(i + k, j, thickness), new Triple(i + 1f, j, thickness), new Triple(i + 1f, j + k, thickness), }); CreateUnit(new List <Triple>() { new Triple(i + 1f, j + k, 0f), new Triple(i + 1f, j + 1f, 0f), new Triple(i + 1f - k, j + 1f, 0f), new Triple(i + 1f, j + k, thickness), new Triple(i + 1f, j + 1f, thickness), new Triple(i + 1f - k, j + 1f, thickness), }); CreateUnit(new List <Triple>() { new Triple(i + 1f - k, j + 1f, 0f), new Triple(i, j + 1f, 0f), new Triple(i, j + 1f - k, 0f), new Triple(i + 1f - k, j + 1f, thickness), new Triple(i, j + 1f, thickness), new Triple(i, j + 1f - k, thickness), }); } } } } return(new Dictionary <string, object> { { "shapeMatchingGoals", shapeMatchingGoals }, { "meshBinders", new MeshBinder(Mesh.ByVerticesAndIndices(vertices, indices), new Color(0f, 0.7f, 1f, 0.9f)) }, { "polylineBinders", KinetiX.polylineBinders }, }); }
public static Mesh PlaneMesh( [DefaultArgument("CoordinateSystem.ByOriginVectors(Point.Origin(), Vector.XAxis(), Vector.YAxis())")] CoordinateSystem cs, [DefaultArgument("20.0")] double lengthX, [DefaultArgument("20.0")] double lengthY, [DefaultArgument("20")] int divX, [DefaultArgument("20")] int divY, [DefaultArgument("true")] bool alternatingDiagons) { List <Point> vertices = new List <Point>((divX + 1) * (divY + 1)); for (int j = 0; j <= divY; j++) { for (int i = 0; i <= divX; i++) { vertices.Add( Point.ByCartesianCoordinates( cs, ((double)i / divX - 0.5f) * lengthX, ((double)j / divY - 0.5f) * lengthY)); } } List <int> indices = new List <int>(); if (alternatingDiagons) { for (int j = 0; j < divY; j++) { for (int i = 0; i < divX; i++) { int a = i + j * (divX + 1); int b = i + 1 + j * (divX + 1); int c = i + 1 + (j + 1) * (divX + 1); int d = i + (j + 1) * (divX + 1); if ((i + j) % 2 == 0) { indices.Add(a); indices.Add(b); indices.Add(c); indices.Add(a); indices.Add(c); indices.Add(d); } else { indices.Add(a); indices.Add(b); indices.Add(d); indices.Add(b); indices.Add(c); indices.Add(d); } } } } else { for (int j = 0; j < divY; j++) { for (int i = 0; i < divX; i++) { int a = i + j * (divX + 1); int b = i + 1 + j * (divX + 1); int c = i + 1 + (j + 1) * (divX + 1); int d = i + (j + 1) * (divX + 1); indices.Add(a); indices.Add(b); indices.Add(c); indices.Add(a); indices.Add(c); indices.Add(d); } } } return(Mesh.ByVerticesAndIndices(vertices, indices)); }