public TaskState( NBTag tag ) { if( FormatVersion != tag["FormatVersion"].GetInt() ) throw new FormatException( "Incompatible format." ); Shapes = tag["Shapes"].GetInt(); Vertices = tag["Vertices"].GetInt(); ImprovementCounter = tag["ImprovementCounter"].GetInt(); MutationCounter = tag["MutationCounter"].GetInt(); TaskStart = DateTime.UtcNow.Subtract( TimeSpan.FromTicks( tag["ElapsedTime"].GetLong() ) ); ProjectOptions = new ProjectOptions( tag["ProjectOptions"] ); BestMatch = new DNA( tag["BestMatch"] ); CurrentMatch = BestMatch; Initializer = (IInitializer)ModuleManager.ReadModule( tag["Initializer"] ); Mutator = (IMutator)ModuleManager.ReadModule( tag["Mutator"] ); Evaluator = (IEvaluator)ModuleManager.ReadModule( tag["Evaluator"] ); byte[] imageBytes = tag["ImageData"].GetBytes(); using( MemoryStream ms = new MemoryStream( imageBytes ) ) { OriginalImage = new Bitmap( ms ); } var statsTag = (NBTList)tag["MutationStats"]; foreach( NBTag stat in statsTag ) { MutationType mutationType = (MutationType)Enum.Parse( typeof( MutationType ), stat["Type"].GetString() ); MutationCounts[mutationType] = stat["Count"].GetInt(); MutationImprovements[mutationType] = stat["Sum"].GetDouble(); } }
public DNA(DNA other) { Shapes = new Shape[other.Shapes.Length]; for (int i = 0; i < Shapes.Length; i++) { Shapes[i] = new Shape(other.Shapes[i]); } Divergence = other.Divergence; }
DNA IMutator.Mutate( Random rand, DNA oldDNA, TaskState task ) { DNA newDNA = new DNA( oldDNA ); if( rand.Next( 20 ) == 0 ) { newDNA.SwapShapes( rand ); } else { MutateShape( rand, newDNA, newDNA.Shapes[rand.Next( newDNA.Shapes.Length )], task ); } return newDNA; }
static void MutateShape( Random rand, DNA dna, Shape shape, TaskState task ) { int maxOverlap = task.ProjectOptions.MaxOverlap; shape.PreviousState = shape.Clone() as Shape; switch( rand.Next( 9 ) ) { case 0: shape.Color = Color.FromArgb( (byte)rand.Next( task.ProjectOptions.MinAlpha, 256 ), shape.Color.R, shape.Color.G, shape.Color.B ); dna.LastMutation = MutationType.ReplaceColor; break; case 1: shape.Color = Color.FromArgb( shape.Color.A, (byte)rand.Next( 256 ), shape.Color.G, shape.Color.B ); dna.LastMutation = MutationType.ReplaceColor; break; case 2: shape.Color = Color.FromArgb( shape.Color.A, shape.Color.R, (byte)rand.Next( 256 ), shape.Color.B ); dna.LastMutation = MutationType.ReplaceColor; break; case 3: shape.Color = Color.FromArgb( shape.Color.A, shape.Color.R, shape.Color.G, (byte)rand.Next( 256 ) ); dna.LastMutation = MutationType.ReplaceColor; break; case 4: case 5: shape.Points[rand.Next( shape.Points.Length )].X = rand.NextFloat( -maxOverlap, task.ImageWidth + maxOverlap ); dna.LastMutation = MutationType.ReplacePoint; break; case 6: case 7: shape.Points[rand.Next( shape.Points.Length )].Y = rand.NextFloat( -maxOverlap, task.ImageHeight + maxOverlap ); dna.LastMutation = MutationType.ReplacePoint; break; case 8: shape.Points[rand.Next( shape.Points.Length )].X = rand.NextFloat( -maxOverlap, task.ImageWidth + maxOverlap ); shape.Points[rand.Next( shape.Points.Length )].Y = rand.NextFloat( -maxOverlap, task.ImageHeight + maxOverlap ); dna.LastMutation = MutationType.ReplacePoints; break; } }
public DNA Mutate( Random rand, DNA oldDNA, TaskState task ) { DNA newDNA = new DNA( oldDNA ); int s1 = rand.Next( newDNA.Shapes.Length ); Shape shape = newDNA.Shapes[s1]; switch( rand.Next( 20 ) ) { case 0: newDNA.SwapShapes( rand ); break; case 1: RandomizeShape( rand, shape, task ); newDNA.LastMutation = MutationType.ReplaceShape; break; default: MutateShape( rand, newDNA, shape, task ); break; } return newDNA; }
public DNA Initialize( Random rand, TaskState task ) { DNA dna = new DNA { Shapes = new Shape[task.Shapes] }; int shapesPerSegment = task.Shapes / 9; int shapeCounter = 0; for( int i = 0; i < task.Shapes - shapesPerSegment * 9; i++ ) { Shape shape = new Shape { Color = Color.FromArgb( StartingAlpha, Color.R, Color.G, Color.B ), Points = new PointF[task.Vertices] }; for( int j = 0; j < shape.Points.Length; j++ ) { shape.Points[j] = new PointF( rand.NextFloat( -MaxOverlap, task.ImageWidth + MaxOverlap ), rand.NextFloat( -MaxOverlap, task.ImageHeight + MaxOverlap ) ); } dna.Shapes[i] = shape; shapeCounter++; } for( int x = 0; x < 3; x++ ) { for( int y = 0; y < 3; y++ ) { for( int i = 0; i < shapesPerSegment; i++ ) { Shape shape = new Shape { Color = Color.FromArgb( StartingAlpha, Color.R, Color.G, Color.B ), Points = new PointF[task.Vertices] }; for( int j = 0; j < shape.Points.Length; j++ ) { shape.Points[j] = new PointF( rand.NextFloat( task.ImageWidth / 3f * x - MaxOverlap, task.ImageWidth / 3f * ( x + 1 ) + MaxOverlap ), rand.NextFloat( task.ImageHeight / 3f * y - MaxOverlap, task.ImageHeight / 3f * ( y + 1 ) + MaxOverlap ) ); } dna.Shapes[shapeCounter] = shape; shapeCounter++; } } } return dna; }
public DNA Mutate( Random rand, DNA oldDNA, TaskState task ) { int maxOverlap = task.ProjectOptions.MaxOverlap; DNA newDNA = new DNA( oldDNA ); Shape shape = newDNA.Shapes[rand.Next( newDNA.Shapes.Length )]; shape.PreviousState = shape.Clone() as Shape; shape.Color = Color.FromArgb( rand.Next( task.ProjectOptions.MinAlpha, 256 ), rand.NextByte(), rand.NextByte(), rand.NextByte() ); double area, maxArea = MaxPolygonArea * task.ImageWidth * task.ImageHeight; do { for( int i = 0; i < shape.Points.Length; i++ ) { shape.Points[i] = new PointF( rand.NextFloat( -maxOverlap, task.ImageWidth + maxOverlap ), rand.NextFloat( -maxOverlap, task.ImageHeight + maxOverlap ) ); } area = CalculateArea( shape.Points ); } while( area > maxArea ); newDNA.LastMutation = MutationType.ReplaceShape; return newDNA; }
public static ShapeEvaluation[] SortShapes(TaskState state) { var results = new List<ShapeEvaluation>(); using (var testCanvas = new Bitmap(state.ImageWidth, state.ImageHeight)) { double baseDivergence = state.Evaluator.CalculateDivergence(testCanvas, state.BestMatch, state, 1); for (int i = 0; i < state.BestMatch.Shapes.Length; i++) { var dnaWithoutShape = new DNA(state.BestMatch); dnaWithoutShape.Shapes[i].Color = Color.Transparent; double diffDivergence = state.Evaluator.CalculateDivergence(testCanvas, dnaWithoutShape, state, 1); results.Add(new ShapeEvaluation { Ordinal = i, Divergence = diffDivergence - baseDivergence, Shape = state.BestMatch.Shapes[i] }); } } results.Sort((r1, r2) => Math.Sign(r2.Divergence - r1.Divergence)); return results.ToArray(); }
static PointF MutatePoint( Random rand, DNA dna, PointF point, TaskState task ) { int maxOverlap = task.ProjectOptions.MaxOverlap; switch( rand.Next( 5 ) ) { case 0: case 1: point.X = rand.NextFloat( -maxOverlap, task.ImageWidth + maxOverlap ); dna.LastMutation = MutationType.ReplacePoint; break; case 2: case 3: point.Y = rand.NextFloat( -maxOverlap, task.ImageHeight + maxOverlap ); dna.LastMutation = MutationType.ReplacePoint; break; case 4: point.X = rand.NextFloat( -maxOverlap, task.ImageWidth + maxOverlap ); point.Y = rand.NextFloat( -maxOverlap, task.ImageHeight + maxOverlap ); dna.LastMutation = MutationType.ReplacePoints; break; } return point; }
public Mutation( DNA previousDna, DNA newDna ) { PreviousDNA = previousDna; NewDNA = newDna; Timestamp = DateTime.UtcNow; }
public double CalculateDivergence( Bitmap testImage, DNA dna, TaskState state, double maxAcceptableDivergence ) { if( Emphasized ) { if( EmphasisAmount == 2 ) { maxDivergence = 3L * state.ImageWidth * state.ImageHeight * 255L * 255L; } else { maxDivergence = 3L * state.ImageWidth * state.ImageHeight * Math.Pow( 255, EmphasisAmount ); } } else { maxDivergence = 3L * state.ImageWidth * state.ImageHeight * 255L; } double sum = 0; double roundedMax = ( maxAcceptableDivergence * maxDivergence + 1 ); using( Graphics g = Graphics.FromImage( testImage ) ) { g.Clear( state.ProjectOptions.Matte ); g.SmoothingMode = ( Smooth ? SmoothingMode.HighQuality : SmoothingMode.HighSpeed ); for( int i = 0; i < dna.Shapes.Length; i++ ) { g.FillPolygon( new SolidBrush( dna.Shapes[i].Color ), dna.Shapes[i].Points, FillMode.Alternate ); } } byte* originalPointer, testPointer; BitmapData testData = testImage.LockBits( new Rectangle( Point.Empty, testImage.Size ), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb ); if( Emphasized ) { if( EmphasisAmount == 2 ) { for( int i = 0; i < state.ImageHeight; i++ ) { originalPointer = (byte*)state.WorkingImageData.Scan0 + state.WorkingImageData.Stride * i; testPointer = (byte*)testData.Scan0 + testData.Stride * i; for( int j = 0; j < state.ImageWidth; j++ ) { int b = Math.Abs( *originalPointer - *testPointer ); int g = Math.Abs( originalPointer[1] - testPointer[1] ); int r = Math.Abs( originalPointer[2] - testPointer[2] ); sum += r * r + b * b + g * g; originalPointer += 4; testPointer += 4; } if( sum > roundedMax ) { sum = maxDivergence; break; } } } else { for( int i = 0; i < state.ImageHeight; i++ ) { originalPointer = (byte*)state.WorkingImageData.Scan0 + state.WorkingImageData.Stride*i; testPointer = (byte*)testData.Scan0 + testData.Stride*i; for( int j = 0; j < state.ImageWidth; j++ ) { int b = Math.Abs( *originalPointer - *testPointer ); int g = Math.Abs( originalPointer[1] - testPointer[1] ); int r = Math.Abs( originalPointer[2] - testPointer[2] ); sum += Math.Pow( r, EmphasisAmount ) + Math.Pow( g, EmphasisAmount ) + Math.Pow( b, EmphasisAmount ); originalPointer += 4; testPointer += 4; } if( sum > roundedMax ) { sum = maxDivergence; break; } } } } else { for( int i = 0; i < state.ImageHeight; i++ ) { originalPointer = (byte*)state.WorkingImageData.Scan0 + state.WorkingImageData.Stride * i; testPointer = (byte*)testData.Scan0 + testData.Stride * i; for( int j = 0; j < state.ImageWidth; j++ ) { int b = Math.Abs( *originalPointer - *testPointer ); int g = Math.Abs( originalPointer[1] - testPointer[1] ); int r = Math.Abs( originalPointer[2] - testPointer[2] ); sum += r + b + g; originalPointer += 4; testPointer += 4; } if( sum > roundedMax ) { sum = maxDivergence; break; } } } testImage.UnlockBits( testData ); if( Emphasized ) { return Math.Pow( sum / maxDivergence, 1 / EmphasisAmount ); } else { return sum / maxDivergence; } }
void MutateShape( Random rand, DNA dna, Shape shape, TaskState task ) { shape.PreviousState = shape.Clone() as Shape; switch( rand.Next( 10 ) ) { case 0: shape.Color = Color.FromArgb( (byte)rand.Next( task.ProjectOptions.MinAlpha, 256 ), shape.Color.R, shape.Color.G, shape.Color.B ); dna.LastMutation = MutationType.ReplaceColor; if( rand.Next( 10 ) == 0 ) { MutateMultiplePoints( shape, rand, dna, task ); dna.LastMutation = MutationType.ReplaceShape; } break; case 1: shape.Color = Color.FromArgb( shape.Color.A, rand.NextByte(), shape.Color.G, shape.Color.B ); dna.LastMutation = MutationType.ReplaceColor; if( rand.Next( 10 ) == 0 ) { MutateMultiplePoints( shape, rand, dna, task ); dna.LastMutation = MutationType.ReplaceShape; } break; case 2: shape.Color = Color.FromArgb( shape.Color.A, shape.Color.R, rand.NextByte(), shape.Color.B ); dna.LastMutation = MutationType.ReplaceColor; if( rand.Next( 10 ) == 0 ) { MutateMultiplePoints( shape, rand, dna, task ); dna.LastMutation = MutationType.ReplaceShape; } break; case 3: shape.Color = Color.FromArgb( shape.Color.A, shape.Color.R, shape.Color.G, rand.NextByte() ); dna.LastMutation = MutationType.ReplaceColor; if( rand.Next( 10 ) == 0 ) { MutateMultiplePoints( shape, rand, dna, task ); dna.LastMutation = MutationType.ReplaceShape; } break; default: MutateMultiplePoints( shape, rand, dna, task ); break; } }
void MutateMultiplePoints( Shape shape, Random rand, DNA dna, TaskState task ) { int index = rand.Next( shape.Points.Length ); shape.Points[index] = MutatePoint( rand, dna, shape.Points[index], task ); if( rand.Next( 2 ) == 0 ) { index = ( index + 1 ) % shape.Points.Length; shape.Points[index] = MutatePoint( rand, dna, shape.Points[index], task ); if( rand.Next( 2 ) == 0 ) { index = ( index + 1 ) % shape.Points.Length; shape.Points[index] = MutatePoint( rand, dna, shape.Points[index], task ); } dna.LastMutation = MutationType.ReplacePoints; } else { dna.LastMutation = MutationType.ReplacePoint; } }
void Run() { Random rand = new Random(); Bitmap testCanvas = new Bitmap(State.ImageWidth, State.ImageHeight); while (!stopped) { Interlocked.Increment(ref State.MutationCounter); DNA mutation = State.Mutator.Mutate(rand, State.CurrentMatch, State); bool takeRisk = (rand.NextDouble() < State.ProjectOptions.RiskRate * State.CurrentMatch.Divergence); double riskMargin = -(State.CurrentMatch.Divergence * State.CurrentMatch.Divergence) * State.ProjectOptions.RiskMargin; if (!takeRisk) { riskMargin = 0; } mutation.Divergence = State.Evaluator.CalculateDivergence(testCanvas, mutation, State, State.CurrentMatch.Divergence - riskMargin); if (Math.Abs(mutation.Divergence - 1) < float.Epsilon) { continue; } double improvement = State.CurrentMatch.Divergence - mutation.Divergence; if (improvement > 0 || takeRisk && (improvement > riskMargin)) { lock (State.ImprovementLock) { riskMargin = -(State.CurrentMatch.Divergence * State.CurrentMatch.Divergence) * State.ProjectOptions.RiskMargin; if (!takeRisk) { riskMargin = 0; } mutation.Divergence = State.Evaluator.CalculateDivergence(testCanvas, mutation, State, 1); improvement = State.CurrentMatch.Divergence - mutation.Divergence; if (improvement > 0 || takeRisk && (improvement > riskMargin)) { if (improvement <= 0) { if (State.BestMatch.Divergence < State.CurrentMatch.Divergence) { State.FailedRiskCounter++; mutation = State.BestMatch; } else { State.RiskyMoveCounter++; } } else { State.MutationCounts[mutation.LastMutation]++; State.MutationImprovements[mutation.LastMutation] += improvement; } State.MutationDataLog.Add(new PointF { X = (float)DateTime.UtcNow.Subtract(State.TaskStart).TotalSeconds, Y = (float)mutation.Divergence }); State.CurrentMatch = mutation; if (mutation.Divergence < State.BestMatch.Divergence) { State.BestMatch = mutation; State.LastImprovementTime = DateTime.UtcNow; State.LastImprovementMutationCount = State.MutationCounter; State.ImprovementCounter++; State.HasChangedSinceSave = true; } picBestMatch.Invalidate(); picDiff.Invalidate(); graphWindow1.SetData(State.MutationDataLog, false, true, false, false, true, true); } } AutoSave(); } } }
PointF MutatePoint( Random rand, DNA dna, PointF point, TaskState task ) { float posDelta = (float)rand.NextDouble() * MaxPosDelta * ( rand.Next( 2 ) == 0 ? 1 : -1 ); int maxOverlap = task.ProjectOptions.MaxOverlap; switch( rand.Next( 5 ) ) { case 0: case 1: point.X = Math.Max( -maxOverlap, Math.Min( task.ImageWidth - 1 + maxOverlap, point.X + posDelta ) ); dna.LastMutation = MutationType.AdjustPoint; break; case 2: case 3: point.Y = Math.Max( -maxOverlap, Math.Min( task.ImageHeight - 1 + maxOverlap, point.Y + posDelta ) ); dna.LastMutation = MutationType.AdjustPoint; break; case 4: point.X = Math.Max( -maxOverlap, Math.Min( task.ImageWidth - 1 + maxOverlap, point.X + posDelta ) ); point.Y = Math.Max( -maxOverlap, Math.Min( task.ImageHeight - 1 + maxOverlap, point.Y + posDelta ) ); dna.LastMutation = MutationType.AdjustPoints; break; } return point; }
public DNA Mutate( Random rand, DNA oldDNA, TaskState task ) { DNA newDNA = new DNA( oldDNA ); Shape shape = newDNA.Shapes[rand.Next( newDNA.Shapes.Length )]; int choice = rand.Next( ( EnableRotation ? 16 : 12 ) ); switch( choice ) { case 0: case 1: shape.PreviousState = shape.Clone() as Shape; MoveShape( rand, shape, task ); newDNA.LastMutation = MutationType.Move; break; case 2: case 3: shape.PreviousState = shape.Clone() as Shape; ScaleShape( rand, shape, task ); newDNA.LastMutation = MutationType.Scale; break; case 4: shape.PreviousState = shape.Clone() as Shape; ScaleShape( rand, shape, task ); MoveShape( rand, shape, task ); newDNA.LastMutation = MutationType.Transform; break; case 5: shape.PreviousState = shape.Clone() as Shape; MoveShape( rand, shape, task ); ScaleShape( rand, shape, task ); newDNA.LastMutation = MutationType.Transform; break; case 6: case 7: case 8: case 9: shape.PreviousState = shape.Clone() as Shape; ChangeColor( rand, shape, task ); newDNA.LastMutation = MutationType.ReplaceColor; break; case 10: newDNA.SwapShapes( rand ); break; case 11: shape.PreviousState = shape.Clone() as Shape; MoveShape( rand, shape, task ); ScaleShape( rand, shape, task ); ChangeColor( rand, shape, task ); newDNA.LastMutation = MutationType.Transform; break; case 12: case 13: shape.PreviousState = shape.Clone() as Shape; RotateShape( rand, shape ); newDNA.LastMutation = MutationType.Rotate; break; case 14: shape.PreviousState = shape.Clone() as Shape; MoveShape( rand, shape, task ); RotateShape( rand, shape ); newDNA.LastMutation = MutationType.Transform; break; case 15: shape.PreviousState = shape.Clone() as Shape; ChangeColor( rand, shape, task ); newDNA.LastMutation = MutationType.ReplaceColor; break; } return newDNA; }
void bImportDNA_Click(object sender, EventArgs e) { DNAImportWindow win = new DNAImportWindow(); if (win.ShowDialog() == DialogResult.OK) { Reset(); try { string[] parts = win.DNA.Split(' '); Stop(); State.Vertices = Int32.Parse(parts[0]); State.Shapes = Int32.Parse(parts[1]); nVertices.Value = State.Vertices; nPolygons.Value = State.Shapes; DNA importedDNA = new DNA { Shapes = new Shape[State.Shapes] }; int offset = 2; for (int s = 0; s < State.Shapes; s++) { Shape shape = new Shape { Points = new PointF[State.Vertices] }; int r = Int32.Parse(parts[offset]); int g = Int32.Parse(parts[offset + 1]); int b = Int32.Parse(parts[offset + 2]); int a = (int)(float.Parse(parts[offset + 3])*255); shape.Color = Color.FromArgb(a, r, g, b); offset += 4; for (int v = 0; v < State.Vertices; v++) { float X = float.Parse(parts[offset]); float Y = float.Parse(parts[offset + 1]); shape.Points[v] = new PointF(X, Y); offset += 2; } importedDNA.Shapes[s] = shape; } State.CurrentMatch = importedDNA; State.BestMatch = importedDNA; State.SetEvaluator(State.Evaluator); UpdateTick(); picBestMatch.Invalidate(); picDiff.Invalidate(); } catch (FormatException ex) { MessageBox.Show("Could not import DNA!" + Environment.NewLine + ex); } } }
public DNA Initialize(Random rand, TaskState task) { var dna = new DNA { Shapes = new Shape[task.Shapes] }; for (int s = 0; s < task.Shapes; s++) { var shape = new Shape { Color = Color.FromArgb(StartingAlpha, Color.R, Color.G, Color.B), Points = new PointF[task.Vertices] }; int maxRadius = (int)Math.Round(Math.Min(task.ImageWidth, task.ImageHeight)*MaxRadiusRatio); int radius = rand.Next(MinRadius, maxRadius); var center = new Point(rand.Next(radius - MaxOverlap, task.ImageWidth - radius + MaxOverlap), rand.Next(radius - MaxOverlap, task.ImageHeight - radius + MaxOverlap)); for (int v = 0; v < task.Vertices; v++) { double t = v*Math.PI*2*Revolutions/task.Vertices + Angle*Math.PI*2 + Math.PI/task.Vertices; shape.Points[v].X = (float)(center.X + Math.Cos(t)*radius); shape.Points[v].Y = (float)(center.Y + Math.Sin(t)*radius); } if (shape.GetBoundaries().Width < 1 || shape.GetBoundaries().Height < 1) { continue; } dna.Shapes[s] = shape; } return dna; }
DNA IInitializer.Initialize( Random rand, TaskState task ) { DNA dna = new DNA { Shapes = new Shape[task.Shapes] }; for( int i = 0; i < dna.Shapes.Length; i++ ) { Shape shape = new Shape { Color = Color.FromArgb( StartingAlpha, Color.R, Color.G, Color.B ), Points = new PointF[task.Vertices] }; for( int j = 0; j < shape.Points.Length; j++ ) { shape.Points[j] = new PointF( rand.NextFloat( -MaxOverlap, task.ImageWidth + MaxOverlap ), rand.NextFloat( -MaxOverlap, task.ImageHeight + MaxOverlap ) ); } dna.Shapes[i] = shape; } return dna; }
void MutateShape( Random rand, DNA dna, Shape shape, TaskState task ) { shape.PreviousState = shape.Clone() as Shape; int colorDelta = (byte)rand.Next( 1, MaxColorDelta + 1 ) * ( rand.Next( 2 ) == 0 ? 1 : -1 ); switch( rand.Next( 10 ) ) { case 0: shape.Color = Color.FromArgb( Math.Max( task.ProjectOptions.MinAlpha, Math.Min( 255, shape.Color.A + colorDelta ) ), shape.Color.R, shape.Color.G, shape.Color.B ); dna.LastMutation = MutationType.AdjustColor; if( rand.Next( 10 ) == 0 ) { MutateMultiplePoints( shape, rand, dna, task ); dna.LastMutation = MutationType.ReplaceShape; } break; case 1: shape.Color = Color.FromArgb( shape.Color.A, Math.Max( 0, Math.Min( 255, shape.Color.R + colorDelta ) ), shape.Color.G, shape.Color.B ); dna.LastMutation = MutationType.AdjustColor; if( rand.Next( 10 ) == 0 ) { MutateMultiplePoints( shape, rand, dna, task ); dna.LastMutation = MutationType.ReplaceShape; } break; case 2: shape.Color = Color.FromArgb( shape.Color.A, shape.Color.R, Math.Max( 0, Math.Min( 255, shape.Color.G + colorDelta ) ), shape.Color.B ); dna.LastMutation = MutationType.AdjustColor; if( rand.Next( 10 ) == 0 ) { MutateMultiplePoints( shape, rand, dna, task ); dna.LastMutation = MutationType.ReplaceShape; } break; case 3: shape.Color = Color.FromArgb( shape.Color.A, shape.Color.R, shape.Color.G, Math.Max( 0, Math.Min( 255, shape.Color.B + colorDelta ) ) ); dna.LastMutation = MutationType.AdjustColor; if( rand.Next( 10 ) == 0 ) { MutateMultiplePoints( shape, rand, dna, task ); dna.LastMutation = MutationType.ReplaceShape; } break; default: MutateMultiplePoints( shape, rand, dna, task ); break; } }
public double CalculateDivergence(Bitmap testImage, DNA dna, TaskState state, double maxAcceptableDivergence) { if (Emphasized) { if (EmphasisAmount == 2) { maxDivergence = 3L * state.ImageWidth / 2L * state.ImageHeight / 2L * 255L * 255L; } else { maxDivergence = (long)(3L * state.ImageWidth / 2L * state.ImageHeight / 2L * Math.Pow(255, EmphasisAmount)); } } else { maxDivergence = 3L * state.ImageWidth / 2L * state.ImageHeight / 2L * 255L; } long sum = 0; long roundedMax = (long)(maxAcceptableDivergence * maxDivergence + 1); using (Graphics g = Graphics.FromImage(testImage)) { g.Clear(state.ProjectOptions.Matte); g.Transform = new Matrix(.5f, 0, 0, .5f, 0, 0); g.SmoothingMode = (Smooth ? SmoothingMode.HighQuality : SmoothingMode.HighSpeed); for (int i = 0; i < dna.Shapes.Length; i++) { g.FillPolygon(new SolidBrush(dna.Shapes[i].Color), dna.Shapes[i].Points, FillMode.Alternate); } } BitmapData testData = testImage.LockBits(new Rectangle(Point.Empty, testImage.Size), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); for (int i = 0; i < state.ImageHeight / 2; i++) { byte *originalPointer = (byte *)halfResData.Scan0 + halfResData.Stride * i; byte *testPointer = (byte *)testData.Scan0 + testData.Stride * i; for (int j = 0; j < state.ImageWidth / 2; j++) { int b = Math.Abs(*originalPointer - *testPointer); int g = Math.Abs(originalPointer[1] - testPointer[1]); int r = Math.Abs(originalPointer[2] - testPointer[2]); if (Emphasized) { if (EmphasisAmount == 2) { sum += r * r + b * b + g * g; } else { sum += (long) (Math.Pow(r, EmphasisAmount) + Math.Pow(g, EmphasisAmount) + Math.Pow(b, EmphasisAmount)); } } else { sum += r + b + g; } originalPointer += 4; testPointer += 4; } if (sum > roundedMax) { sum = (long)maxDivergence; break; } } testImage.UnlockBits(testData); if (Emphasized) { return(Math.Pow(sum / maxDivergence, 1 / EmphasisAmount)); } else { return(sum / maxDivergence); } }
public void SetEvaluator( IEvaluator newEvaluator ) { lock( ImprovementLock ) { if( OriginalImage != null && BestMatch != null ) { using( Bitmap testCanvas = new Bitmap( ImageWidth, ImageHeight ) ) { newEvaluator.Initialize( this ); BestMatch.Divergence = newEvaluator.CalculateDivergence( testCanvas, BestMatch, this, 1 ); CurrentMatch = BestMatch; } } Evaluator = newEvaluator; } }
public DNA Mutate( Random rand, DNA oldDNA, TaskState task ) { DNA newDNA = new DNA( oldDNA ); int s1 = rand.Next( newDNA.Shapes.Length ); Shape shape = newDNA.Shapes[s1]; if( rand.Next( 20 ) == 0 ) { newDNA.SwapShapes( rand ); } else { MutateShape( rand, newDNA, shape, task ); } return newDNA; }
void MutateShape( Random rand, DNA dna, Shape shape, TaskState task ) { int maxOverlap = task.ProjectOptions.MaxOverlap; shape.PreviousState = shape.Clone() as Shape; int colorDelta = (byte)rand.Next( 1, MaxColorDelta + 1 ) * ( rand.Next( 2 ) == 0 ? 1 : -1 ); float posDelta = (float)rand.NextDouble() * MaxPosDelta * ( rand.Next( 2 ) == 0 ? 1 : -1 ); switch( rand.Next( 9 ) ) { case 0: shape.Color = Color.FromArgb( Math.Max( task.ProjectOptions.MinAlpha, Math.Min( 255, shape.Color.A + colorDelta ) ), shape.Color.R, shape.Color.G, shape.Color.B ); dna.LastMutation = MutationType.AdjustColor; break; case 1: shape.Color = Color.FromArgb( shape.Color.A, Math.Max( 0, Math.Min( 255, shape.Color.R + colorDelta ) ), shape.Color.G, shape.Color.B ); dna.LastMutation = MutationType.AdjustColor; break; case 2: shape.Color = Color.FromArgb( shape.Color.A, shape.Color.R, Math.Max( 0, Math.Min( 255, shape.Color.G + colorDelta ) ), shape.Color.B ); dna.LastMutation = MutationType.AdjustColor; break; case 3: shape.Color = Color.FromArgb( shape.Color.A, shape.Color.R, shape.Color.G, Math.Max( 0, Math.Min( 255, shape.Color.B + colorDelta ) ) ); dna.LastMutation = MutationType.AdjustColor; break; case 4: case 5: int pt1 = rand.Next( shape.Points.Length ); shape.Points[pt1].X = Math.Max( -maxOverlap, Math.Min( task.ImageWidth - 1 + maxOverlap, shape.Points[pt1].X + posDelta ) ); dna.LastMutation = MutationType.AdjustPoint; break; case 6: case 7: int pt2 = rand.Next( shape.Points.Length ); shape.Points[pt2].Y = Math.Max( -maxOverlap, Math.Min( task.ImageHeight - 1 + maxOverlap, shape.Points[pt2].Y + posDelta ) ); dna.LastMutation = MutationType.AdjustPoint; break; case 8: int pt3 = rand.Next( shape.Points.Length ); shape.Points[pt3].X = Math.Max( -maxOverlap, Math.Min( task.ImageWidth - 1 + maxOverlap, shape.Points[pt3].X + posDelta ) ); shape.Points[pt3].Y = Math.Max( -maxOverlap, Math.Min( task.ImageHeight - 1 + maxOverlap, shape.Points[pt3].Y + posDelta ) ); dna.LastMutation = MutationType.AdjustPoints; break; } }
public DNA Mutate(Random rand, DNA oldDNA, TaskState task) { DNA newDNA = new DNA(oldDNA); Shape shape = newDNA.Shapes[rand.Next(newDNA.Shapes.Length)]; int choice = rand.Next((EnableRotation ? 16 : 12)); switch (choice) { case 0: case 1: shape.PreviousState = shape.Clone() as Shape; MoveShape(rand, shape, task); newDNA.LastMutation = MutationType.Move; break; case 2: case 3: shape.PreviousState = shape.Clone() as Shape; ScaleShape(rand, shape, task); newDNA.LastMutation = MutationType.Scale; break; case 4: shape.PreviousState = shape.Clone() as Shape; ScaleShape(rand, shape, task); MoveShape(rand, shape, task); newDNA.LastMutation = MutationType.Transform; break; case 5: shape.PreviousState = shape.Clone() as Shape; MoveShape(rand, shape, task); ScaleShape(rand, shape, task); newDNA.LastMutation = MutationType.Transform; break; case 6: case 7: case 8: case 9: shape.PreviousState = shape.Clone() as Shape; ChangeColor(rand, shape, task); newDNA.LastMutation = MutationType.ReplaceColor; break; case 10: newDNA.SwapShapes(rand); break; case 11: shape.PreviousState = shape.Clone() as Shape; MoveShape(rand, shape, task); ScaleShape(rand, shape, task); ChangeColor(rand, shape, task); newDNA.LastMutation = MutationType.Transform; break; case 12: case 13: shape.PreviousState = shape.Clone() as Shape; RotateShape(rand, shape); newDNA.LastMutation = MutationType.Rotate; break; case 14: shape.PreviousState = shape.Clone() as Shape; MoveShape(rand, shape, task); RotateShape(rand, shape); newDNA.LastMutation = MutationType.Transform; break; case 15: shape.PreviousState = shape.Clone() as Shape; ChangeColor(rand, shape, task); newDNA.LastMutation = MutationType.ReplaceColor; break; } return(newDNA); }