示例#1
0
        public Bitmap DrawMazeOrdered(T structure, DrawingParameters parameters, IEnumerable <Cell> order)
        {
            if (!parameters.strokeEnabled && !parameters.fillEnabled)
            {
                return(null);
            }

            var    size   = CalculateBitmapSize(structure, parameters);
            Bitmap bitmap = new Bitmap(size.width, size.height);

            using (Graphics graphics = Graphics.FromImage(bitmap))
            {
                graphics.CompositingQuality = CompositingQuality.HighQuality;
                graphics.SmoothingMode      = SmoothingMode.HighQuality;
                graphics.PixelOffsetMode    = PixelOffsetMode.HighQuality;

                if (parameters.fillEnabled)
                {
                    FillMaze(graphics, structure, parameters, order);
                }

                if (parameters.strokeEnabled)
                {
                    StrokeMaze(graphics, structure, parameters);
                }
            }

            return(bitmap);
        }
示例#2
0
        protected override (int width, int height) CalculateBitmapSize(CircularStructure structure,
                                                                       DrawingParameters parameters)
        {
            int diameter =
                (int)((structure.parameters.rings * 2 + 1) * parameters.cellSize + 2 * parameters.strokeWidth);

            return(diameter, diameter);
        }
        protected override (int width, int height) CalculateBitmapSize(RectangularStructure structure,
                                                                       DrawingParameters parameters)
        {
            int width  = (int)(structure.parameters.width * parameters.cellSize + parameters.strokeWidth * 2);
            int height = (int)(structure.parameters.height * parameters.cellSize + parameters.strokeWidth * 2);

            return(width, height);
        }
示例#4
0
        protected override (int width, int height) CalculateBitmapSize(ShapedStructure structure,
                                                                       DrawingParameters parameters)
        {
            int width  = (int)(structure.parameters.shape.Width * parameters.cellSize);
            int height = (int)(structure.parameters.shape.Height * parameters.cellSize);

            return(width, height);
        }
        protected override void StrokeMaze(Graphics graphics,
                                           RectangularStructure structure,
                                           DrawingParameters parameters)
        {
            graphics.TranslateTransform(parameters.strokeWidth, parameters.strokeWidth);

            float width      = structure.parameters.width;
            float height     = structure.parameters.height;
            float drawWidth  = parameters.cellSize;
            float drawHeight = parameters.cellSize;

            Pen pen = new Pen(parameters.strokeColor, parameters.strokeWidth);

            pen.StartCap = LineCap.Round;
            pen.EndCap   = LineCap.Round;

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    PointF p1 = new PointF(x * drawWidth, y * drawHeight);
                    PointF p2 = new PointF((x + 1) * drawWidth, y * drawHeight);
                    PointF p3 = new PointF((x + 1) * drawWidth, (y + 1) * drawHeight);
                    PointF p4 = new PointF(x * drawWidth, (y + 1) * drawHeight);

                    Cell curCell = structure.GetCellAtPosition(new RectangularPosition(x, y));

                    if (!structure.ContainsCellAtPosition(new RectangularPosition(x - 1, y)))
                    {
                        graphics.DrawLine(pen, p1, p4);
                    }

                    if (!structure.ContainsCellAtPosition(new RectangularPosition(x, y - 1)))
                    {
                        graphics.DrawLine(pen, p1, p2);
                    }

                    if (!structure.ContainsCellAtPosition(new RectangularPosition(x + 1, y)) ||
                        !structure.IsAdjacent(curCell,
                                              structure.GetCellAtPosition(new RectangularPosition(x + 1, y))))
                    {
                        graphics.DrawLine(pen, p2, p3);
                    }

                    if (!structure.ContainsCellAtPosition(new RectangularPosition(x, y + 1)) ||
                        !structure.IsAdjacent(curCell,
                                              structure.GetCellAtPosition(new RectangularPosition(x, y + 1))))
                    {
                        graphics.DrawLine(pen, p3, p4);
                    }
                }
            }

            graphics.ResetTransform();
        }
        protected override void FillMaze(Graphics graphics,
                                         RectangularStructure structure,
                                         DrawingParameters parameters,
                                         IEnumerable <Cell> order)
        {
            graphics.TranslateTransform(parameters.strokeWidth, parameters.strokeWidth);

            float drawWidth  = parameters.cellSize;
            float drawHeight = parameters.cellSize;

            int   i     = 0;
            int   count = order.Count();
            Brush brush = new SolidBrush(parameters.fillColor);

            foreach (Cell cell in order)
            {
                if (parameters.fillType == FillType.GenerationGradient)
                {
                    brush = new SolidBrush(Helpers.Lerp(Color.Black, parameters.fillColor, (float)i / count));
                }

                RectangularPosition pos = cell.Position as RectangularPosition;
                int x = pos.x;
                int y = pos.y;

                PointF p1 = new PointF(x * drawWidth, y * drawHeight);
                PointF p2 = new PointF((x + 1) * drawWidth, y * drawHeight);
                PointF p3 = new PointF((x + 1) * drawWidth, (y + 1) * drawHeight);
                PointF p4 = new PointF(x * drawWidth, (y + 1) * drawHeight);

                GraphicsPath bounds = new GraphicsPath();
                bounds.AddLine(p1, p2);
                bounds.AddLine(p2, p3);
                bounds.AddLine(p3, p4);
                bounds.AddLine(p4, p1);

                graphics.FillPath(brush, bounds);

                i++;
            }

            graphics.ResetTransform();
        }
