public static void Render(string pointFilePath, Size?resolution) { using var points = PointStream.Load(pointFilePath); var viewPort = points.ViewPort; var actualResolution = resolution ?? points.ViewPort.Resolution; if (actualResolution != points.ViewPort.Resolution) { viewPort = new ViewPort(viewPort.Area, actualResolution); } var imageFilePath = pointFilePath + $".{actualResolution.Width}x{actualResolution.Height}.png"; using var timer = TimedOperation.Start("points", totalWork: actualResolution.Area()); var image = new FastImage(actualResolution); image.Fill(Color.White); Parallel.ForEach(points, point => { image.SetPixel(viewPort.GetPosition(point), Color.Black); timer.AddWorkDone(1); }); image.Save(imageFilePath); }
public static void RenderAllSpans(string edgeSpansPath, string imageFilePath, bool showDirections) { Log.Info($"Output image: {imageFilePath}"); if (showDirections) { Log.Info("Displaying span directions as well."); } using var spans = EdgeSpanStream.Load(edgeSpansPath); using var timer = TimedOperation.Start("edge spans", totalWork: showDirections?spans.Count * 2 : spans.Count); var scale = showDirections ? 3 : 1; var resolution = spans.ViewPort.Resolution.Scale(scale); var image = new FastImage(resolution); image.Fill(Color.White); Parallel.ForEach(spans, logicalSpan => { if (showDirections) { var scaledLocation = logicalSpan.Location.Scale(scale); for (int yDelta = 0; yDelta < 3; yDelta++) { for (int xDelta = 0; xDelta < 3; xDelta++) { image.SetPixel( scaledLocation.OffsetBy(xDelta, yDelta), (logicalSpan.Location.X + logicalSpan.Location.Y) % 2 == 1 ? Color.Black : Color.Gray); } } } else { image.SetPixel( logicalSpan.Location, Color.Black); } timer.AddWorkDone(1); }); if (showDirections) { Parallel.ForEach(spans, locatedSpan => { var scaledLocation = locatedSpan.Location.Scale(scale); var pointingTo = scaledLocation.OffsetBy(1, 1).OffsetIn(locatedSpan.ToOutside); image.SetPixel( pointingTo, Color.Red); timer.AddWorkDone(1); }); } image.Save(imageFilePath); }
public static void Export(MetaMap map, MapPalette palette, string outputFilePath, int scale = 1) { using var image = new FastImage(map.Width, map.Height, scale); for (var tileY = 0; tileY < map.Height; tileY++) { for (var tileX = 0; tileX < map.Width; tileX++) { var tileColor = palette.PickColor(map[tileX, tileY]); image.SetPixel(tileX, tileY, tileColor); } } image.Save(outputFilePath); }
public static void Render(string gridFilePath, string imageFilePath) { Log.Info($"Output image: {imageFilePath}"); using var grid = PointGrid.Load(gridFilePath); using var timer = TimedOperation.Start("points", totalWork: grid.ViewPort.Resolution.Area()); var image = new FastImage(grid.ViewPort.Resolution); image.Fill(Color.White); Parallel.ForEach(grid, row => { foreach (var setSegment in row.GetSegmentsInSet()) { foreach (var x in Enumerable.Range(setSegment.StartCol, setSegment.Length)) { image.SetPixel(x, row.Y, Color.Black); } } timer.AddWorkDone(grid.ViewPort.Resolution.Width); }); image.Save(imageFilePath); }
public static void RenderSingleSpan(string edgeSpansPath, int spanIndex, int sideResolution) { var resolution = new Size(sideResolution, sideResolution); using var spans = EdgeSpanStream.Load(edgeSpansPath); using var timer = TimedOperation.Start("points", totalWork: resolution.Area()); var random = new Random(); var index = spanIndex >= 0 ? spanIndex : random.Next(0, spans.Count); var imageFilePath = Path.Combine( Path.GetDirectoryName(edgeSpansPath) ?? throw new Exception($"Could not get directory name: {edgeSpansPath}"), Path.GetFileNameWithoutExtension(edgeSpansPath) + $"_{index}_{sideResolution}x{sideResolution}.png"); Log.Info($"Using edge span index {index:N0}"); Log.Info($"Output file: {imageFilePath}"); var span = spans.ElementAt(index).ToConcreteDouble(spans.ViewPort); var spanLength = span.Length(); Log.Info($"Edge span: {span} (length: {spanLength})"); var image = new FastImage(resolution); var viewPort = new ViewPort(GetArea(span), resolution); Log.Info($"View port: {viewPort}"); var positionInSet = viewPort.GetPosition(span.InSet); var positionNotInSet = viewPort.GetPosition(span.NotInSet); var highlightPixelRadius = resolution.Width / 100; var borderPoint = span.FindBoundaryPoint(Constant.IterationRange.Max); Log.Info($"Border point: {borderPoint} (escape time: {ScalarDoubleKernel.FindEscapeTime(borderPoint)})"); var borderPointPosition = viewPort.GetPosition(borderPoint); // TODO: Why is the inner loop parallelized? for (int row = 0; row < resolution.Height; row++) { Parallel.For(0, resolution.Width, col => { var position = new Point(col, row); var c = viewPort.GetComplex(position); Color PickColor() { if (position.DistanceSquaredFrom(positionInSet) <= highlightPixelRadius) { return(Color.Red); } if (position.DistanceSquaredFrom(positionNotInSet) <= highlightPixelRadius) { return(Color.ForestGreen); } if (position.DistanceSquaredFrom(borderPointPosition) <= highlightPixelRadius) { return(Color.Fuchsia); } var isInSet = ScalarDoubleKernel.FindEscapeTime(c, Constant.IterationRange.Max).IsInfinite; return(isInSet ? Color.FromArgb(0x20, 0x20, 0x20) : Color.White); } image.SetPixel(position, PickColor()); }); timer.AddWorkDone(resolution.Width); } image.Save(imageFilePath); }