Exemple #1
0
        private static (int x, int y) GetCellCenter(HexMaze maze, Cell cell, int halfHeight, int xOffset)
        {
            var(row, column) = maze.GetPositionOfCell(cell);
            var centerX = (column * (CornerRadius - xOffset) * 2) + (CornerRadius / 2) + Margin;
            var centerY = (row * halfHeight * 2) + halfHeight + Margin;

            if (column % 2 == 1)
            {
                centerY += halfHeight;
            }

            return(centerX, centerY);
        }
Exemple #2
0
        public static SKImage RenderWithSkia(this HexMaze maze,
                                             RenderOptions renderOptions,
                                             DistanceInfo distanceInfo,
                                             ShortestPathInfo shortestPathInfo)
        {
            if (maze == null)
            {
                throw new ArgumentNullException(nameof(maze));
            }

            renderOptions = renderOptions ?? new RenderOptions();

            var rightCorner       = GetCoords(CornerRadius, 0);
            var bottomRightCorner = GetCoords(CornerRadius, 60);
            var bottomLeftCorner  = GetCoords(CornerRadius, 120);
            var leftCorner        = GetCoords(CornerRadius, 180);
            var topLeftCorner     = GetCoords(CornerRadius, 240);
            var topRightCorner    = GetCoords(CornerRadius, 300);

            var halfHeight = (int)Math.Abs(topRightCorner.y);
            var xOffset    = (int)(Math.Cos(30) * (halfHeight * 2));

            var imageWidth  = ((CornerRadius - xOffset) * 2 * maze.ColumnCount) + (Margin * 2);
            var imageHeight = (halfHeight * 2 * maze.RowCount) + (Margin * 2) + halfHeight;
            var imageInfo   = new SKImageInfo(imageWidth, imageHeight, SKColorType.Rgba8888, SKAlphaType.Premul);

            using (var surface = SKSurface.Create(imageInfo))
            {
                surface.Canvas.Clear(SKColors.Black);

                var whitePaint = new SKPaint {
                    Color = SKColors.White, StrokeWidth = CellLineWidth, TextAlign = SKTextAlign.Center
                };
                var startPaint = new SKPaint {
                    Color = SKColors.Green, StrokeWidth = 1, TextAlign = SKTextAlign.Center
                };
                var finishPaint = new SKPaint {
                    Color = SKColors.Red, StrokeWidth = 1, TextAlign = SKTextAlign.Center
                };
                var pathPaint = new SKPaint {
                    Color = SKColors.Yellow, StrokeWidth = 1, TextAlign = SKTextAlign.Center
                };

                foreach (var cell in maze.AllCells)
                {
                    var cellCenter = GetCellCenter(maze, cell, halfHeight, xOffset);

                    var corners = new[]
                    {
                        new SKPoint(rightCorner.x + cellCenter.x, rightCorner.y + cellCenter.y),
                        new SKPoint(bottomRightCorner.x + cellCenter.x, bottomRightCorner.y + cellCenter.y),
                        new SKPoint(bottomLeftCorner.x + cellCenter.x, bottomLeftCorner.y + cellCenter.y),
                        new SKPoint(leftCorner.x + cellCenter.x, leftCorner.y + cellCenter.y),
                        new SKPoint(topLeftCorner.x + cellCenter.x, topLeftCorner.y + cellCenter.y),
                        new SKPoint(topRightCorner.x + cellCenter.x, topRightCorner.y + cellCenter.y),
                    };

                    // All walls starting from bottom right and going clockwise
                    var isWallOpen = new[] { false, false, false, false, false, false };
                    foreach (var cellWall in cell.CellWalls)
                    {
                        if (cellWall.IsPassable)
                        {
                            var otherCellCenter = GetCellCenter(maze, cellWall.GetOtherCell(cell), halfHeight, xOffset);
                            var angle           = GetNormalizedDegreesToCell(cellCenter, otherCellCenter);
                            var index           = angle / 60;
                            isWallOpen[index] = true;
                        }
                    }

                    if (renderOptions.ShowGradientOfDistanceFromStart)
                    {
                        var finishingCellDistance = distanceInfo.DistanceFromStartMap[distanceInfo.FarthestCell];
                        var currentCellDistance   = distanceInfo.DistanceFromStartMap[cell];
                        var intensity             = (byte)(255 * (currentCellDistance / (decimal)finishingCellDistance));
                        var color = new SKColor(0, 0, intensity);
                        var paint = new SKPaint {
                            Color = color, Style = SKPaintStyle.Fill
                        };

                        var path = new SKPath();
                        path.MoveTo(corners[0]);
                        path.LineTo(corners[1]);
                        path.LineTo(corners[2]);
                        path.LineTo(corners[3]);
                        path.LineTo(corners[4]);
                        path.LineTo(corners[5]);
                        path.LineTo(corners[0]);

                        surface.Canvas.DrawPath(path, paint);
                    }

                    for (var x = 0; x < isWallOpen.Length; x++)
                    {
                        if (!isWallOpen[x])
                        {
                            var first  = corners[x];
                            var second = corners[x < 5 ? x + 1 : 0];
                            surface.Canvas.DrawLine(first, second, whitePaint);
                        }
                    }

                    if (renderOptions.HighlightShortestPath && shortestPathInfo.IsCellInPath(cell))
                    {
                        var paint = cell == maze.StartingCell ? startPaint
                            : cell == maze.FinishingCell ? finishPaint
                            : pathPaint;

                        var distance = distanceInfo.DistanceFromStartMap[cell];
                        surface.Canvas.DrawText(distance.ToString(), cellCenter.x, cellCenter.y + halfHeight / 2, paint);
                    }
                    else if (renderOptions.ShowAllDistances && distanceInfo.DistanceFromStartMap.ContainsKey(cell))
                    {
                        var distance = distanceInfo.DistanceFromStartMap[cell];
                        surface.Canvas.DrawText(distance.ToString(), cellCenter.x, cellCenter.y + halfHeight / 2, whitePaint);
                    }
                    else if (cell == maze.StartingCell)
                    {
                        surface.Canvas.DrawText("S", cellCenter.x, cellCenter.y + halfHeight / 2, startPaint);
                    }
                    else if (cell == maze.FinishingCell)
                    {
                        surface.Canvas.DrawText("E", cellCenter.x, cellCenter.y + halfHeight / 2, finishPaint);
                    }
                }

                return(surface.Snapshot());
            }
        }