示例#7
0
        protected override void StrokeMaze(Graphics graphics, CircularStructure structure, DrawingParameters parameters)
        {
            float translate = parameters.strokeWidth
                              + structure.parameters.rings * parameters.cellSize
                              + parameters.cellSize * 0.5f;

            graphics.TranslateTransform(translate, translate);

            float ringHeight    = parameters.cellSize;
            float halfHeight    = ringHeight * 0.5f;
            int   prevRingCount = 1;

            Pen pen = new Pen(parameters.strokeColor, parameters.strokeWidth);

            pen.StartCap = LineCap.Round;
            pen.EndCap   = LineCap.Round;

            for (int x = 1; x <= structure.parameters.rings; x++)
            {
                int cellsNumber = CircularFunctions.CellsInRing(x, structure.parameters.ratio, prevRingCount);

                for (int y = 0; y < cellsNumber; y++)
                {
                    Brush brush = new SolidBrush(parameters.fillColor);

                    var polarSideA = CircularFunctions.CircularPositionToPolar(x, y, ringHeight, cellsNumber);
                    var polarSideB = CircularFunctions.CircularPositionToPolar(x, y + 1, ringHeight, cellsNumber);

                    float innerSize = (x * ringHeight - halfHeight);
                    float outerSize = (x * ringHeight + halfHeight);

                    var t1 = CircularFunctions.PolarToCartesian(innerSize, polarSideA.angle);
                    var t2 = CircularFunctions.PolarToCartesian(outerSize, polarSideA.angle);
                    var t3 = CircularFunctions.PolarToCartesian(outerSize, polarSideB.angle);
                    var t4 = CircularFunctions.PolarToCartesian(innerSize, polarSideB.angle);

                    RectangleF inner = new RectangleF(-innerSize, -innerSize, innerSize * 2, innerSize * 2);
                    RectangleF outer = new RectangleF(-outerSize, -outerSize, outerSize * 2, outerSize * 2);

                    float sweep = CircularFunctions.RadToDeg(polarSideB.angle)
                                  - CircularFunctions.RadToDeg(polarSideA.angle);

                    Cell curCell = structure.GetCellAtPosition(new CircularPosition(x, y));

                    foreach (Cell neighbourCell in curCell.NeighbourCells)
                    {
                        CircularPosition neighborPosition = neighbourCell.Position as CircularPosition;

                        if (neighborPosition.ring == (x - 1) && !structure.IsAdjacent(curCell, neighbourCell))
                        {
                            graphics.DrawArc(pen, inner, CircularFunctions.RadToDeg(polarSideB.angle), -sweep);
                        }

                        if ((neighborPosition.step == (y + 1) || y == (cellsNumber - 1) && neighborPosition.step == 0) &&
                            !structure.IsAdjacent(curCell, neighbourCell))
                        {
                            graphics.DrawLine(pen, t3.x, t3.y, t4.x, t4.y);
                        }
                    }

                    if (x == structure.parameters.rings)
                    {
                        graphics.DrawArc(pen, outer, CircularFunctions.RadToDeg(polarSideA.angle), sweep);
                    }
                }

                prevRingCount = cellsNumber;
            }

            graphics.ResetTransform();
        }
