예제 #1
0
        public static void GenerateHexLinePaths(Polygons in_outline, ref Polygons result, int lineSpacing, int infillExtendIntoPerimeter_um, double rotationDegrees, int layerIndex)
        {
            int extraRotationAngle = 0;

            if (in_outline.Count > 0)
            {
                Polygons outlines = in_outline.Offset(infillExtendIntoPerimeter_um);
                if (outlines.Count > 0)
                {
                    int         perIncrementOffset = (int)(lineSpacing * Math.Sqrt(3) / 2 + .5);
                    PointMatrix matrix             = new PointMatrix(-(rotationDegrees + extraRotationAngle));         // we are rotating the part so we rotate by the negative so the lines go the way we expect

                    outlines.applyMatrix(matrix);

                    AABB boundary = new AABB(outlines);

                    boundary.min.X  = ((boundary.min.X / lineSpacing) - 1) * lineSpacing;
                    boundary.min.Y  = ((boundary.min.Y / perIncrementOffset) - 1) * perIncrementOffset;
                    boundary.max.X += lineSpacing;
                    boundary.max.Y += perIncrementOffset;
                    Polygons unclipedPatern = new Polygons();

                    foreach (IntPoint startPoint in StartPositionIterator(boundary, lineSpacing, layerIndex))
                    {
                        Polygon attachedLine = new Polygon();
                        foreach (IntPoint center in IncrementPositionIterator(startPoint, boundary, lineSpacing, layerIndex))
                        {
                            // what we are adding are the little plusses that define the points
                            //        | top
                            //        |
                            //        /\ center
                            //   left/  \ right
                            //
                            IntPoint left  = center + new IntPoint(-lineSpacing / 2, -perIncrementOffset / 3);
                            IntPoint right = center + new IntPoint(lineSpacing / 2, -perIncrementOffset / 3);
                            IntPoint top   = center + new IntPoint(0, perIncrementOffset * 2 / 3);

                            switch (layerIndex % 3)
                            {
                            case 0:                                     // left to right
                                attachedLine.Add(left); attachedLine.Add(center);
                                attachedLine.Add(center); attachedLine.Add(right);
                                unclipedPatern.Add(new Polygon()
                                {
                                    top, center
                                });
                                break;

                            case 1:                                     // left to top
                                attachedLine.Add(left); attachedLine.Add(center);
                                attachedLine.Add(center); attachedLine.Add(top);
                                unclipedPatern.Add(new Polygon()
                                {
                                    center, right
                                });
                                break;

                            case 2:                                     // top to right
                                attachedLine.Add(top); attachedLine.Add(center);
                                attachedLine.Add(center); attachedLine.Add(right);
                                unclipedPatern.Add(new Polygon()
                                {
                                    left, center
                                });
                                break;
                            }
                        }
                        if (attachedLine.Count > 0)
                        {
                            unclipedPatern.Add(attachedLine);
                        }
                    }

                    PolyTree ret     = new PolyTree();
                    Clipper  clipper = new Clipper();
                    clipper.AddPaths(unclipedPatern, PolyType.ptSubject, false);
                    clipper.AddPaths(outlines, PolyType.ptClip, true);
                    clipper.Execute(ClipType.ctIntersection, ret, PolyFillType.pftPositive, PolyFillType.pftEvenOdd);

                    Polygons    newSegments   = Clipper.OpenPathsFromPolyTree(ret);
                    PointMatrix inversematrix = new PointMatrix((rotationDegrees + extraRotationAngle));
                    newSegments.applyMatrix(inversematrix);

                    result.AddRange(newSegments);
                }
            }
        }
예제 #2
0
        private static IEnumerable <IntPoint> StartPositionIterator(AABB boundary, int lineSpacing, int layerIndex)
        {
            int perIncrementOffset = (int)(lineSpacing * Math.Sqrt(3) / 2 + .5);
            int yLineCount         = (int)((boundary.max.Y - boundary.min.Y + perIncrementOffset) / perIncrementOffset) + 1;

            switch (layerIndex % 3)
            {
            case 0:                     // left to right
                for (int yIndex = 0; yIndex < yLineCount; yIndex++)
                {
                    long yPosition     = boundary.min.Y + yIndex * perIncrementOffset;
                    bool removeXOffset = ((yPosition / perIncrementOffset) % 2) == 0;
                    long xOffsetForY   = lineSpacing / 2;
                    if (removeXOffset)                             // if we are at every other y
                    {
                        xOffsetForY = 0;
                    }
                    long firstX = boundary.min.X + xOffsetForY;

                    yield return(new IntPoint(firstX, yPosition));
                }
                break;

            case 1:                     // left to top
            {
                IntPoint nextPoint = new IntPoint();
                for (int yIndex = yLineCount; yIndex >= 0; yIndex--)
                {
                    long yPosition         = boundary.min.Y + yIndex * perIncrementOffset;
                    bool createLineSegment = ((yPosition / perIncrementOffset) % 2) == 0;
                    if (createLineSegment)
                    {
                        nextPoint = new IntPoint(boundary.min.X, yPosition);
                        yield return(nextPoint);
                    }
                }

                IntPoint positionAdd = new IntPoint(lineSpacing, 0);
                nextPoint += positionAdd;
                while (nextPoint.X > boundary.min.X &&
                       nextPoint.X < boundary.max.X)
                {
                    yield return(nextPoint);

                    nextPoint += positionAdd;
                }
            }
            break;

            case 2:                     // top to right
            {
                IntPoint nextPoint = new IntPoint();
                for (int yIndex = 0; yIndex < yLineCount; yIndex++)
                {
                    long yPosition         = boundary.min.Y + yIndex * perIncrementOffset;
                    bool createLineSegment = ((yPosition / perIncrementOffset) % 2) == 0;
                    if (createLineSegment)
                    {
                        nextPoint = new IntPoint(boundary.min.X, yPosition);
                        yield return(nextPoint);
                    }
                }

                IntPoint positionAdd = new IntPoint(lineSpacing, 0);
                nextPoint += positionAdd;
                while (nextPoint.X > boundary.min.X &&
                       nextPoint.X < boundary.max.X)
                {
                    yield return(nextPoint);

                    nextPoint += positionAdd;
                }
            }
            break;
            }
        }
예제 #3
0
        private static IEnumerable <IntPoint> IncrementPositionIterator(IntPoint startPoint, AABB boundary, int lineSpacing, int layerIndex)
        {
            IntPoint positionAdd        = new IntPoint(lineSpacing, 0);
            int      perIncrementOffset = (int)(lineSpacing * Math.Sqrt(3) / 2 + .5);

            switch (layerIndex % 3)
            {
            case 0:                     // left to right
                positionAdd = new IntPoint(lineSpacing, 0);
                break;

            case 1:                     // left to top
                positionAdd = new IntPoint(lineSpacing / 2, perIncrementOffset);
                break;

            case 2:                     // top to right
                positionAdd = new IntPoint(lineSpacing / 2, -perIncrementOffset);
                break;
            }
            IntPoint nextPoint = startPoint;

            do
            {
                yield return(nextPoint);

                nextPoint += positionAdd;
            } while (nextPoint.X > boundary.min.X &&
                     nextPoint.X < boundary.max.X &&
                     nextPoint.Y > boundary.min.Y &&
                     nextPoint.Y < boundary.max.Y);
        }