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;
                        }
                    }
                }
            }
        }
Ejemplo n.º 2
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.");
        }
Ejemplo n.º 3
0
        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;
        }
Ejemplo n.º 5
0
        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;
                }
            }
        }
Ejemplo n.º 6
0
        //+(-) - поворот по (против) часовой стрелке на угол
        //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);
        }
Ejemplo n.º 7
0
            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++;
            }
        }
Ejemplo n.º 9
0
        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;
                        }
                    }
                }
            }
        }
Ejemplo n.º 10
0
        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;
        }
Ejemplo n.º 11
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;
        }
Ejemplo n.º 12
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);
        }