示例#8
0
        protected override void FillMaze(Graphics graphics,
                                         CircularStructure structure,
                                         DrawingParameters parameters,
                                         IEnumerable <Cell> order)
        {
            float translate = parameters.strokeWidth
                              + structure.parameters.rings * parameters.cellSize
                              + parameters.cellSize * 0.5f;

            graphics.TranslateTransform(translate, translate);

            float ringHeight    = parameters.cellSize;
            float halfHeight    = ringHeight * 0.5f;
            int   prevRingCount = 1;

            int   i     = 0;
            int   count = order.Count();
            Brush brush = new SolidBrush(parameters.fillColor);

            foreach (Cell cell in order)
            {
                if (parameters.fillType == FillType.GenerationGradient)
                {
                    brush = new SolidBrush(Helpers.Lerp(Color.Black, parameters.fillColor, (float)i / count));
                }

                CircularPosition pos = cell.Position as CircularPosition;
                int x = pos.ring;
                int y = pos.step;

                if (x == 0)
                {
                    graphics.FillEllipse(brush, -halfHeight, -halfHeight, ringHeight, ringHeight);

                    continue;
                }

                int cellsInRing = CircularFunctions.CellsInRing(x, structure.parameters.ratio);

                var polarSideA = CircularFunctions.CircularPositionToPolar(x, y, ringHeight, cellsInRing);
                var polarSideB = CircularFunctions.CircularPositionToPolar(x, y + 1, ringHeight, cellsInRing);

                float innerSize = (x * ringHeight - halfHeight);
                float outerSize = (x * ringHeight + halfHeight);

                var t1 = CircularFunctions.PolarToCartesian(innerSize, polarSideA.angle);
                var t2 = CircularFunctions.PolarToCartesian(outerSize, polarSideA.angle);
                var t3 = CircularFunctions.PolarToCartesian(outerSize, polarSideB.angle);
                var t4 = CircularFunctions.PolarToCartesian(innerSize, polarSideB.angle);

                RectangleF inner = new RectangleF(-innerSize, -innerSize, innerSize * 2, innerSize * 2);
                RectangleF outer = new RectangleF(-outerSize, -outerSize, outerSize * 2, outerSize * 2);

                float sweep = CircularFunctions.RadToDeg(polarSideB.angle)
                              - CircularFunctions.RadToDeg(polarSideA.angle);

                GraphicsPath bounds = new GraphicsPath();
                bounds.AddLine(t1.Item1, t1.Item2, t2.Item1, t2.Item2);
                bounds.AddArc(outer, CircularFunctions.RadToDeg(polarSideA.angle), sweep);
                bounds.AddLine(t3.Item1, t3.Item2, t4.Item1, t4.Item2);
                bounds.AddArc(inner, CircularFunctions.RadToDeg(polarSideB.angle), -sweep);
                bounds.CloseFigure();

                graphics.FillPath(brush, bounds);

                i++;
            }

            graphics.ResetTransform();
        }
示例#9
0
 public Bitmap DrawMaze(T structure, DrawingParameters parameters)
 {
     return(DrawMazeOrdered(structure, parameters, structure));
 }
示例#10
0
 protected abstract (int width, int height) CalculateBitmapSize(T structure, DrawingParameters parameters);
示例#11
0
 protected abstract void StrokeMaze(Graphics graphics, T structure, DrawingParameters parameters);
示例#12
0
 protected abstract void FillMaze(Graphics graphics,
                                  T structure,
                                  DrawingParameters parameters,
                                  IEnumerable <Cell> order);