public MyMarchingCubesMesher() { // Cube Edges for (int i = 0; i < m_edges.Length; i++) { m_edges[i] = new MyEdge(); } // Temporary voxel values, serve as cache between precalc and voxel map - so we don't have to always access voxel maps but can look here for (int i = 0; i < m_temporaryVoxels.Length; i++) { m_temporaryVoxels[i] = new MyTemporaryVoxel(); } // Array of edges in the cell m_edgeVertexCalcCounter = 0; m_edgeVertex = new MyEdgeVertex[CELL_EDGES_SIZE][][][]; for (int x = 0; x < CELL_EDGES_SIZE; x++) { m_edgeVertex[x] = new MyEdgeVertex[CELL_EDGES_SIZE][][]; for (int y = 0; y < CELL_EDGES_SIZE; y++) { m_edgeVertex[x][y] = new MyEdgeVertex[CELL_EDGES_SIZE][]; for (int z = 0; z < CELL_EDGES_SIZE; z++) { m_edgeVertex[x][y][z] = new MyEdgeVertex[MyMarchingCubesConstants.CELL_EDGE_COUNT]; for (int w = 0; w < MyMarchingCubesConstants.CELL_EDGE_COUNT; w++) { m_edgeVertex[x][y][z][w] = new MyEdgeVertex(); m_edgeVertex[x][y][z][w].CalcCounter = 0; } } } } }
public void TestBasicBranching() { m_out = new System.Text.StringBuilder(); Model model = new Model("Model"); model.AddService <ITaskManagementService>(new TaskManagementService()); object branchChannelMarker = "BranchChannelMarker"; Task root = new Task(model, "Root"); new TaskProcessor(model, "taskProcessor", root); // It is added into the model automatically. Edge sub1 = new MyEdge("Sub1", m_out); Edge sub2 = new MyEdge("Sub2", m_out); Edge sub3 = new MyEdge("Sub3", m_out); Edge.Connect(root.PreVertex, sub1.PreVertex); Edge.Connect(sub1.PostVertex, sub2.PreVertex).Channel = branchChannelMarker; Edge.Connect(sub2.PostVertex, sub1.PreVertex).Channel = branchChannelMarker; Edge.Connect(sub1.PostVertex, sub3.PreVertex); //Accept default channel marker. Edge.Connect(sub3.PostVertex, root.PostVertex); sub2.Channel = "AlternateChannelMarker"; sub1.PostVertex.EdgeFiringManager = new CountedBranchManager(model, new object[] { branchChannelMarker, Edge.NULL_CHANNEL_MARKER }, new int[] { 2, 1 }); sub1.PreVertex.EdgeReceiptManager = new MultiChannelEdgeReceiptManager(sub1.PreVertex); sub2.PreVertex.EdgeReceiptManager = new MultiChannelEdgeReceiptManager(sub2.PreVertex); sub3.PreVertex.EdgeReceiptManager = new MultiChannelEdgeReceiptManager(sub3.PreVertex); model.Start(); Assert.IsTrue(branchResult.Equals(m_out.ToString()), "BranchingTester Results", "Branching tester failed to match expected results."); }
public void TestBasicLooping() { m_out = new System.Text.StringBuilder(); Model model = new Model("Model"); model.AddService <ITaskManagementService>(new TaskManagementService()); Task root = new Task(model, "Root"); new TaskProcessor(model, "taskProcessor", root); // It is added into the model automatically. Edge sub1 = new MyEdge("Sub1", m_out); Edge sub2 = new MyEdge("Sub2", m_out); Edge sub3 = new MyEdge("Sub3", m_out); CreateLoopback(model, sub2.PostVertex, sub2.PreVertex, "LoopbackChannelMarker", 5); ArrayList children = new ArrayList(); children.Add(sub1); children.Add(sub2); children.Add(sub3); root.AddChainOfChildren(children); model.Start(); Assert.IsTrue(loopResult.Equals(m_out.ToString()), "LoopingTester Results", "Looping tester failed to match expected results."); }
// Linearly interpolates position, normal and material on poly-cube edge. Interpolated point is where an isosurface cuts an edge between two vertices, each with their own scalar value. void GetVertexInterpolation(MyStorageDataCache cache, MyTemporaryVoxel inputVoxelA, MyTemporaryVoxel inputVoxelB, int edgeIndex) { MyEdge edge = m_edges[edgeIndex]; byte contentA = cache.Content(inputVoxelA.IdxInCache); byte contentB = cache.Content(inputVoxelB.IdxInCache); byte materialA = cache.Material(inputVoxelA.IdxInCache); byte materialB = cache.Material(inputVoxelB.IdxInCache); if (Math.Abs(MyVoxelConstants.VOXEL_ISO_LEVEL - contentA) < 0.00001f) { edge.Position = inputVoxelA.Position; edge.Normal = inputVoxelA.Normal; edge.Material = materialA; edge.Ambient = inputVoxelA.Ambient; return; } if (Math.Abs(MyVoxelConstants.VOXEL_ISO_LEVEL - contentB) < 0.00001f) { edge.Position = inputVoxelB.Position; edge.Normal = inputVoxelB.Normal; edge.Material = materialB; edge.Ambient = inputVoxelB.Ambient; return; } float mu = (float)(MyVoxelConstants.VOXEL_ISO_LEVEL - contentA) / (float)(contentB - contentA); Debug.Assert(mu > 0.0f && mu < 1.0f); edge.Position.X = inputVoxelA.Position.X + mu * (inputVoxelB.Position.X - inputVoxelA.Position.X); edge.Position.Y = inputVoxelA.Position.Y + mu * (inputVoxelB.Position.Y - inputVoxelA.Position.Y); edge.Position.Z = inputVoxelA.Position.Z + mu * (inputVoxelB.Position.Z - inputVoxelA.Position.Z); edge.Normal.X = inputVoxelA.Normal.X + mu * (inputVoxelB.Normal.X - inputVoxelA.Normal.X); edge.Normal.Y = inputVoxelA.Normal.Y + mu * (inputVoxelB.Normal.Y - inputVoxelA.Normal.Y); edge.Normal.Z = inputVoxelA.Normal.Z + mu * (inputVoxelB.Normal.Z - inputVoxelA.Normal.Z); if (MyVRageUtils.IsZero(edge.Normal)) { edge.Normal = inputVoxelA.Normal; } else { edge.Normal = MyVRageUtils.Normalize(edge.Normal); } float mu2 = ((float)contentB) / (((float)contentA) + ((float)contentB)); edge.Material = (mu2 <= 0.5f) ? materialA : materialB; edge.Ambient = inputVoxelA.Ambient + mu2 * (inputVoxelB.Ambient - inputVoxelA.Ambient); return; }
public void LSystem(int iter) { PointF cur_point = new PointF(0, pictureBox1.Height - 10); string cur_iter = atom; int cur_angle = main_angle; for (int i = 0; i < iter; i++) { cur_iter = iterativeString(cur_iter); } f_length = ScaleSystem(cur_iter, ref cur_point, cur_angle, iter); Stack <PointF> savedPoint = new Stack <PointF>(); Stack <int> savedAngle = new Stack <int>(); bool rand_on = false; foreach (var ch in cur_iter) { if (ch == '+') { cur_angle += dangle; } else if (ch == '-') { cur_angle -= dangle; } else if (ch == 'F') { if (rand_on) { cur_angle = savedRandAngle.Dequeue(); } MyEdge e = EdgeByAngle(cur_point, cur_angle, f_length); draw_queue.Enqueue(e); cur_point = e.end; } else if (ch == '[') { savedAngle.Push(cur_angle); savedPoint.Push(cur_point); } else if (ch == ']') { cur_point = savedPoint.Pop(); cur_angle = savedAngle.Pop(); } else if (ch == '@') { rand_on = true; } } }
//+(-) - поворот по (против) часовой стрелке на угол //F,G,D - рисуют прямую public Bitmap DrawFractal(string fractal, double direction, double angle, int length, Bitmap bm) { if (fractal == null) { return(bm); } MyPoint p1 = new MyPoint(bm.Width / 2, bm.Height / 2); MyPoint p2 = new MyPoint(bm.Width / 2, bm.Height / 2 - length); Stack <KeyValuePair <MyPoint, double> > s = new Stack <KeyValuePair <MyPoint, double> >(); for (int i = 0; i < fractal.Length; ++i) { if (fractal[i] == '+') { direction += angle; } if (fractal[i] == '-') { direction -= angle; } if (fractal[i] == 'F' || fractal[i] == 'G' || fractal[i] == 'D') { p2.RotationPoint(p1, direction); if (0 < p1.X && 0 < p1.Y && 0 < p2.X && 0 < p2.Y && bm.Width > p1.X && bm.Height > p1.Y && bm.Width > p2.X && bm.Height > p2.Y) { bm = MyEdge.DrawEdge(bm, p1, p2); } p1 = p2; p2 = new MyPoint(p1.X, p1.Y - length); } if (fractal[i] == '[') { s.Push(new KeyValuePair <MyPoint, double>(p1, direction)); } if (fractal[i] == ']') { p1 = s.Peek().Key; direction = s.Pop().Value; p2 = new MyPoint(p1.X, p1.Y - length); } } return(bm); }
public MyPoint IntersectionEdge(MyEdge edge) { double k1 = (p2.X - p1.X) / (p2.Y - p1.Y); double k2 = (edge.P2.X - edge.P1.X) / (edge.P2.Y - edge.P1.Y); if (k1 == k2) { return(null); } double x = ((p1.X * p2.Y - p2.X * p1.Y) * (edge.P2.X - edge.P1.X) - (edge.P1.X * edge.P2.Y - edge.P2.X * edge.P1.Y) * (p2.X - p1.X)) / ((p1.Y - p2.Y) * (edge.P2.X - edge.P1.X) - (edge.P1.Y - edge.P2.Y) * (p2.X - p1.X)); double y = ((edge.P1.Y - edge.P2.Y) * x - (edge.P1.X * edge.P2.Y - edge.P2.X * edge.P1.Y)) / (edge.P2.X - edge.P1.X); if (x >= Math.Min(Math.Min(p1.X, p2.X), Math.Min(edge.P1.X, edge.P2.X)) && x <= Math.Max(Math.Max(p1.X, p2.X), Math.Max(edge.P1.X, edge.P2.X)) && y >= Math.Min(Math.Min(p1.Y, p2.Y), Math.Min(edge.P1.Y, edge.P2.Y)) && y <= Math.Max(Math.Max(p1.Y, p2.Y), Math.Max(edge.P1.Y, edge.P2.Y))) { return(new MyPoint(x, y)); } else { return(null); } }
private void CreateTriangles(ref Vector3I coord0, int cubeIndex, ref Vector3I tempVoxelCoord0) { MyVoxelVertex tmpVertex = new MyVoxelVertex(); int g = MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_VOXELS; Vector3I edge = new Vector3I(coord0.X, coord0.Y, coord0.Z); for (int i = 0; MyMarchingCubesConstants.TriangleTable[cubeIndex, i] != -1; i += 3) { // Edge indexes inside the cube int edgeIndex0 = MyMarchingCubesConstants.TriangleTable[cubeIndex, i + 0]; int edgeIndex1 = MyMarchingCubesConstants.TriangleTable[cubeIndex, i + 1]; int edgeIndex2 = MyMarchingCubesConstants.TriangleTable[cubeIndex, i + 2]; MyEdge edge0 = m_edges[edgeIndex0]; MyEdge edge1 = m_edges[edgeIndex1]; MyEdge edge2 = m_edges[edgeIndex2]; // Edge indexes inside the cell Vector4I edgeConversion0 = MyMarchingCubesConstants.EdgeConversion[edgeIndex0]; Vector4I edgeConversion1 = MyMarchingCubesConstants.EdgeConversion[edgeIndex1]; Vector4I edgeConversion2 = MyMarchingCubesConstants.EdgeConversion[edgeIndex2]; MyEdgeVertex edgeVertex0 = m_edgeVertex[edge.X + edgeConversion0.X][edge.Y + edgeConversion0.Y][edge.Z + edgeConversion0.Z][edgeConversion0.W]; MyEdgeVertex edgeVertex1 = m_edgeVertex[edge.X + edgeConversion1.X][edge.Y + edgeConversion1.Y][edge.Z + edgeConversion1.Z][edgeConversion1.W]; MyEdgeVertex edgeVertex2 = m_edgeVertex[edge.X + edgeConversion2.X][edge.Y + edgeConversion2.Y][edge.Z + edgeConversion2.Z][edgeConversion2.W]; MyVoxelVertex compressedVertex0 = new MyVoxelVertex(); compressedVertex0.Position = edge0.Position; MyVoxelVertex compressedVertex1 = new MyVoxelVertex(); compressedVertex1.Position = edge1.Position; MyVoxelVertex compressedVertex2 = new MyVoxelVertex(); compressedVertex2.Position = edge2.Position; // We want to skip all wrong triangles, those that have two vertex at almost the same location, etc. // We do it simply, by calculating triangle normal and then checking if this normal has length large enough if (IsWrongTriangle(ref compressedVertex0, ref compressedVertex1, ref compressedVertex2) == true) { continue; } // Vertex at edge 0 if (edgeVertex0.CalcCounter != m_edgeVertexCalcCounter) { // If vertex at edge0 wasn't calculated for this cell during this precalc, we need to add it // Short overflow check System.Diagnostics.Debug.Assert(m_resultVerticesCounter <= ushort.MaxValue); edgeVertex0.CalcCounter = m_edgeVertexCalcCounter; edgeVertex0.VertexIndex = (ushort)m_resultVerticesCounter; tmpVertex.Position = edge0.Position; tmpVertex.Normal = edge0.Normal; tmpVertex.Ambient = edge0.Ambient; tmpVertex.Material = edge0.Material; tmpVertex.PositionMorph = edge0.Position; m_resultVertices[m_resultVerticesCounter] = tmpVertex; m_resultVerticesCounter++; } // Vertex at edge 1 if (edgeVertex1.CalcCounter != m_edgeVertexCalcCounter) { // If vertex at edge1 wasn't calculated for this cell during this precalc, we need to add it // Short overflow check System.Diagnostics.Debug.Assert(m_resultVerticesCounter <= ushort.MaxValue); edgeVertex1.CalcCounter = m_edgeVertexCalcCounter; edgeVertex1.VertexIndex = (ushort)m_resultVerticesCounter; tmpVertex.Position = edge1.Position; tmpVertex.Normal = edge1.Normal; tmpVertex.Ambient = edge1.Ambient; tmpVertex.Material = edge1.Material; tmpVertex.PositionMorph = edge1.Position; m_resultVertices[m_resultVerticesCounter] = tmpVertex; m_resultVerticesCounter++; } // Vertex at edge 2 if (edgeVertex2.CalcCounter != m_edgeVertexCalcCounter) { // If vertex at edge2 wasn't calculated for this cell during this precalc, we need to add it // Short overflow check System.Diagnostics.Debug.Assert(m_resultVerticesCounter <= ushort.MaxValue); edgeVertex2.CalcCounter = m_edgeVertexCalcCounter; edgeVertex2.VertexIndex = (ushort)m_resultVerticesCounter; tmpVertex.Position = edge2.Position; tmpVertex.Normal = edge2.Normal; tmpVertex.Ambient = edge2.Ambient; tmpVertex.Material = edge2.Material; tmpVertex.PositionMorph = edge2.Position; tmpVertex.Cell = coord0; ; m_resultVertices[m_resultVerticesCounter] = tmpVertex; m_resultVerticesCounter++; } // Triangle m_resultTriangles[m_resultTrianglesCounter].VertexIndex0 = edgeVertex0.VertexIndex; m_resultTriangles[m_resultTrianglesCounter].VertexIndex1 = edgeVertex1.VertexIndex; m_resultTriangles[m_resultTrianglesCounter].VertexIndex2 = edgeVertex2.VertexIndex; Debug.Assert(edgeVertex0.VertexIndex < m_resultVerticesCounter); Debug.Assert(edgeVertex1.VertexIndex < m_resultVerticesCounter); Debug.Assert(edgeVertex2.VertexIndex < m_resultVerticesCounter); m_resultTrianglesCounter++; } }
private void Button5_Click_1(object sender, EventArgs e)// BellmanFord { try { iskm = Convert.ToInt32(textBox6.Text);//ИСКОМАЯ ВЕРШИНА } catch (Exception) { MessageBox.Show("Введите вершину для поиска"); return; } List <MyEdge> arr = new List <MyEdge>(); arr = new List <MyEdge>(); for (int i = 0; i < this.n; i++) { for (int j = 0; j < this.n; j++) { if (!double.IsInfinity(mas[i, j]))//если не бесконечность, значит есть вершина { MyEdge me = new MyEdge(); me.from = i;//записал в ребро всю инфу me.to = j; me.weight = mas[i, j]; arr.Add(me); } } } int edgesNumber = arr.Count; dist = new double[n]; for (int i = 0; i < n; ++i)//сначала расстояния считаем бесконечностями { dist[i] = double.PositiveInfinity; } dist[iskm] = 0; //расстояние до самой себя, очевидно равно нулю for (int i = 1; i < n; ++i) //для каждой вершины проходимся по всем рёбрам n-1 раз //(максимальное число рёбер между двумя вершинами: n-1) { for (int j = 0; j < edgesNumber; ++j) { int u = arr[j].from; int v = arr[j].to; double weight = arr[j].weight; //если уже известное расстояние до вершины u не равно бесконечности и добавление нового ребра //с началом в u меньше известного расстояния до вершины v, то делаем расстояние до вершины v // равным расстоянию до u + длина данного ребра if (dist[u] != double.PositiveInfinity && dist[u] + weight < dist[v]) { dist[v] = dist[u] + weight; cntBellFord++; } cntBellFord++; } } for (int j = 0; j < edgesNumber; ++j)//проверка на негативный цикл { int u = arr[j].from; int v = arr[j].to; double weight = arr[j].weight; if (dist[u] != double.PositiveInfinity && dist[u] + weight < dist[v]) //с минимальными расстояниями //что -то не то, если они негативные. Просто они накапливают мимнимальное значение //за счет негативных путей. { textBox2.Text = "Есть отрицательный цикл"; } } dijkstra(mas, iskm); textBox1.Text = Convert.ToString(cntBellFord); Form3 f1 = new Form3(); f1.Owner = this; f1.ShowDialog(); dist = null; cntBellFord = 0; }
protected List <MyEdge> arr; //Здесь соберу все рёбра public void Button7_Click_1(object sender, EventArgs e) //КРАСКАЛ { //double[] edges = new double[(n * (n - 1) / 2)];// формула максимального числа рёбер(полного графа) arr = new List <MyEdge>(); for (int i = 0; i < n; i++)//Отрезаю нижний треугольник, т.к. граф неориентированный { for (int j = 0; j < i; j++) { mas[i, j] = double.PositiveInfinity; } } for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (!Double.IsInfinity(mas[i, j]))//если не бесконечность, значит есть вершина { MyEdge me = new MyEdge(); me.from = i;//записал в ребро всю инфу me.to = j; me.vertice1 = dataGridView1.Rows[i].HeaderCell.Value.ToString(); me.vertice2 = dataGridView1.Columns[j].HeaderCell.Value.ToString(); me.weight = mas[i, j]; arr.Add(me); } } } if (arr.Count == 0) { return; } IEnumerable <MyEdge> query = arr.OrderBy(MyEdge => MyEdge.weight); //просто делает запрос, исходный массив не сортируется List <MyEdge> srtd = new List <MyEdge>(); //список отсортированных рёбер for (int i = 0; i < arr.Count; i++) {//добавил ссылки в новый массив. srtd вроде как получился индексным srtd.Add(query.ElementAt(i)); } int edgesNumber = srtd.Count; double k = Convert.ToDouble(edgesNumber); cntKrusc += k * Math.Log(k, 2); MyEdge[] result = new MyEdge[n - 1]; //в результирующем списке рёбер всегда будет n-1 int ee = 0; // индекс для масива result int ii = 0; // индекс для отсортированных рёбер subset[] subsets = new subset[n]; for (ii = 0; ii < n; ++ii)// выделяю память для n подмассивов { subsets[ii] = new subset(); subsets[ii].parent = ii; subsets[ii].rank = 0; } ii = 0; while (ee < n - 1) //пока не набрали n-1 рёбер { cntKrusc++; //подсчет одной попытки добавления ребра, результативной или нет, не важно MyEdge next_edge = new MyEdge(); next_edge = srtd[ii++]; //беру очередное ребро из списка отсортированных //сабсет изначально содержит все вершины в виде объектов subset //эти вершины представлены просто индексами каждого объекта сабсет. //А вот принадлежность к дереву изначально сама на себя(индекс сабсета и номер родителя одинаковы). //Т.е. вершина сама как бы является деревом, ссылаясь на себя. При добавлении новой вершины //она направляется на сабсет с индексом-номером этой, добавляемой вершины и ищет там своего предка, //гляда на родителя этого сабсета. Находит его и назначает себе. А при присоединении к вершине // с меньшим рангом всё равно ворзвращаешься на того же родителя. //Остановка происходит, когда добавлено n-1 рёбер. До этого может несколько рёбер пропустить, если //у обеих их вершин будет одинаковый предок. int x = find(subsets, next_edge.from); //ищем вершинки. Если они обе(их общие предки) уже есть int y = find(subsets, next_edge.to); //в сабсетах,то включение данного ребра бессмысленно if (x != y) //Если включение данного ребра не создаёт цикл(если общие предки вершин разные), то { //добавить его в result и увеличить индекс для выбора следующего ребра result[ee++] = next_edge; //добавить ребро в список Union(subsets, x, y); //добавить вершины в сабсеты(по сути назначить им общего родителя) cntKrusc++; //подсчет одной результативной попытки }//иначе игнорировать ребро } for (int i = 0; i < n; i++) {//Все вершины в бесконечность перед обновлением матрицы for (int j = 0; j < n; j++) { mas[i, j] = double.PositiveInfinity; dataGridView1.Rows[i].Cells[j].Value = mas[i, j]; } } for (int a = 0; a < result.Length; a++) {//засовываю в mas & datagridview пересчитанные Краскалом значения int i = result[a].from; int j = result[a].to; double w = result[a].weight; mas[i, j] = w; dataGridView1.Rows[i].Cells[j].Value = w; } textBox1.Text = Convert.ToString(Convert.ToInt32(cntKrusc)); cntKrusc = 0; }
public float ScaleSystem(string input, ref PointF start_point, int angle, int iter) { float length = f_length; double min_x = 0; double max_x = 0; double min_y = pictureBox1.Height - 10; double max_y = pictureBox1.Height - 10; Stack <PointF> savedPoint = new Stack <PointF>(); Stack <int> savedAngle = new Stack <int>(); savedRandAngle = new Queue <int>(); bool rand_on = false; foreach (var ch in input) { if (ch == '+') { if (rand_on) { angle += dangle + r.Next(-dangle, dangle) / 2; } else { angle += dangle; } } else if (ch == '-') { if (rand_on) { angle -= dangle + r.Next(-dangle, dangle) / 2; } else { angle -= dangle; } } else if (ch == 'F') { if (rand_on) { savedRandAngle.Enqueue(angle); } MyEdge e = EdgeByAngle(start_point, angle, length); if (e.end.X > max_x) { max_x = e.end.X; } if (e.end.Y > max_y) { max_y = e.end.Y; } if (e.end.Y < min_y) { min_y = e.end.Y; } if (e.end.X < min_x) { min_x = e.end.X; } start_point = e.end; } else if (ch == '[') { savedAngle.Push(angle); savedPoint.Push(start_point); } else if (ch == ']') { start_point = savedPoint.Pop(); angle = savedAngle.Pop(); } else if (ch == '@') { rand_on = true; } } double dx = max_x - min_x; double dy = max_y - min_y; double prop_x, prop_y, min_prop; if (dx != 0) { prop_x = (pictureBox1.Width - 1) / dx; } else { prop_x = -1; } if (dy != 0) { prop_y = (pictureBox1.Height - 1) / dy; } else { prop_y = -1; } if (prop_x < prop_y) { min_prop = prop_x; } else { min_prop = prop_y; } start_point = new PointF((float)Math.Abs(min_x * min_prop), (float)Math.Abs((min_y - pictureBox1.Height + 10) * min_prop)); return(length * (float)min_prop); }