| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- using System;
- using System.Collections.Generic;
- using System.Drawing;
- using System.IO;
- using System.Linq;
- namespace D6.Bonus
- {
- class Program
- {
- static void Main(string[] args)
- {
- if (args.Length < 2) return;
- if (File.Exists(args[0]) == false) return;
- if (int.TryParse(args[1], out int ceil) == false) return;
- var coordinates = new List<((uint x, uint y) coord, bool isInfinite)>();
- var file = File.OpenText(args[0]);
- uint minXY = int.MaxValue;
- uint maxXY = 0;
- do
- {
- var line = file.ReadLine();
- if (line == null) break;
- var cl = line.Split(", ");
- (uint x, uint y) xy = (uint.Parse(cl[0]), uint.Parse(cl[1]));
- if (xy.x < minXY) minXY = xy.x;
- if (xy.y < minXY) minXY = xy.y;
- if (xy.x > maxXY) maxXY = xy.x;
- if (xy.y > maxXY) maxXY = xy.y;
- coordinates.Add((xy, false));
- } while (true);
- uint size = minXY + maxXY;
- var area = new (int closest, int total)[size, size];
- FillMapArea(size, coordinates, area);
- FlagPointOnEdges(size, coordinates);
- GenerateBitMap(ceil, coordinates, size, area);
- }
- private static void GenerateBitMap(int ceil, List<((uint x, uint y) coord, bool isInfinite)> coordinates, uint size, (int closest, int total)[,] area)
- {
- var bmp = new Bitmap((int)size, (int)size);
- Random r = new Random();
- Dictionary<int, Color> Colors = new Dictionary<int, Color>();
- for (var x = 0; x < size; x++)
- {
- for (var y = 0; y < size; y++)
- {
- var id = area[x, y].closest;
- var total = area[x, y].total;
- if (Colors.ContainsKey(id) == false)
- Colors.Add(id, Color.FromArgb(coordinates.ElementAt(id).isInfinite ? 20 : 255, r.Next(0, 256), r.Next(0, 256), r.Next(0, 256)));
- if (coordinates.ElementAt(id).isInfinite && (x + y % 3) % 3 > 0) continue;
- bmp.SetPixel(x, y, Colors[id]);
- var c = bmp.GetPixel(x, y);
- if (total < ceil) bmp.SetPixel(x, y, Color.FromArgb((int)((c.R + 127) / 1.5), (int)((c.G + 127) / 1.5), (int)((c.B + 127) / 1.5)));
- }
- }
- foreach (var coord in coordinates)
- {
- int x = (int)coord.coord.x;
- int y = (int)coord.coord.y;
- bmp.SetPixel(x, y, Color.Red);
- bmp.SetPixel(x - 1, y, Color.Red);
- bmp.SetPixel(x + 1, y, Color.Red);
- bmp.SetPixel(x, y - 1, Color.Red);
- bmp.SetPixel(x, y + 1, Color.Red);
- bmp.SetPixel(x - 1, y - 1, Color.DarkRed);
- bmp.SetPixel(x + 1, y - 1, Color.DarkRed);
- bmp.SetPixel(x - 1, y + 1, Color.DarkRed);
- bmp.SetPixel(x + 1, y + 1, Color.DarkRed);
- }
- bmp = new Bitmap(bmp, new Size((int)(size * 2), (int)(size * 2)));
- bmp.Save("result.bmp");
- }
- private static void FlagPointOnEdges(uint size, List<((uint x, uint y) coord, bool isInfinite)> coordinates)
- {
- for (uint i = 0; i < size; ++i)
- {
- #pragma warning disable IDE0042 // Deconstruct variable declaration
- var x0yi = GetClosest(coordinates, (0, i));
- MarkInfinite(coordinates, x0yi.closest);
- var xiy0 = GetClosest(coordinates, (i, 0));
- MarkInfinite(coordinates, xiy0.closest);
- var xsizeyi = GetClosest(coordinates, (size, i));
- MarkInfinite(coordinates, xsizeyi.closest);
- var xiysize = GetClosest(coordinates, (i, size));
- MarkInfinite(coordinates, xiysize.closest);
- #pragma warning restore IDE0042 // Deconstruct variable declaration
- }
- }
- private static void FillMapArea(uint size, List<((uint x, uint y) coord, bool isInfinite)> coordinates, (int closest, int total)[,] area)
- {
- for (uint x = 0; x < size; x++)
- {
- for (uint y = 0; y < size; y++)
- {
- var closest = GetClosest(coordinates, (x, y));
- area[x,y] = closest;
- }
- }
- }
- private static (int closest, int total) GetClosest(List<((uint x, uint y) coord, bool isInfinite)> coordinates, (uint x, uint y) point)
- {
- int total = 0;
- int lowest = int.MaxValue;
- int lowestId = 0;
- for (int i = 0; i < coordinates.Count; i++)
- {
- var (x, y) = coordinates[i].coord;
- var manhattan = Math.Abs((int)point.x - (int)x) + Math.Abs((int)point.y - (int)y);
- if (manhattan < lowest)
- {
- lowest = manhattan;
- lowestId = i;
- }
- total += manhattan;
- }
- return (lowestId, total);
- }
- private static void MarkInfinite(List<((uint x, uint y) coord, bool isInfinite)> coordinates, int id)
- {
- var coord = coordinates[id];
- coord.isInfinite = true;
- coordinates[id] = coord;
- }
- }
- }
|