public static void Mutate(this DnaBrush dnaBrush, DnaDrawing dnaDrawing) { if (Tools.WillMutate(Settings.ActiveRedMutationRate)) { dnaBrush.Red = Tools.GetRandomNumber(Settings.ActiveRedRangeMin, Settings.ActiveRedRangeMax); dnaDrawing.SetDirty(); } if (Tools.WillMutate(Settings.ActiveGreenMutationRate)) { dnaBrush.Green = Tools.GetRandomNumber(Settings.ActiveGreenRangeMin, Settings.ActiveGreenRangeMax); dnaDrawing.SetDirty(); } if (Tools.WillMutate(Settings.ActiveBlueMutationRate)) { dnaBrush.Blue = Tools.GetRandomNumber(Settings.ActiveBlueRangeMin, Settings.ActiveBlueRangeMax); dnaDrawing.SetDirty(); } if (Tools.WillMutate(Settings.ActiveAlphaMutationRate)) { dnaBrush.Alpha = Tools.GetRandomNumber(Settings.ActiveAlphaRangeMin, Settings.ActiveAlphaRangeMax); dnaDrawing.SetDirty(); } }
public static void Mutate(this DnaDrawing dnaDrawing) { if (Tools.WillMutate(Settings.ActiveAddPolygonMutationRate)) { if (dnaDrawing.AddPolygon()) { dnaDrawing.SetDirty(); } } if (Tools.WillMutate(Settings.ActiveRemovePolygonMutationRate)) { if (dnaDrawing.RemovePolygon()) { dnaDrawing.SetDirty(); } } if (Tools.WillMutate(Settings.ActiveMovePolygonMutationRate)) { if (dnaDrawing.MovePolygon()) { dnaDrawing.SetDirty(); } } foreach (DnaPolygon polygon in dnaDrawing.Polygons) { polygon.Mutate(dnaDrawing); } }
public double GetDrawingFitness(DnaDrawing newDrawing) { double error = 0; Renderer.Render(newDrawing, _g, 1); BitmapData bd = _bmp.LockBits( new Rectangle(0, 0, newDrawing.Width, newDrawing.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); unchecked { unsafe { fixed(Pixel *psourcePixels = _sourceImagePixels) { Pixel *p1 = (Pixel *)bd.Scan0.ToPointer(); Pixel *p2 = psourcePixels; for (int i = _sourceImagePixels.Length; i > 0; i--, p1++, p2++) { int r = p1->R - p2->R; int g = p1->G - p2->G; int b = p1->B - p2->B; error += r * r + g * g + b * b; } } } } _bmp.UnlockBits(bd); return(error); }
public static void Serialize(DnaDrawing drawing, string fileName) { if (fileName == null) { return; } if (fileName.EndsWith("xml")) { try { var serializer = new XmlSerializer(drawing.GetType()); using (var writer = new FileStream(fileName, FileMode.Create)) { serializer.Serialize(writer, drawing); } } catch (Exception) { } } else { SerializeBinary(drawing, fileName); } }
private static DnaDrawing GetNewInitializedDrawing(JobInfo info) { var drawing = new DnaDrawing(); drawing.Init(info); return(drawing); }
private void StartEvolution() { SetupSourceColorMatrix(); if (currentDrawing == null) { currentDrawing = GetNewInitializedDrawing(); } lastSelected = 0; const int numThreads = 16; var tasks = new Task <Tuple <DnaDrawing, double> > [numThreads]; while (isRunning) { for (var i = 0; i < numThreads; i++) { tasks[i] = Task.Factory.StartNew(() => Work(currentDrawing, sourceColors)); } Task.WaitAll(tasks); foreach (var task in tasks) { if (task.Result.Item1 == null || task.Result.Item2 > errorLevel) { continue; } selected++; currentDrawing = task.Result.Item1; errorLevel = task.Result.Item2; } generation++; } }
private void redraw() { guiDrawing = currentDrawing; pnlCanvas.Invalidate(); lastRepaint = DateTime.Now; lastSelected = currentEvolver.selected; }
//Render a Drawing public static void Render(DnaDrawing drawing,Graphics g,int scale) { g.Clear(Color.Black); foreach (DnaShape s in drawing.Shapes) s.Render(g, scale); }
private void WorkerThreadStart() { Initialize(); while (isRunning) { //assign current work data to a tmp var, so that we use the same data through the entire itteration //even if data is changed by the main thread, nothing will break or go wrong. WorkerData tmpData = data; if (tmpData.hasNewParent) { Tools.InitRandom(tmpData.randomSeed); tmpData.hasNewParent = false; } DnaDrawing newDrawing = GetMutatedSeedSyncedDrawing(); double newErrorLevel = FitnessCalculator.GetDrawingFitness(newDrawing, info.SourceImage, partitionY, partitionHeight); var result = new DnaPartitionResult { Drawing = newDrawing, ErrorLevel = newErrorLevel, }; tmpData.workerTail.Enqueue(result); } }
private DnaDrawing GetMutatedSeedSyncedDrawing() { DnaDrawing newDrawing = parentDrawing.Clone(); newDrawing.Mutate(info); return(newDrawing); }
private static DnaDrawing GetNewInitializedDrawing() { var drawing = new DnaDrawing(); drawing.Init(); // HAKKAB for loobis Settings.cs-is sätestatud minimaalselt arvu Polügoone lisama return(drawing); }
public double GetNextErrorLevel() { var drawing = new DnaDrawing(); drawing.SourceImage = sourceImage; drawing.Polygons = new List <DnaPolygon>(); int i = 0; foreach (LayeredWorker worker in workers) { i++; if (i == 1) { continue; } DnaDrawing workerDrawing = worker.GetDrawing(); drawing.Polygons.AddRange(workerDrawing.Clone().Polygons); //drawing = worker.GetDrawing(); } currentDrawing = drawing; currentErrorLevel = FitnessCalculator.GetDrawingFitness(drawing, sourceImage); return(currentErrorLevel); }
public double GetDrawingFitness(DnaDrawing newDrawing) { double error = 0; using (var b = new Bitmap(newDrawing.Width, newDrawing.Height, PixelFormat.Format24bppRgb)) using (Graphics g = Graphics.FromImage(b)) { Renderer.Render(newDrawing, g, 1); BitmapData bmd1 = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); for (int y = 0; y < b.Height; y++) { for (int x = 0; x < b.Width; x++) { Color c1 = GetPixel(bmd1, x, y); Color c2 = _sourceColors[x, y]; double pixelError = GetColorFitness(c1, c2); error += pixelError; } } b.UnlockBits(bmd1); } return(error); }
public static void Mutate(this DnaBrush dnaBrush, DnaDrawing dnaDrawing) { if (Tools.WillMutate(Settings.ActiveRedMutationRate)) { dnaBrush.Red = Tools.GetRandomNumber(Settings.ActiveRedRangeMin, Settings.ActiveRedRangeMax); dnaDrawing.SetDirty(); } if (Tools.WillMutate(Settings.ActiveGreenMutationRate)) { dnaBrush.Green = Tools.GetRandomNumber(Settings.ActiveGreenRangeMin, Settings.ActiveGreenRangeMax); dnaDrawing.SetDirty(); } if (Tools.WillMutate(Settings.ActiveBlueMutationRate)) { dnaBrush.Blue = Tools.GetRandomNumber(Settings.ActiveBlueRangeMin, Settings.ActiveBlueRangeMax); dnaDrawing.SetDirty(); } if (Tools.WillMutate(Settings.ActiveAlphaMutationRate)) { dnaBrush.Alpha = Tools.GetRandomNumber(Settings.ActiveAlphaRangeMin, Settings.ActiveAlphaRangeMax); dnaDrawing.SetDirty(); } }
public static double GetDrawingFitness(DnaDrawing newDrawing, Color[,] sourceColors) { double error = 0; { Renderer.Render(newDrawing, g, 1); BitmapData bmd1 = b.LockBits(new Rectangle(0, 0, Tools.MaxWidth, Tools.MaxHeight), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); for (int y = 0; y < Tools.MaxHeight; y++) { for (int x = 0; x < Tools.MaxWidth; x++) { Color c1 = GetPixel(bmd1, x, y); Color c2 = sourceColors[x, y]; double pixelError = GetColorFitness(c1, c2); error += pixelError; } } b.UnlockBits(bmd1); } return(error); }
private static DnaDrawing GetNewInitializedDrawing(Settings settings) { var drawing = new DnaDrawing(); drawing.Init(settings); return(drawing); }
internal static long GetDrawingFitness(DnaDrawing newDrawing, SourceImage sourceImage, Bitmap bgImage, Bitmap fgImage) { long error = 0; if (bmp == null) { bmp = new Bitmap(sourceImage.Width, sourceImage.Height, PixelFormat.Format32bppArgb); g = Graphics.FromImage(bmp); } if (bgImage != null) { g.DrawImage(bgImage, 0, 0); } else { g.Clear(Color.Black); } Renderer.Render(newDrawing, g, 1); if (fgImage != null) { g.DrawImage(fgImage, 0, 0); } BitmapData bd = bmp.LockBits( new Rectangle(0, 0, sourceImage.Width, sourceImage.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); unchecked { unsafe { fixed(Pixel *psourcePixels = sourceImage.Pixels) { int partitionEnd = sourceImage.Height * sourceImage.Width; var p1 = (Pixel *)bd.Scan0.ToPointer(); Pixel *p2 = psourcePixels; for (int i = 0; i < partitionEnd; i++, p1++, p2++) { int R = p1->R - p2->R; int G = p1->G - p2->G; int B = p1->B - p2->B; error += R * R + G * G + B * B; } } } } bmp.UnlockBits(bd); // error += newDrawing.Polygons.Count * 3 ; return(error); }
//Render a Drawing internal static void Render(DnaDrawing drawing, Graphics g, int scale) { for (int i = 0; i < drawing.Polygons.Count; i++) { DnaPolygon polygon = drawing.Polygons[i]; Render(polygon, g, scale); } }
//Render a Drawing public static void Render(DnaDrawing drawing, Graphics g, int scale) { g.Clear(Color.Black); foreach (DnaPolygon polygon in drawing.Polygons) { Render(polygon, g, scale); } }
public void Init() { Drawing = new DnaDrawing(); Drawing.Init(); Settings = new Settings(); ErrorLevel = double.MaxValue; LastSavedFitness = double.MaxValue; }
public void Init() { Drawing = new DnaDrawing(); Drawing.Init(); Settings = new Settings(); ErrorLevel = double.MaxValue; LastSavedFitness = double.MaxValue; }
private void Initialize() { Tools.InitRandom(data.randomSeed); parentDrawing = new DnaDrawing { Polygons = new List <DnaPolygon>(), }; }
//Render a Drawing public static void Render(DnaDrawing drawing, Graphics g, int scale) { g.Clear(Color.Black); foreach (DnaShape s in drawing.Shapes) { s.Render(g, scale); } }
public static bool RemovePolygon(this DnaDrawing dnaDrawing) { if (dnaDrawing.Polygons.Count > Settings.ActivePolygonsMin) { int index = Tools.GetRandomNumber(0, dnaDrawing.Polygons.Count); dnaDrawing.Polygons.RemoveAt(index); return(true); } return(false); }
internal WorkerInstance(int randomSeed, JobInfo info) { this.randomSeed = randomSeed; this.info = info; info.InitRandom(randomSeed); parentDrawing = new DnaDrawing { Polygons = new List <DnaPolygon>(), }; }
private static void SaveDnaDrawingToFile(string fileName, DnaDrawing drawing) { DnaDrawing clone; clone = drawing.Clone(); if (clone != null) { Serializer.Serialize(clone, fileName); } }
private void Redraw() { lock (currentDrawing) { guiDrawing = currentDrawing.Clone(); } pnlCanvas.Invalidate(); lastRepaint = DateTime.Now; lastSelected = selected; }
public override void Mutate(DnaDrawing drawing) { if (tool.WillMutate(Settings.ActiveCircleWidthMutationRate)) { rx = ry = mutateScalar(rx, 0, Settings.ActiveMaxCircleRadius, drawing); } Brush.Mutate(drawing); MutateOrigin(drawing); }
public static Bitmap RenderToBitmap(DnaDrawing drawing, int scale) { var bitmap = new Bitmap(Tools.MaxWidth * scale, Tools.MaxHeight * scale, PixelFormat.Format32bppArgb); using (Graphics g = Graphics.FromImage(bitmap)) { Render(drawing, g, scale); } return(bitmap); }
// private void StartEvolution() // { // double errorLevelAtLastSave = double.MaxValue; // Bitmap sourceBitmap = GetSourceBitmap(); // // if (currentCandidate == null) // { // currentCandidate = new Candidate(); // } // lastSelected = 0; // // while (isRunning) // { // var newCandidiate = new Candidate(currentCandidate); // newCandidiate.Drawing.Mutate(); // // if (newCandidiate.Drawing.IsDirty) // { // generation++; // // newCandidiate.CalculateErrorLevel(sourceBitmap); // // if (newCandidiate.ErrorLevel <= currentCandidate.ErrorLevel) // { // selected++; // // lock (currentCandidate) // { // currentCandidate = newCandidiate; // } // // // double percentChange = (errorLevelAtLastSave - newCandidiate.ErrorLevel) / // errorLevelAtLastSave; // if (percentChange > 0.005) // { // SaveImageToFile(newCandidiate.Drawing); // // errorLevelAtLastSave = newCandidiate.ErrorLevel; // // TimeSpan totalTime = DateTime.Now - startTime; // double generationsPerSec = generation/totalTime.TotalSeconds; // int polygons = currentCandidate.Drawing.Polygons.Count; // int points = currentCandidate.Drawing.PointCount; // double pointsPerPolygon = 0; // if (polygons != 0) // pointsPerPolygon = (double)points / polygons; // // // Trace.WriteLine(string.Format( // "{0:yyyy-MM-dd HH:mm:ss} {1,15} {2,15} {3,9:0.0} {4,9} {5,9} {6,9:0.0}", // DateTime.Now, errorLevelAtLastSave, generation, generationsPerSec, points, polygons, pointsPerPolygon)); // } // // } // } // //else, discard new drawing // } // } private void SaveImageToFile(DnaDrawing drawing) { const string filenameFormat = @"F:\Temp\EvoLisaRender\EvoLisa-{0:000000000}.png"; const int scale = 3; string filename = string.Format(filenameFormat, sequence++); using (Bitmap buffer = Renderer.RenderToBitmap(drawing, scale)) { buffer.Save(filename, ImageFormat.Png); } }
public static bool AddPolygon(this DnaDrawing dnaDrawing) { if (dnaDrawing.Polygons.Count < Settings.ActivePolygonsMax) { var newPolygon = DnaPolygon.GetRandom(dnaDrawing.Width, dnaDrawing.Height); int index = Tools.GetRandomNumber(0, dnaDrawing.Polygons.Count); dnaDrawing.Polygons.Insert(index, newPolygon); return(true); } return(false); }
private void tmrRedraw_Tick(object sender, EventArgs e) { if (currentDrawing == null) { return; } int polygons = currentDrawing.Polygons.Count; int points = currentDrawing.PointCount; double avg = 0; if (polygons != 0) { avg = points / polygons; } toolStripStatusLabelFitness.Text = errorLevel.ToString(); toolStripStatusLabelGeneration.Text = generation.ToString(); toolStripStatusLabelSelected.Text = selected.ToString(); toolStripStatusLabelPoints.Text = points.ToString(); toolStripStatusLabelPolygons.Text = polygons.ToString(); toolStripStatusLabelAvgPoints.Text = avg.ToString(); bool shouldRepaint = false; if (repaintIntervall.Ticks > 0) { if (lastRepaint < DateTime.Now - repaintIntervall) { shouldRepaint = true; } } if (repaintOnSelectedSteps > 0) { if (lastSelected + repaintOnSelectedSteps < selected) { shouldRepaint = true; } } if (shouldRepaint) { lock (currentDrawing) { guiDrawing = currentDrawing.Clone(); } pnlCanvas.Invalidate(); lastRepaint = DateTime.Now; lastSelected = selected; } }
private void OpenDNA() { Stop(); DnaDrawing drawing = Serializer.DeserializeDnaDrawing(FileUtil.GetOpenFileName(FileUtil.DnaExtension)); if (drawing != null) { currentCandidate = new Candidate(drawing); pnlCanvas.Invalidate(); lastRepaint = DateTime.Now; } }
private void OpenDNA() { _evolutionEngine.Stop(); string openFileName = FileUtil.GetOpenFileName(FileUtil.DnaExtension); if (_evolutionEngine.OpenDNA(openFileName)) { guiDrawing = _evolutionEngine.GetGuiDrawing(); pnlCanvas.Invalidate(); lastRepaint = DateTime.Now; } }
private static bool RemovePoint(this DnaPolygon dnaPolygon, DnaDrawing drawing) { if (dnaPolygon.Points.Count > Settings.ActivePointsPerPolygonMin) { if (drawing.PointCount > Settings.ActivePointsMin) { int index = Tools.GetRandomNumber(0, dnaPolygon.Points.Count); dnaPolygon.Points.RemoveAt(index); return true; } } return false; }
public static void Mutate(this DnaPoint dnaPoint, DnaDrawing dnaDrawing) { if (Tools.WillMutate(Settings.ActiveMovePointMaxMutationRate)) { dnaPoint.X = Tools.GetRandomNumber(0, dnaDrawing.Width); dnaPoint.Y = Tools.GetRandomNumber(0, dnaDrawing.Height); dnaDrawing.SetDirty(); } if (Tools.WillMutate(Settings.ActiveMovePointMidMutationRate)) { dnaPoint.X = MathUtils.Clamp( dnaPoint.X + Tools.GetRandomNumber(-Settings.ActiveMovePointRangeMid, Settings.ActiveMovePointRangeMid), 0, dnaDrawing.Width); dnaPoint.Y = MathUtils.Clamp( dnaPoint.Y + Tools.GetRandomNumber(-Settings.ActiveMovePointRangeMid, Settings.ActiveMovePointRangeMid), 0, dnaDrawing.Height); dnaDrawing.SetDirty(); } if (Tools.WillMutate(Settings.ActiveMovePointMinMutationRate)) { dnaPoint.X = MathUtils.Clamp( dnaPoint.X + Tools.GetRandomNumber(-Settings.ActiveMovePointRangeMin, Settings.ActiveMovePointRangeMin), 0, dnaDrawing.Width); dnaPoint.Y = MathUtils.Clamp( dnaPoint.Y + Tools.GetRandomNumber(-Settings.ActiveMovePointRangeMin, Settings.ActiveMovePointRangeMin), 0, dnaDrawing.Height); dnaDrawing.SetDirty(); } }
public static void Mutate(this DnaPolygon dnaPolygon, DnaDrawing drawing) { if (Tools.WillMutate(Settings.ActiveAddPointMutationRate)) { if (dnaPolygon.AddPoint(drawing)) { drawing.SetDirty(); } } if (Tools.WillMutate(Settings.ActiveRemovePointMutationRate)) { if (dnaPolygon.RemovePoint(drawing)) { drawing.SetDirty(); } } dnaPolygon.Brush.Mutate(drawing); dnaPolygon.Points.ForEach(p => p.Mutate(drawing)); }
private static bool AddPoint(this DnaPolygon dnaPolygon, DnaDrawing drawing) { if (dnaPolygon.Points.Count < Settings.ActivePointsPerPolygonMax) { if (drawing.PointCount < Settings.ActivePointsMax) { int index = Tools.GetRandomNumber(1, dnaPolygon.Points.Count - 1); DnaPoint prev = dnaPolygon.Points[index - 1]; DnaPoint next = dnaPolygon.Points[index]; var newPointX = (prev.X + next.X)/2; var newPointY = (prev.Y + next.Y)/2; var newPoint = new DnaPoint(newPointX, newPointY); dnaPolygon.Points.Insert(index, newPoint); return true; } } return false; }
public virtual void Mutate(DnaDrawing drawing) { Console.WriteLine("Mutating Ellipse"); if (tool.WillMutate(Settings.ActiveCircleWidthMutationRate)) { rx = mutateScalar(rx, 0, Settings.ActiveMaxCircleRadius, drawing); } if (tool.WillMutate(Settings.ActiveCircleHeightMutationRate)) { ry = mutateScalar(ry, 0, Settings.ActiveMaxCircleRadius, drawing); } if (tool.WillMutate(Settings.ActiveRotationMutationRate)) { rotation = mutateScalar(rotation, -999.0, 999.0, drawing); } Brush.Mutate(drawing); MutateOrigin(drawing); }
public double mutateScalar(double scalar, double min, double max, DnaDrawing drawing) { if (tool.WillMutate(Settings.ActiveCircleSizeMidMutationRate)) { drawing.SetDirty(); return Math.Min(Math.Max(min, scalar + tool.GetRandomNumber(-Settings.ActiveCircleSizeRangeMid, Settings.ActiveCircleSizeRangeMid)), max); } if (tool.WillMutate(Settings.ActiveCircleSizeMinMutationRate)) { drawing.SetDirty(); return Math.Min(Math.Max(min, scalar + tool.GetRandomNumber(-Settings.ActiveCircleSizeRangeMin, Settings.ActiveCircleSizeRangeMin)), max); } return scalar; }
public void MutateOrigin(DnaDrawing drawing) { if (tool.WillMutate(Settings.ActiveMovePointMaxMutationRate)) { origin.X = tool.GetRandomNumber(-Settings.ActiveMaxCircleRadius, Tools.MaxWidth + Settings.ActiveMaxCircleRadius); origin.Y = tool.GetRandomNumber(-Settings.ActiveMaxCircleRadius, Tools.MaxHeight + Settings.ActiveMaxCircleRadius); drawing.SetDirty(); } if (tool.WillMutate(Settings.ActiveMovePointMidMutationRate)) { origin.X = Math.Min( Math.Max(-Settings.ActiveMaxCircleRadius, origin.X + tool.GetRandomNumber(-Settings.ActiveMovePointRangeMid, Settings.ActiveMovePointRangeMid)), Tools.MaxWidth + Settings.ActiveMaxCircleRadius); origin.Y = Math.Min( Math.Max(-Settings.ActiveMaxCircleRadius, origin.Y + tool.GetRandomNumber(-Settings.ActiveMovePointRangeMid, Settings.ActiveMovePointRangeMid)), Tools.MaxHeight + Settings.ActiveMaxCircleRadius); drawing.SetDirty(); } if (tool.WillMutate(Settings.ActiveMovePointMinMutationRate)) { origin.X = Math.Min( Math.Max(-Settings.ActiveMaxCircleRadius, origin.X + tool.GetRandomNumber(-Settings.ActiveMovePointRangeMin, Settings.ActiveMovePointRangeMin)), Tools.MaxWidth + Settings.ActiveMaxCircleRadius); origin.Y = Math.Min( Math.Max(-Settings.ActiveMaxCircleRadius, origin.Y + tool.GetRandomNumber(-Settings.ActiveMovePointRangeMin, Settings.ActiveMovePointRangeMin)), Tools.MaxHeight + Settings.ActiveMaxCircleRadius); drawing.SetDirty(); } }
private void RemovePoint(DnaDrawing drawing) { if (Points.Count > Settings.ActivePointsPerPolygonMin) { int index = tool.GetRandomNumber(0, Points.Count); Points.RemoveAt(index); drawing.SetDirty(); } }
private void AddPoint(DnaDrawing drawing) { if (Points.Count < Settings.ActivePointsPerPolygonMax) { var newPoint = new DnaPoint(); int index = tool.GetRandomNumber(1, Points.Count - 1); DnaPoint prev = Points[index - 1]; DnaPoint next = Points[index]; newPoint.X = (prev.X + next.X)/2; newPoint.Y = (prev.Y + next.Y)/2; Points.Insert(index, newPoint); drawing.SetDirty(); } }
public void breed(DnaDrawing other) { lock (this) { lock (other) { shuffleShapes(); other.shuffleShapes(); List<DnaShape> otherFirst = other.firstHalf; List<DnaShape> otherSnd = other.secondHalf; List<DnaShape> thisFirst = firstHalf; List<DnaShape> thisSnd = secondHalf; otherFirst.AddRange(thisSnd); thisFirst.AddRange(otherSnd); Shapes = thisFirst; other.Shapes = otherFirst; } } }
public DnaDrawing Clone() { lock (this) { var drawing = new DnaDrawing(seed); drawing.tool = tool; drawing.Shapes = new List<DnaShape>(); foreach (DnaShape shape in Shapes) drawing.Shapes.Add(shape.Clone()); return drawing; } }
public new void Mutate(DnaDrawing drawing) { Brush.Mutate(drawing); MutateOrigin(drawing); }
public void Mutate(DnaDrawing drawing) { if (tool.WillMutate(Settings.ActiveAddPointMutationRate)) AddPoint(drawing); if (tool.WillMutate(Settings.ActiveRemovePointMutationRate)) RemovePoint(drawing); Brush.Mutate(drawing); Points.ForEach(p => p.Mutate(drawing)); }