Exemplo n.º 1
0
        public bool BridgeAngle(Polygons areaGoingOnTop, long perimeterExpandDistance, out double bridgeAngle, Polygons bridgeAreas, string debugName = "")
        {
            SliceLayer layerToRestOn = this;

            bridgeAngle = -1;
            var boundaryBox = new Aabb(areaGoingOnTop);

            boundaryBox.Expand(perimeterExpandDistance);
            // To detect if we have a bridge, first calculate the intersection of the current layer with the previous layer.
            // This gives us the islands that the layer rests on.

            var islandsToRestOn = new Polygons();

            foreach (LayerIsland islandToRestOn in layerToRestOn.Islands)
            {
                if (!boundaryBox.Hit(islandToRestOn.BoundingBox))
                {
                    continue;
                }

                islandsToRestOn.AddRange(areaGoingOnTop.CreateIntersection(islandToRestOn.IslandOutline));
            }

            if (bridgeAreas != null)
            {
                bridgeAreas.AddRange(areaGoingOnTop.CreateDifference(layerToRestOn.AllOutlines));
            }

            if (outputDebugData)
            {
                WriteDebugData(areaGoingOnTop, layerToRestOn, islandsToRestOn);
            }

            if (islandsToRestOn.Count > 5 || islandsToRestOn.Count < 1)
            {
                return(false);
            }

            if (islandsToRestOn.Count == 1)
            {
                return(GetSingleIslandAngle(areaGoingOnTop, islandsToRestOn[0], out bridgeAngle, debugName));
            }

            // Find the 2 largest islands that we rest on.
            double biggestArea       = 0;
            double nextBiggestArea   = 0;
            int    indexOfBiggest    = -1;
            int    indexOfNextBigest = -1;

            for (int islandIndex = 0; islandIndex < islandsToRestOn.Count; islandIndex++)
            {
                // Skip internal holes
                if (!islandsToRestOn[islandIndex].Orientation())
                {
                    continue;
                }

                double area = Math.Abs(islandsToRestOn[islandIndex].Area());
                if (area > biggestArea)
                {
                    if (biggestArea > nextBiggestArea)
                    {
                        nextBiggestArea   = biggestArea;
                        indexOfNextBigest = indexOfBiggest;
                    }

                    biggestArea    = area;
                    indexOfBiggest = islandIndex;
                }
                else if (area > nextBiggestArea)
                {
                    nextBiggestArea   = area;
                    indexOfNextBigest = islandIndex;
                }
            }

            if (indexOfBiggest < 0 || indexOfNextBigest < 0)
            {
                return(false);
            }

            IntPoint center1 = islandsToRestOn[indexOfBiggest].CenterOfMass();
            IntPoint center2 = islandsToRestOn[indexOfNextBigest].CenterOfMass();

            bridgeAngle = Math.Atan2(center2.Y - center1.Y, center2.X - center1.X) / Math.PI * 180;
            Range0To360(ref bridgeAngle);
            if (outputDebugData)
            {
                islandsToRestOn.SaveToGCode("{0} - angle {1:0.}.gcode".FormatWith(debugName, bridgeAngle));
            }

            return(true);
        }