// ****************************************************************** public void RemoveColor(Color c) { for (var n = UsedColors.Count - 1; n >= 0; n--) { if (UsedColors[n].Color == c) { UsedColors.RemoveAt(n); } } }
private int GetColorID(Color color) { int colorID; bool keyFound; keyFound = UsedColors.TryGetValue(color.ToArgb(), out colorID); if (!keyFound) { colorID = (++_colorIdCounter); UsedColors.Add(color.ToArgb(), colorID); } return(colorID); }
// ****************************************************************** public Color GetNextColor() { while (true) { double hue = _random.NextDouble() * 360; double saturation; double luminance; // To go quicker and darker for white background // saturation = Math.Sqrt(_random.NextDouble()) ; // luminance = Math.Sqrt(_random.NextDouble()); // To go quicker and lighter for dark background //saturation = Math.Pow(_random.NextDouble(), 2.0); //luminance = Math.Pow(_random.NextDouble(), 2.0); // Less performance but higher compatibility saturation = _random.NextDouble(); luminance = _random.NextDouble(); HSL hsl = new HSL(hue, saturation, luminance); Color c = hsl.ToColor(); if (IsFarEnoughFromExistingColor(c, DistanceMin)) { UsedColors.Add(new ColorRatio(c)); DistanceMin += .02; _badTryCount = 0; return(c); } _badTryCount++; if (_badTryCount > Accuracy) { _badTryCount = 0; DistanceMin -= .002; } } }
// TODO: make this whole thing a coroutine? public override void OnUpdate(float realTimeDelta, float simulationTimeDelta) { TransportManager theTransportManager; SimulationManager theSimulationManager; TransportLine[] lines; try { //Digest changes if (_config.UndigestedChanges) { Logger.Message("Applying undigested changes"); _colorStrategy = SetColorStrategy(_config.ColorStrategy); _namingStrategy = SetNamingStrategy(_config.NamingStrategy); _config.UndigestedChanges = false; } if (_initialized == false) { return; } // try and limit how often we are scanning for lines. this ain't that important if (_nextUpdateTime >= DateTimeOffset.Now) { return; } if (!Singleton <TransportManager> .exists || !Singleton <SimulationManager> .exists) { return; } theTransportManager = Singleton <TransportManager> .instance; theSimulationManager = Singleton <SimulationManager> .instance; lines = theTransportManager.m_lines.m_buffer; } catch (Exception ex) { Logger.Error(ex.ToString()); return; } if (theSimulationManager.SimulationPaused) { return; } var locked = false; try { _nextUpdateTime = DateTimeOffset.Now.AddSeconds(Constants.UpdateIntervalSeconds); locked = Monitor.TryEnter(lines, SimulationManager.SYNCHRONIZE_TIMEOUT); if (!locked) { return; } _usedColors = UsedColors.FromLines(lines); for (ushort i = 0; i < lines.Length - 1; i++) { ProcessLine(i, lines[i], false, theSimulationManager, theTransportManager); } } catch (Exception ex) { Logger.Error(ex.ToString()); } finally { if (locked) { Monitor.Exit(lines); } } }
public void Analyze() { Region reg; // Temprory object Bitmap inputBmp; Color currentPixelColor; CPoint currentPixel; // Current pixel location (in Input Image coordinate) // Initialize this.Output = null; Pixels = new Pixel[Input.Width, Input.Height]; currentPixel = new CPoint(); inputBmp = (Bitmap)Input; _colorIdCounter = 0; Regions.Clear(); UsedColors.Clear(); Region.ResetIdCounter(); this.AnalyzeCanceled = false; this.AnalyzeException = null; #region Fast Algorithm //try { // // Initialize // Pixels = new Pixel[Input.Width, Input.Height]; // currentPixel = new CPoint(); // inputBmp = (Bitmap)Input; // _colorIdCounter = 0; // Regions.Clear(); // UsedColors.Clear(); // Region.ResetIdCounter(); // this.AnalyzeCanceled = false; // this.AnalyzeException = null; // for (int y = 0; y < Input.Height; y++) { // for (int x = 0; x < Input.Width; x++) { // Pixels[x, y] = new Pixel(); // reg = new Region(); // Pixels[x, y].Color = inputBmp.GetPixel(x, y); // reg.ColorID = GetColorID(Pixels[x, y].Color); // Pixels[x, y].Region = reg; // } // } //} //catch (Exception e) { // AnalyzeException = e; // this.Pixels = null; // this.UsedColors = null; // this.Output = null; // GC.Collect(); // return; //} #endregion #region Complete Algorithm try { #region Scan First Row // Scan inputBmp[0, 0] reg = new Region(); currentPixel.X = 0; currentPixel.Y = 0; Pixels[0, 0] = new Pixel(); Pixels[0, 0].Region = reg; Pixels[0, 0].Color = inputBmp.GetPixel(0, 0); reg.ColorID = GetColorID(Pixels[0, 0].Color); reg.Boundaries = new Rectangle(0, 0, 1, 1); reg.GeometricSum = new Point(0, 0); reg.Pixels.Add(currentPixel); Regions.Add(reg); // Scan Pixel [1...Input.Width-1] of First Row // reg = null; for (int x = 1; x < Input.Width; x++) { currentPixel = new CPoint(); currentPixel.X = x; currentPixel.Y = 0; currentPixelColor = inputBmp.GetPixel(x, 0); if (currentPixelColor == Pixels[x - 1, 0].Color) { // Add this pixel to it's left neighbor's region reg = Pixels[x - 1, 0].Region; reg.Pixels.Add(currentPixel); reg.Boundaries.Width += 1; // reg.GeometricSum.Y = 0; // No need to set. it has already set to zero } else { // Create a new Region for currentPixel reg = new Region(GetColorID(currentPixelColor), new Rectangle(x, 0, 1, 1)); reg.Pixels.Add(currentPixel); Regions.Add(reg); } reg.GeometricSum.X += currentPixel.X; reg.GeometricSum.Y += currentPixel.Y; Pixels[x, 0] = new Pixel(); Pixels[x, 0].Color = currentPixelColor; Pixels[x, 0].Region = reg; } #endregion #region Scan Rest of Image // reg = null; for (int y = 1; (y < Input.Height) && (_continueAnalyze); y++) { #region Scan First Pixel of Current Row currentPixel = new CPoint(); currentPixel.X = 0; currentPixel.Y = y; currentPixelColor = inputBmp.GetPixel(0, y); if (currentPixelColor == Pixels[0, currentPixel.Y - 1].Color) { reg = Pixels[0, currentPixel.Y - 1].Region; reg.Boundaries.Height++; } else if (currentPixelColor == Pixels[1, currentPixel.Y - 1].Color) { reg = Pixels[1, currentPixel.Y - 1].Region; reg.Boundaries = Rectangle.Union(reg.Boundaries, new Rectangle(currentPixel.X, currentPixel.Y, 1, 1)); } else { reg = new Region(GetColorID(currentPixelColor), new Rectangle(0, currentPixel.Y, 1, 1)); Regions.Add(reg); } //reg.GeometricSum.X += currentPixel.X; reg.GeometricSum.Y += currentPixel.Y; reg.Pixels.Add(currentPixel); Pixels[0, currentPixel.Y] = new Pixel(); Pixels[0, currentPixel.Y].Region = reg; Pixels[0, currentPixel.Y].Color = currentPixelColor; #endregion #region Scan Inner Pixels of Current Row for (int x = 1; x < Input.Width - 1; x++) { currentPixel = new CPoint(); currentPixel.X = x; currentPixel.Y = y; currentPixelColor = inputBmp.GetPixel(x, y); if (currentPixelColor == Pixels[x - 1, currentPixel.Y].Color) { reg = Pixels[x - 1, currentPixel.Y].Region; } else if (currentPixelColor == Pixels[x - 1, currentPixel.Y - 1].Color) { reg = Pixels[x - 1, currentPixel.Y - 1].Region; } else if (currentPixelColor == Pixels[x, currentPixel.Y - 1].Color) { reg = Pixels[x, currentPixel.Y - 1].Region; } else if (currentPixelColor == Pixels[x + 1, currentPixel.Y - 1].Color) { reg = Pixels[x + 1, currentPixel.Y - 1].Region; } else { // Create a new region reg = new Region(); reg.ColorID = GetColorID(currentPixelColor); reg.Boundaries = new Rectangle(currentPixel.X, currentPixel.Y, 1, 1); Regions.Add(reg); } reg.GeometricSum.X += currentPixel.X; reg.GeometricSum.Y += currentPixel.Y; reg.Boundaries = Rectangle.Union(reg.Boundaries, new Rectangle(currentPixel.X, currentPixel.Y, 1, 1)); reg.Pixels.Add(currentPixel); Pixels[currentPixel.X, currentPixel.Y] = new Pixel(); Pixels[currentPixel.X, currentPixel.Y].Region = reg; Pixels[currentPixel.X, currentPixel.Y].Color = currentPixelColor; // Merge Regions with same color if ((currentPixelColor == Pixels[x - 1, currentPixel.Y - 1].Color) && (currentPixelColor == Pixels[x + 1, currentPixel.Y - 1].Color) && (Pixels[x - 1, currentPixel.Y - 1].Region.ID != Pixels[x + 1, currentPixel.Y - 1].Region.ID)) { Regions.Remove(Pixels[x + 1, currentPixel.Y - 1].Region); Pixels[x - 1, currentPixel.Y - 1].Region.Merge(Pixels[x + 1, currentPixel.Y - 1].Region, Pixels); } if ((currentPixelColor == Pixels[x - 1, currentPixel.Y].Color) && (currentPixelColor == Pixels[x + 1, currentPixel.Y - 1].Color) && (Pixels[x - 1, currentPixel.Y].Region.ID != Pixels[x + 1, currentPixel.Y - 1].Region.ID)) { Regions.Remove(Pixels[x + 1, currentPixel.Y - 1].Region); Pixels[x - 1, currentPixel.Y].Region.Merge(Pixels[x + 1, currentPixel.Y - 1].Region, Pixels); } } #endregion #region Scan Last Pixel of Current Row currentPixel = new CPoint(); currentPixel.X = Input.Width - 1; currentPixel.Y = y; currentPixelColor = inputBmp.GetPixel(currentPixel.X, currentPixel.Y); if (currentPixelColor == Pixels[currentPixel.X - 1, currentPixel.Y].Color) { reg = Pixels[currentPixel.X - 1, currentPixel.Y].Region; } else if (currentPixelColor == Pixels[currentPixel.X - 1, currentPixel.Y - 1].Color) { reg = Pixels[currentPixel.X - 1, currentPixel.Y - 1].Region; } else if (currentPixelColor == Pixels[currentPixel.X, currentPixel.Y - 1].Color) { reg = Pixels[currentPixel.X, currentPixel.Y - 1].Region; } else { reg = new Region(GetColorID(currentPixelColor), new Rectangle(currentPixel.X, currentPixel.Y, 1, 1)); Regions.Add(reg); } reg.GeometricSum.X += currentPixel.X; reg.GeometricSum.Y += currentPixel.Y; reg.Boundaries = Rectangle.Union(reg.Boundaries, new Rectangle(currentPixel.X, currentPixel.Y, 1, 1)); reg.Pixels.Add(currentPixel); Pixels[currentPixel.X, currentPixel.Y] = new Pixel(); Pixels[currentPixel.X, currentPixel.Y].Region = reg; Pixels[currentPixel.X, currentPixel.Y].Color = currentPixelColor; #endregion } #endregion } catch (Exception e) { AnalyzeException = e; this.Pixels = null; this.UsedColors = null; this.Output = null; GC.Collect(); return; } #endregion // Produce Output Image if (_continueAnalyze) { RedrawOutput(); } else { // Operations canceled, Reset object _continueAnalyze = true; this.AnalyzeCanceled = true; } }