예제 #1
0
        public static QuiverWithPotential <int> GetEvenFlowerType1QP(int numVerticesInCenterPolygon, int firstVertex = DefaultFirstVertex)
        {
            if (!EvenFlowerType1ParameterIsValid(numVerticesInCenterPolygon))
            {
                throw new ArgumentOutOfRangeException(nameof(numVerticesInCenterPolygon));
            }

            int numLayers = UsefulQuivers.GetNumberOfLayersInEvenFlowerType1Quiver(numVerticesInCenterPolygon);
            int numVerticesInFullInnerLayer = 2 * numVerticesInCenterPolygon;
            int numVerticesInOuterLayer     = 3 * numVerticesInCenterPolygon;

            var potential = new Potential <int>();

            // Center polygon
            potential = potential.AddCycle(new DetachedCycle <int>(Enumerable.Range(firstVertex, numVerticesInCenterPolygon).AppendElement(firstVertex)), +1);

            // Full inner layers
            if (numLayers > 2)
            {
                // First layer (the squares and triangles between the first and second layers)
                var curLayer  = GetLayerVertices(0);
                var nextLayer = GetLayerVertices(1);
                for (int indexInLayer = 0; indexInLayer < numVerticesInCenterPolygon; indexInLayer++)
                {
                    var triangleVertices = new int[] { curLayer[indexInLayer], nextLayer[2 * indexInLayer - 1], nextLayer[2 * indexInLayer], curLayer[indexInLayer] };
                    potential = potential.AddCycle(new DetachedCycle <int>(triangleVertices), +1);

                    var squareVertices = new int[] { curLayer[indexInLayer], curLayer[indexInLayer + 1], nextLayer[2 * indexInLayer + 1], nextLayer[2 * indexInLayer], curLayer[indexInLayer] };
                    potential = potential.AddCycle(new DetachedCycle <int>(squareVertices), -1);
                }

                // Remaining layers (only squares)
                for (int layerIndex = 1; layerIndex < numLayers - 2; layerIndex++) // 0-based layer index
                {
                    curLayer  = GetLayerVertices(layerIndex);
                    nextLayer = GetLayerVertices(layerIndex + 1);
                    for (int indexInLayer = 0; indexInLayer < numVerticesInFullInnerLayer; indexInLayer++)
                    {
                        int sign = (layerIndex + indexInLayer).Modulo(2) == 1 ? +1 : -1;

                        var squareVertices = sign == +1 ?
                                             new int[] { curLayer[indexInLayer + 1], curLayer[indexInLayer], nextLayer[indexInLayer], nextLayer[indexInLayer + 1], curLayer[indexInLayer + 1] } :
                        new int[] { curLayer[indexInLayer], curLayer[indexInLayer + 1], nextLayer[indexInLayer + 1], nextLayer[indexInLayer], curLayer[indexInLayer] };
                        potential = potential.AddCycle(new DetachedCycle <int>(squareVertices), sign);
                    }
                }
            }

            // Outer layer
            {
                int layerIndex = numLayers - 2;
                var curLayer   = GetLayerVertices(layerIndex);
                var nextLayer  = GetLayerVertices(layerIndex + 1);
                if (numLayers == 2)
                {
                    // Add pentagons and triangle in this degenerate case
                    for (int indexInLayer = 0; indexInLayer < curLayer.Count; indexInLayer++)
                    {
                        var triangleVertices = new int[] { curLayer[indexInLayer], nextLayer[3 * indexInLayer - 1], nextLayer[3 * indexInLayer], curLayer[indexInLayer] };
                        potential = potential.AddCycle(new DetachedCycle <int>(triangleVertices), +1);

                        var pentagonVertices = new int[] { curLayer[indexInLayer], curLayer[indexInLayer + 1], nextLayer[3 * indexInLayer + 2], nextLayer[3 * indexInLayer + 1], nextLayer[3 * indexInLayer], curLayer[indexInLayer] };
                        potential = potential.AddCycle(new DetachedCycle <int>(pentagonVertices), -1);
                    }
                }
                else
                {
                    // Add pentagons and squares in the non-degenerate case
                    for (int indexInCenterLayer = 0; indexInCenterLayer < numVerticesInCenterPolygon; indexInCenterLayer++)
                    {
                        // Add pentagon
                        int indexInPenultimateLayer = 2 * indexInCenterLayer;
                        int indexInUltimateLayer    = 3 * indexInCenterLayer;
                        int pentagonSign            = layerIndex.Modulo(2) == 1 ? +1 : -1; // Remember that layerIndex is the index of the *penultimate* layer
                        var pentagonVertices        = pentagonSign == +1 ?
                                                      new int[] { curLayer[indexInPenultimateLayer + 1], curLayer[indexInPenultimateLayer], nextLayer[indexInUltimateLayer], nextLayer[indexInUltimateLayer + 1], nextLayer[indexInUltimateLayer + 2], curLayer[indexInPenultimateLayer + 1] } :
                        new int[] { curLayer[indexInPenultimateLayer], curLayer[indexInPenultimateLayer + 1], nextLayer[indexInUltimateLayer + 2], nextLayer[indexInUltimateLayer + 1], nextLayer[indexInUltimateLayer], curLayer[indexInPenultimateLayer] };
                        potential = potential.AddCycle(new DetachedCycle <int>(pentagonVertices), pentagonSign);

                        // Add square
                        int squareSign = -pentagonSign;
                        indexInPenultimateLayer += 1;
                        indexInUltimateLayer    += 2;
                        var squareVertices = squareSign == +1 ?
                                             new int[] { curLayer[indexInPenultimateLayer + 1], curLayer[indexInPenultimateLayer], nextLayer[indexInUltimateLayer], nextLayer[indexInUltimateLayer + 1], curLayer[indexInPenultimateLayer + 1] } :
                        new int[] { curLayer[indexInPenultimateLayer], curLayer[indexInPenultimateLayer + 1], nextLayer[indexInUltimateLayer + 1], nextLayer[indexInUltimateLayer], curLayer[indexInPenultimateLayer] };
                        potential = potential.AddCycle(new DetachedCycle <int>(squareVertices), squareSign);
                    }
                }
            }

            var qp = new QuiverWithPotential <int>(potential);

            return(qp);

            CircularList <int> GetLayerVertices(int layerIndex)
            => new CircularList <int>(GetVerticesInEvenFlowerType1QPLayer(numVerticesInCenterPolygon, layerIndex, firstVertex));
        }
예제 #2
0
 public static int GetNumberOfLayersInEvenFlowerType1QP(int numVerticesInCenterPolygon)
 => UsefulQuivers.GetNumberOfLayersInEvenFlowerType1Quiver(numVerticesInCenterPolygon);