Example #1
0
        private void ChainDeeper(Node firstNode, Node secondNode)
        {
            ElementsChain chain = new ElementsChain();

            chain.AddNode(firstNode);                                                                               // Добавляем текущую ноду в цепь
            chain.AddNode(secondNode);                                                                              // Добавляем предыдущую ноду в цепь

            Node currentNode = secondNode;
            Node prevNode    = firstNode;

            while (currentNode.Connections.Count < 3)
            {
                if (currentNode.Connections.Count < 2)                                                              // Тупик
                {
                    return;
                }
                Node nextNode = currentNode.Connections.Keys.FirstOrDefault(i => i != prevNode);
                prevNode    = currentNode;                                                                                          // Переходим на следующую
                currentNode = nextNode;
                chain.AddNode(currentNode);                                                                                         // Записываем ноду в цепь
            }
            if (Chains.FirstOrDefault(i => i.Nodes.First() == chain.Nodes.Last() && i.Nodes.Last() == chain.Nodes.First()) == null) // Проверка на существующий путь
            {
                Chains.Add(chain);                                                                                                  // Добавляем цепь в список цепей
            }
        }
Example #2
0
        public int SameDirected(ElementsChain chain)
        {
            var left    = Nodes.Skip(1).TakeWhile(i => i != chain.Nodes.First()).ToArray();
            var right   = Nodes.Skip(left.Length + 1).ToArray();
            var rotated = right.Concat(left).ToArray();

            return(rotated[1] == chain.Nodes[1] ? 1 : rotated.Last() == chain.Nodes[1] ? -1 : 0);
        }
Example #3
0
        public void Update()
        {
            ResetNodesState();                                                                      // Сброс состояния нод, присвоение им номеров

            foreach (Connector connector in Connectors)
            {
                if (connector.NodeA.Connections.Count == 1 && connector.NodeB.Connections.Count > 1 ||
                    connector.NodeA.Connections.Count > 1 && connector.NodeB.Connections.Count == 1)
                {
                    throw new WrongSchemeException("Unconnected pin found!");
                }
            }

            ContoursSearch();                                                                       // Получаем список замкнутых контуров

            if (Contours.Count < 1)
            {
                return;
            }

            if (Contours.Count == 1)
            {
                if (Contours.First().Connectors.Count(i => i is Battery) != 1)
                {
                    throw new WrongSchemeException("Check layout! Wrong batteries amount!");
                }

                Battery       bat      = Contours.First().Connectors.First(i => i is Battery) as Battery;
                ElementsChain batChain = new ElementsChain(new Node[] { bat.NodeA, bat.NodeB });
                double        amp      = bat.Eds / Contours.First().Connectors.Sum(i => i.Resistance) * Contours.First().SameDirected(batChain);

                Contours.First().RunElectricCurrent(amp);
                return;
            }

            ChainsSerach();                                                                         // Получаем список цепей
            UpdateChainNumbers();

            Rule1Count = Nodes.Count(i => i.Connections.Count > 2) - 1;                   // Количество уравнений по первому правилу
            int matrixSize = Chains.Count;                                                // Размер матрицы (количество неизвестных)

            CountMatrix  = new double[matrixSize, matrixSize];                            // Матрица для левой части уравнений
            resultVector = new double[matrixSize];                                        // Вектор для правой части уравнений

            for (int i = 0; i < matrixSize; i++)                                          // Уравнение
            {
                for (int j = 0; j < matrixSize; j++)                                      // Неизвестная
                {
                    if (i < Rule1Count)                                                   // Первое правило
                    {
                        Node curNode = Nodes                                              // Следующая по списку нода с >2 ног
                                       .Where(nd => nd.Connections.Count > 2)
                                       .ElementAt(i);
                        CountMatrix[i, j] = Chains[j].GetCurrentDirection(curNode);
                    }
                    else                                                                            // Второе правило
                    {
                        // Если контур включает в себя хотябы один коннектор из цепочки, то он включает в себя всю цепочку
                        if (Contours[i - Rule1Count].Connectors.Contains(Chains[j].Connectors.First()))
                        {
                            CountMatrix[i, j] = Chains[j].GetResistance() * Contours[i - Rule1Count].SameDirected(Chains[j]);
                        }
                    }
                }
                resultVector[i] = i < Rule1Count ? 0 : Contours[i - Rule1Count].GetEds();      // Результирующий вектор (0 или сумма ЭДС)
            }

            KramerCounter kc = new KramerCounter(CountMatrix, resultVector);            // Крамер

            double[] xv = kc.Answer;

            for (int i = 0; i < xv.Length; i++)
            {
                Chains[i].RunElectricCurrent(-xv[i]);
            }
            Fire("Quations", "DisplayMatrix");
        }