├── .gitignore ├── SuperImageEvolver ├── Icons │ ├── disk.png │ ├── gear.png │ ├── control.png │ ├── images.png │ ├── document.png │ ├── disk--pencil.png │ ├── disk-black.png │ ├── image-export.png │ ├── information.png │ ├── arrow-stop-180.png │ ├── document-export.png │ ├── document-import.png │ ├── control-stop-square.png │ ├── layer-shape-polygon.png │ └── folder-horizontal-open.png ├── Mutators │ ├── MutatorHelper.cs │ ├── IMutator.cs │ ├── HarderMutator.cs │ ├── MediumMutator.cs │ ├── SoftMutator.cs │ ├── HardMutator.cs │ ├── HardishMutator.cs │ ├── TranslateMutator.cs │ └── SoftTranslateMutator.cs ├── Initializers │ ├── IInitializer.cs │ ├── SolidColorInitializer.cs │ ├── RadialInitializer.cs │ └── SegmentedInitializer.cs ├── Properties │ ├── Settings.settings │ ├── Settings.Designer.cs │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ └── Resources.resx ├── Evaluators │ ├── IEvaluator.cs │ ├── LumaEvaluator.cs │ ├── SloppyRGBEvaluator.cs │ └── RGBEvaluator.cs ├── Core │ ├── MutationType.cs │ ├── Mutation.cs │ ├── IModule.cs │ ├── Utilities.cs │ ├── ProjectOptions.cs │ ├── Shape.cs │ ├── DNA.cs │ ├── TaskState.cs │ └── ModuleManager.cs ├── Program.cs ├── CustomInterpolationPictureBox.cs ├── ModuleSettingsDisplay.cs ├── DNAImportWindow.cs ├── Canvas.Designer.cs ├── DiffCanvas.Designer.cs ├── GraphWindow.Designer.cs ├── PolygonValueEvaluator.cs ├── GraphWindow.cs ├── ModuleSettingsDisplay.Designer.cs ├── Canvas.cs ├── DNAImportWindow.Designer.cs ├── DNAImportWindow.resx ├── ModuleSettingsDisplay.resx ├── MainForm.resx ├── SuperImageEvolver.csproj └── DiffCanvas.cs ├── README.md ├── SuperImageEvolver.sln └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | _ReSharper*/ 2 | SuperImageEvolver/bin/ 3 | SuperImageEvolver/obj/ 4 | *.suo 5 | *.user 6 | *.userprefs 7 | -------------------------------------------------------------------------------- /SuperImageEvolver/Icons/disk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mstefarov/SuperImageEvolver/HEAD/SuperImageEvolver/Icons/disk.png -------------------------------------------------------------------------------- /SuperImageEvolver/Icons/gear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mstefarov/SuperImageEvolver/HEAD/SuperImageEvolver/Icons/gear.png -------------------------------------------------------------------------------- /SuperImageEvolver/Icons/control.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mstefarov/SuperImageEvolver/HEAD/SuperImageEvolver/Icons/control.png -------------------------------------------------------------------------------- /SuperImageEvolver/Icons/images.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mstefarov/SuperImageEvolver/HEAD/SuperImageEvolver/Icons/images.png -------------------------------------------------------------------------------- /SuperImageEvolver/Icons/document.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mstefarov/SuperImageEvolver/HEAD/SuperImageEvolver/Icons/document.png -------------------------------------------------------------------------------- /SuperImageEvolver/Icons/disk--pencil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mstefarov/SuperImageEvolver/HEAD/SuperImageEvolver/Icons/disk--pencil.png -------------------------------------------------------------------------------- /SuperImageEvolver/Icons/disk-black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mstefarov/SuperImageEvolver/HEAD/SuperImageEvolver/Icons/disk-black.png -------------------------------------------------------------------------------- /SuperImageEvolver/Icons/image-export.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mstefarov/SuperImageEvolver/HEAD/SuperImageEvolver/Icons/image-export.png -------------------------------------------------------------------------------- /SuperImageEvolver/Icons/information.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mstefarov/SuperImageEvolver/HEAD/SuperImageEvolver/Icons/information.png -------------------------------------------------------------------------------- /SuperImageEvolver/Icons/arrow-stop-180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mstefarov/SuperImageEvolver/HEAD/SuperImageEvolver/Icons/arrow-stop-180.png -------------------------------------------------------------------------------- /SuperImageEvolver/Icons/document-export.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mstefarov/SuperImageEvolver/HEAD/SuperImageEvolver/Icons/document-export.png -------------------------------------------------------------------------------- /SuperImageEvolver/Icons/document-import.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mstefarov/SuperImageEvolver/HEAD/SuperImageEvolver/Icons/document-import.png -------------------------------------------------------------------------------- /SuperImageEvolver/Icons/control-stop-square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mstefarov/SuperImageEvolver/HEAD/SuperImageEvolver/Icons/control-stop-square.png -------------------------------------------------------------------------------- /SuperImageEvolver/Icons/layer-shape-polygon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mstefarov/SuperImageEvolver/HEAD/SuperImageEvolver/Icons/layer-shape-polygon.png -------------------------------------------------------------------------------- /SuperImageEvolver/Icons/folder-horizontal-open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mstefarov/SuperImageEvolver/HEAD/SuperImageEvolver/Icons/folder-horizontal-open.png -------------------------------------------------------------------------------- /SuperImageEvolver/Mutators/MutatorHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SuperImageEvolver { 4 | public static class MutatorHelper { 5 | 6 | } 7 | } -------------------------------------------------------------------------------- /SuperImageEvolver/Mutators/IMutator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SuperImageEvolver { 4 | public interface IMutator : IModule { 5 | DNA Mutate( Random rand, DNA dna, TaskState task ); 6 | } 7 | } -------------------------------------------------------------------------------- /SuperImageEvolver/Initializers/IInitializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SuperImageEvolver { 4 | public interface IInitializer : IModule { 5 | DNA Initialize( Random rand, TaskState task ); 6 | } 7 | } -------------------------------------------------------------------------------- /SuperImageEvolver/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SuperImageEvolver/Evaluators/IEvaluator.cs: -------------------------------------------------------------------------------- 1 | using System.Drawing; 2 | 3 | namespace SuperImageEvolver { 4 | public interface IEvaluator : IModule { 5 | bool Smooth { get; } 6 | 7 | void Initialize( TaskState state ); 8 | 9 | double CalculateDivergence( Bitmap testImage, DNA dna, TaskState state, double maxAcceptableDivergence ); 10 | } 11 | } -------------------------------------------------------------------------------- /SuperImageEvolver/Core/MutationType.cs: -------------------------------------------------------------------------------- 1 | namespace SuperImageEvolver { 2 | public enum MutationType { 3 | ReplaceShape, 4 | ReplaceColor, 5 | ReplacePoint, 6 | ReplacePoints, 7 | AdjustColor, 8 | AdjustPoint, 9 | AdjustPoints, 10 | SwapShapes, 11 | Move, 12 | Scale, 13 | Transform, 14 | Rotate 15 | } 16 | } -------------------------------------------------------------------------------- /SuperImageEvolver/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace SuperImageEvolver { 5 | static class Program { 6 | [STAThread] 7 | static void Main( string[] args ) { 8 | Application.EnableVisualStyles(); 9 | Application.SetCompatibleTextRenderingDefault( false ); 10 | Application.Run( new MainForm( args ) ); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /SuperImageEvolver/CustomInterpolationPictureBox.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using System.Drawing.Drawing2D; 3 | using System.Windows.Forms; 4 | 5 | namespace SuperImageEvolver { 6 | internal class CustomInterpolationPictureBox : PictureBox { 7 | [DefaultValue(InterpolationMode.Default)] 8 | public InterpolationMode InterpolationMode { get; set; } 9 | 10 | protected override void OnPaint(PaintEventArgs paintEventArgs) { 11 | paintEventArgs.Graphics.InterpolationMode = InterpolationMode; 12 | base.OnPaint(paintEventArgs); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /SuperImageEvolver/ModuleSettingsDisplay.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace SuperImageEvolver { 5 | public partial class ModuleSettingsDisplay : Form where T : class, ICloneable { 6 | public T Module { get; private set; } 7 | 8 | 9 | public ModuleSettingsDisplay( T module ) { 10 | if( module == null ) throw new ArgumentNullException( "module" ); 11 | InitializeComponent(); 12 | Text = module.GetType().Name; 13 | Module = (T)module.Clone(); 14 | pgGrid.SelectedObject = Module; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /SuperImageEvolver/DNAImportWindow.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace SuperImageEvolver { 5 | public sealed partial class DNAImportWindow : Form { 6 | public string DNA { 7 | get { return tPasteArea.Text; } 8 | } 9 | 10 | 11 | public DNAImportWindow() { 12 | InitializeComponent(); 13 | tPasteArea.Text = Clipboard.GetText( TextDataFormat.Text ); 14 | } 15 | 16 | 17 | void tPasteArea_TextChanged( object sender, EventArgs e ) { 18 | bImport.Enabled = tPasteArea.Text.Length > 0; 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /SuperImageEvolver/Core/Mutation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SuperImageEvolver { 4 | public sealed class Mutation { 5 | public Mutation( DNA previousDna, DNA newDna ) { 6 | PreviousDNA = previousDna; 7 | NewDNA = newDna; 8 | Timestamp = DateTime.UtcNow; 9 | } 10 | 11 | 12 | public DNA PreviousDNA { get; set; } 13 | public DNA NewDNA { get; set; } 14 | public DateTime Timestamp { get; set; } 15 | 16 | public double DivergenceDelta { 17 | get { return PreviousDNA.Divergence - NewDNA.Divergence; } 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | SuperImageEvolver - Using genetic algorithms to vectorize images, with mixed results. 2 | 3 | Written in 2011-2014 by Matvei Stefarov (@mstefarov). Based in part on the work of [AlteredQualia](http://alteredqualia.com/visualization/evolve/) and [Roger Alsing](http://rogeralsing.com/2008/12/07/genetic-programming-evolution-of-mona-lisa/). 4 | 5 | To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. This software is distributed without any warranty. See CC0 Public Domain Dedication here: . 6 | 7 | ![Usage example](http://i.imgur.com/wfAd7.png) 8 | 9 | ![Usage example](http://i.imgur.com/uEcxh.png) 10 | -------------------------------------------------------------------------------- /SuperImageEvolver.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SuperImageEvolver", "SuperImageEvolver\SuperImageEvolver.csproj", "{F0E25CA0-3887-4BE7-BB3D-EF40DEA7F1B8}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Any CPU = Debug|Any CPU 9 | Release|Any CPU = Release|Any CPU 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {F0E25CA0-3887-4BE7-BB3D-EF40DEA7F1B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 13 | {F0E25CA0-3887-4BE7-BB3D-EF40DEA7F1B8}.Debug|Any CPU.Build.0 = Debug|Any CPU 14 | {F0E25CA0-3887-4BE7-BB3D-EF40DEA7F1B8}.Release|Any CPU.ActiveCfg = Release|Any CPU 15 | {F0E25CA0-3887-4BE7-BB3D-EF40DEA7F1B8}.Release|Any CPU.Build.0 = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /SuperImageEvolver/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.269 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace SuperImageEvolver.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /SuperImageEvolver/Canvas.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace SuperImageEvolver { 2 | sealed partial class Canvas { 3 | /// 4 | /// Required designer variable. 5 | /// 6 | private System.ComponentModel.IContainer components = null; 7 | 8 | /// 9 | /// Clean up any resources being used. 10 | /// 11 | /// true if managed resources should be disposed; otherwise, false. 12 | protected override void Dispose( bool disposing ) { 13 | if( disposing && (components != null) ) { 14 | components.Dispose(); 15 | } 16 | base.Dispose( disposing ); 17 | } 18 | 19 | #region Component Designer generated code 20 | 21 | /// 22 | /// Required method for Designer support - do not modify 23 | /// the contents of this method with the code editor. 24 | /// 25 | private void InitializeComponent() { 26 | components = new System.ComponentModel.Container(); 27 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 28 | } 29 | 30 | #endregion 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /SuperImageEvolver/DiffCanvas.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace SuperImageEvolver { 2 | sealed partial class DiffCanvas { 3 | /// 4 | /// Required designer variable. 5 | /// 6 | private System.ComponentModel.IContainer components = null; 7 | 8 | /// 9 | /// Clean up any resources being used. 10 | /// 11 | /// true if managed resources should be disposed; otherwise, false. 12 | protected override void Dispose( bool disposing ) { 13 | if( disposing && (components != null) ) { 14 | components.Dispose(); 15 | } 16 | base.Dispose( disposing ); 17 | } 18 | 19 | #region Component Designer generated code 20 | 21 | /// 22 | /// Required method for Designer support - do not modify 23 | /// the contents of this method with the code editor. 24 | /// 25 | private void InitializeComponent() { 26 | components = new System.ComponentModel.Container(); 27 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 28 | } 29 | 30 | #endregion 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /SuperImageEvolver/GraphWindow.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace SuperImageEvolver { 2 | sealed partial class GraphWindow { 3 | /// 4 | /// Required designer variable. 5 | /// 6 | private System.ComponentModel.IContainer components = null; 7 | 8 | /// 9 | /// Clean up any resources being used. 10 | /// 11 | /// true if managed resources should be disposed; otherwise, false. 12 | protected override void Dispose( bool disposing ) { 13 | if( disposing && (components != null) ) { 14 | components.Dispose(); 15 | } 16 | base.Dispose( disposing ); 17 | } 18 | 19 | #region Component Designer generated code 20 | 21 | /// 22 | /// Required method for Designer support - do not modify 23 | /// the contents of this method with the code editor. 24 | /// 25 | private void InitializeComponent() { 26 | components = new System.ComponentModel.Container(); 27 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 28 | } 29 | 30 | #endregion 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /SuperImageEvolver/Core/IModule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SuperImageEvolver { 4 | public interface IModule : ICloneable { 5 | void ReadSettings( NBTag tag ); 6 | 7 | void WriteSettings( NBTag tag ); 8 | } 9 | 10 | 11 | public interface IModuleFactory { 12 | Type ModuleType { get; } 13 | 14 | ModuleFunction Function { get; } 15 | 16 | string ID { get; } 17 | 18 | ModulePreset[] Presets { get; } 19 | 20 | IModule GetInstance(); 21 | } 22 | 23 | 24 | public sealed class ModulePreset { 25 | public ModulePreset( string name, ModuleInstanceCallback _callback, IModuleFactory factory ) { 26 | Name = name; 27 | callback = _callback; 28 | Factory = factory; 29 | } 30 | 31 | 32 | readonly ModuleInstanceCallback callback; 33 | public string Name { get; private set; } 34 | public IModuleFactory Factory { get; private set; } 35 | 36 | 37 | public IModule GetInstance() { 38 | return callback(); 39 | } 40 | } 41 | 42 | 43 | public delegate IModule ModuleInstanceCallback(); 44 | 45 | 46 | public enum ModuleFunction { 47 | Evaluator, 48 | Initializer, 49 | Mutator 50 | } 51 | 52 | 53 | public sealed class DisableAutoSerializationAttribute : Attribute {} 54 | } -------------------------------------------------------------------------------- /SuperImageEvolver/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle( "SuperImageEvolver" )] 8 | [assembly: AssemblyDescription( "" )] 9 | [assembly: AssemblyConfiguration( "" )] 10 | [assembly: AssemblyCompany( "" )] 11 | [assembly: AssemblyProduct( "SuperImageEvolver" )] 12 | [assembly: AssemblyCopyright( "" )] 13 | [assembly: AssemblyTrademark( "" )] 14 | [assembly: AssemblyCulture( "" )] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible( false )] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid( "165f0358-0623-4666-9751-ad1be3d62a5b" )] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion( "0.0.0.1" )] 35 | [assembly: AssemblyFileVersion( "0.0.0.1" )] 36 | -------------------------------------------------------------------------------- /SuperImageEvolver/Core/Utilities.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SuperImageEvolver { 4 | static class Utilities { 5 | public static string ToCompactString( this TimeSpan span ) { 6 | return String.Format( "{0}.{1:00}:{2:00}:{3:00}", 7 | span.Days, span.Hours, span.Minutes, span.Seconds ); 8 | } 9 | 10 | 11 | public static double NextDouble( this Random rand, double max ) { 12 | return rand.NextDouble() * max; 13 | } 14 | 15 | 16 | public static double NextDouble( this Random rand, double min, double max ) { 17 | return rand.NextDouble() * ( max - min ) + min; 18 | } 19 | 20 | 21 | public static float NextFloat( this Random rand ) { 22 | return (float)rand.NextDouble(); 23 | } 24 | 25 | 26 | public static float NextFloat( this Random rand, double max ) { 27 | return (float)( rand.NextDouble() * max ); 28 | } 29 | 30 | 31 | public static float NextFloat( this Random rand, double min, double max ) { 32 | return (float)( rand.NextDouble() * ( max - min ) + min ); 33 | } 34 | 35 | 36 | public static byte NextByte( this Random rand ) { 37 | return (byte)rand.Next( 256 ); 38 | } 39 | 40 | 41 | public static byte NextByte( this Random rand, int max ) { 42 | return (byte)rand.Next( max ); 43 | } 44 | 45 | 46 | public static byte NextByte( this Random rand, int min, int max ) { 47 | return (byte)rand.Next( min, max ); 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /SuperImageEvolver/PolygonValueEvaluator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | 5 | namespace SuperImageEvolver { 6 | internal class PolygonValueEvaluator { 7 | public static ShapeEvaluation[] SortShapes(TaskState state) { 8 | var results = new List(); 9 | 10 | using (var testCanvas = new Bitmap(state.ImageWidth, state.ImageHeight)) { 11 | double baseDivergence = state.Evaluator.CalculateDivergence(testCanvas, state.BestMatch, state, 1); 12 | for (int i = 0; i < state.BestMatch.Shapes.Length; i++) { 13 | var dnaWithoutShape = new DNA(state.BestMatch); 14 | dnaWithoutShape.Shapes[i].Color = Color.Transparent; 15 | double diffDivergence = state.Evaluator.CalculateDivergence(testCanvas, dnaWithoutShape, state, 1); 16 | results.Add(new ShapeEvaluation { 17 | Ordinal = i, 18 | Divergence = diffDivergence - baseDivergence, 19 | Shape = state.BestMatch.Shapes[i] 20 | }); 21 | } 22 | } 23 | 24 | results.Sort((r1, r2) => Math.Sign(r2.Divergence - r1.Divergence)); 25 | return results.ToArray(); 26 | } 27 | } 28 | 29 | 30 | public class ShapeEvaluation { 31 | public int Ordinal { get; set; } 32 | public double Divergence { get; set; } 33 | public Shape Shape { get; set; } 34 | 35 | public override string ToString() { 36 | return "ShapeEval(" + Divergence + ")"; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /SuperImageEvolver/Initializers/SolidColorInitializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | 4 | namespace SuperImageEvolver { 5 | public class SolidColorInitializerFactory : IModuleFactory { 6 | public Type ModuleType { 7 | get { return typeof( SolidColorInitializer ); } 8 | } 9 | 10 | public string ID { 11 | get { return "std.SolidColorInitializer.1"; } 12 | } 13 | 14 | public ModuleFunction Function { 15 | get { return ModuleFunction.Initializer; } 16 | } 17 | 18 | public ModulePreset[] Presets { 19 | get { 20 | return new[] { 21 | new ModulePreset( "Full Random", () => ( new SolidColorInitializer( Color.Black ) ), this ) 22 | }; 23 | } 24 | } 25 | 26 | 27 | public IModule GetInstance() { 28 | return new SolidColorInitializer( Color.Black ); 29 | } 30 | } 31 | 32 | 33 | sealed class SolidColorInitializer : IInitializer { 34 | public Color Color { get; set; } 35 | public int MaxOverlap { get; set; } 36 | public byte StartingAlpha { get; set; } 37 | 38 | 39 | public SolidColorInitializer( Color color ) { 40 | Color = color; 41 | MaxOverlap = 6; 42 | StartingAlpha = 1; 43 | } 44 | 45 | 46 | DNA IInitializer.Initialize( Random rand, TaskState task ) { 47 | DNA dna = new DNA { 48 | Shapes = new Shape[task.Shapes] 49 | }; 50 | for( int i = 0; i < dna.Shapes.Length; i++ ) { 51 | Shape shape = new Shape { 52 | Color = Color.FromArgb( StartingAlpha, Color.R, Color.G, Color.B ), 53 | Points = new PointF[task.Vertices] 54 | }; 55 | for( int j = 0; j < shape.Points.Length; j++ ) { 56 | shape.Points[j] = new PointF( rand.NextFloat( -MaxOverlap, task.ImageWidth + MaxOverlap ), 57 | rand.NextFloat( -MaxOverlap, task.ImageHeight + MaxOverlap ) ); 58 | } 59 | dna.Shapes[i] = shape; 60 | } 61 | return dna; 62 | } 63 | 64 | 65 | object ICloneable.Clone() { 66 | return new SolidColorInitializer( Color ) { 67 | MaxOverlap = MaxOverlap 68 | }; 69 | } 70 | 71 | 72 | void IModule.ReadSettings( NBTag tag ) {} 73 | 74 | void IModule.WriteSettings( NBTag tag ) {} 75 | } 76 | } -------------------------------------------------------------------------------- /SuperImageEvolver/Mutators/HarderMutator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | 4 | namespace SuperImageEvolver { 5 | public class HarderMutatorFactory : IModuleFactory { 6 | public Type ModuleType { 7 | get { return typeof( HarderMutator ); } 8 | } 9 | 10 | public string ID { 11 | get { return "std.HarderMutator.1"; } 12 | } 13 | 14 | public ModuleFunction Function { 15 | get { return ModuleFunction.Mutator; } 16 | } 17 | 18 | public ModulePreset[] Presets { 19 | get { 20 | return new[] { 21 | new ModulePreset( "Harder", () => new HarderMutator(), this ) 22 | }; 23 | } 24 | } 25 | 26 | 27 | public IModule GetInstance() { 28 | return new HarderMutator(); 29 | } 30 | } 31 | 32 | 33 | sealed class HarderMutator : IMutator { 34 | public double MaxPolygonArea { get; set; } 35 | 36 | 37 | public HarderMutator() { 38 | MaxPolygonArea = .5; 39 | } 40 | 41 | 42 | public DNA Mutate( Random rand, DNA oldDNA, TaskState task ) { 43 | int maxOverlap = task.ProjectOptions.MaxOverlap; 44 | DNA newDNA = new DNA( oldDNA ); 45 | Shape shape = newDNA.Shapes[rand.Next( newDNA.Shapes.Length )]; 46 | shape.PreviousState = shape.Clone() as Shape; 47 | shape.Color = Color.FromArgb( rand.Next( task.ProjectOptions.MinAlpha, 256 ), rand.NextByte(), 48 | rand.NextByte(), rand.NextByte() ); 49 | double area, maxArea = MaxPolygonArea * task.ImageWidth * task.ImageHeight; 50 | do { 51 | for( int i = 0; i < shape.Points.Length; i++ ) { 52 | shape.Points[i] = new PointF( rand.NextFloat( -maxOverlap, task.ImageWidth + maxOverlap ), 53 | rand.NextFloat( -maxOverlap, task.ImageHeight + maxOverlap ) ); 54 | } 55 | area = CalculateArea( shape.Points ); 56 | } while( area > maxArea ); 57 | newDNA.LastMutation = MutationType.ReplaceShape; 58 | return newDNA; 59 | } 60 | 61 | 62 | static double CalculateArea( PointF[] points ) { 63 | float minX = float.MaxValue, 64 | maxX = float.MinValue, 65 | minY = float.MaxValue, 66 | maxY = float.MinValue; 67 | for( int i = 0; i < points.Length; i++ ) { 68 | minX = Math.Min( minX, points[i].X ); 69 | maxX = Math.Max( maxX, points[i].X ); 70 | minY = Math.Min( minY, points[i].Y ); 71 | maxY = Math.Max( maxY, points[i].Y ); 72 | } 73 | return ( maxX - minX ) * ( maxY - minY ); 74 | } 75 | 76 | 77 | object ICloneable.Clone() { 78 | return new HarderMutator { 79 | MaxPolygonArea = MaxPolygonArea 80 | }; 81 | } 82 | 83 | 84 | void IModule.ReadSettings( NBTag tag ) {} 85 | 86 | void IModule.WriteSettings( NBTag tag ) {} 87 | } 88 | } -------------------------------------------------------------------------------- /SuperImageEvolver/Core/ProjectOptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | 4 | namespace SuperImageEvolver { 5 | public sealed class ProjectOptions : ICloneable { 6 | public Color Matte { get; set; } 7 | public Color BackColor { get; set; } 8 | public int MaxOverlap { get; set; } 9 | public byte MinAlpha { get; set; } 10 | public TimeSpan RefreshRate { get; set; } 11 | public Color WireframeColor { get; set; } 12 | public Color LastChangeColor1 { get; set; } 13 | public Color LastChangeColor2 { get; set; } 14 | 15 | public double RiskRate { get; set; } 16 | public double RiskMargin { get; set; } 17 | 18 | 19 | public ProjectOptions() { 20 | RiskRate = .1; 21 | RiskMargin = .1; 22 | 23 | Matte = Color.White; 24 | BackColor = Color.DimGray; 25 | MaxOverlap = 8; 26 | MinAlpha = 1; 27 | RefreshRate = TimeSpan.FromMilliseconds( 500 ); 28 | WireframeColor = Color.Black; 29 | LastChangeColor1 = Color.White; 30 | LastChangeColor2 = Color.Black; 31 | } 32 | 33 | 34 | public object Clone() { 35 | return new ProjectOptions { 36 | Matte = Matte, 37 | MaxOverlap = MaxOverlap, 38 | MinAlpha = MinAlpha, 39 | BackColor = BackColor, 40 | RefreshRate = RefreshRate, 41 | WireframeColor = WireframeColor, 42 | LastChangeColor1 = LastChangeColor1, 43 | LastChangeColor2 = LastChangeColor2, 44 | 45 | RiskRate = RiskRate, 46 | RiskMargin = RiskMargin 47 | }; 48 | } 49 | 50 | 51 | public NBTag SerializeNBT() { 52 | NBTCompound tag = new NBTCompound( "ProjectOptions" ); 53 | tag.Append( "Matte", Matte ); 54 | tag.Append( "BackColor", BackColor ); 55 | tag.Append( "MaxOverlap", MaxOverlap ); 56 | tag.Append( "MinAlpha", MinAlpha ); 57 | tag.Append( "RefreshRate", RefreshRate.Ticks ); 58 | tag.Append( "WireframeColor", WireframeColor ); 59 | tag.Append( "LastChangeColor1", LastChangeColor1 ); 60 | tag.Append( "LastChangeColor2", LastChangeColor2 ); 61 | tag.Append( "RiskMargin", RiskMargin ); 62 | tag.Append( "RiskRate", RiskRate ); 63 | return tag; 64 | } 65 | 66 | 67 | public ProjectOptions( NBTag tag ) 68 | : this() { 69 | Matte = tag["Matte"].GetColor(); 70 | BackColor = tag["BackColor"].GetColor(); 71 | MaxOverlap = tag["MaxOverlap"].GetInt(); 72 | MinAlpha = tag["MinAlpha"].GetByte(); 73 | RefreshRate = new TimeSpan( tag.GetLong( "RefreshRate", RefreshRate.Ticks ) ); 74 | WireframeColor = tag.GetColor( "WireframeColor", WireframeColor ); 75 | LastChangeColor1 = tag.GetColor( "LastChangeColor1", LastChangeColor1 ); 76 | LastChangeColor2 = tag.GetColor( "LastChangeColor2", LastChangeColor2 ); 77 | RiskRate = tag.GetDouble( "RiskRate", RiskRate ); 78 | RiskMargin = tag.GetDouble( "RiskMargin", RiskMargin ); 79 | } 80 | } 81 | } -------------------------------------------------------------------------------- /SuperImageEvolver/Core/Shape.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.IO; 4 | using System.Text; 5 | using System.Xml.Linq; 6 | 7 | namespace SuperImageEvolver { 8 | public sealed class Shape : ICloneable { 9 | public Shape() {} 10 | 11 | 12 | public Shape( Shape other ) { 13 | Color = other.Color; 14 | Points = (PointF[])other.Points.Clone(); 15 | OutlineColor = other.OutlineColor; 16 | } 17 | 18 | 19 | public Color Color; 20 | public PointF[] Points; 21 | public Shape PreviousState; 22 | public Color OutlineColor = Color.Transparent; 23 | 24 | 25 | public Shape( NBTag tag ) { 26 | Color = tag["Color"].GetColor(); 27 | var pointsTag = (NBTList)tag["Points"]; 28 | Points = new PointF[pointsTag.Tags.Length]; 29 | for( int i = 0; i < Points.Length; i++ ) { 30 | Points[i] = pointsTag[i].GetPointF(); 31 | } 32 | } 33 | 34 | 35 | public NBTag SerializeNBT() { 36 | NBTCompound tag = new NBTCompound( "Shape" ); 37 | tag.Append( "Color", Color ); 38 | NBTList points = new NBTList( "Points", NBTType.PointF, Points.Length ); 39 | for( int p = 0; p < Points.Length; p++ ) { 40 | points[p] = new NBTag( NBTType.PointF, null, Points[p], points ); 41 | } 42 | tag.Append( points ); 43 | return tag; 44 | } 45 | 46 | 47 | public Shape( Stream stream, int vertices ) { 48 | BinaryReader reader = new BinaryReader( stream ); 49 | Color = Color.FromArgb( reader.ReadInt32() ); 50 | Points = new PointF[vertices]; 51 | for( int p = 0; p < Points.Length; p++ ) { 52 | Points[p].X = reader.ReadSingle(); 53 | Points[p].Y = reader.ReadSingle(); 54 | } 55 | } 56 | 57 | 58 | public XElement SerializeSVG( XNamespace xmlns ) { 59 | XElement el = new XElement( xmlns + "polygon" ); 60 | StringBuilder sb = new StringBuilder(); 61 | foreach( PointF point in Points ) { 62 | sb.AppendFormat( "{0} {1} ", point.X, point.Y ); 63 | } 64 | el.Add( new XAttribute( "points", sb.ToString() ) ); 65 | el.Add( new XAttribute( "fill", String.Format( "rgb({0},{1},{2})", Color.R, Color.G, Color.B ) ) ); 66 | el.Add( new XAttribute( "opacity", Color.A / 255f ) ); 67 | return el; 68 | } 69 | 70 | 71 | public RectangleF GetBoundaries() { 72 | RectangleF rect = new RectangleF( int.MaxValue, int.MaxValue, 0, 0 ); 73 | for( int i = 0; i < Points.Length; i++ ) { 74 | rect.X = Math.Min( rect.X, Points[i].X ); 75 | rect.Y = Math.Min( rect.Y, Points[i].Y ); 76 | rect.Width = Math.Max( rect.Width, Points[i].X ); 77 | rect.Height = Math.Max( rect.Height, Points[i].Y ); 78 | } 79 | rect.Width -= rect.X; 80 | rect.Height -= rect.Y; 81 | return rect; 82 | } 83 | 84 | 85 | public object Clone() { 86 | return new Shape( this ); 87 | } 88 | 89 | 90 | public override string ToString() { 91 | return String.Format("Shape(" + Color + ")"); 92 | } 93 | } 94 | } -------------------------------------------------------------------------------- /SuperImageEvolver/Initializers/RadialInitializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Drawing; 4 | 5 | namespace SuperImageEvolver { 6 | public class RadialInitializerFactory : IModuleFactory { 7 | public Type ModuleType { 8 | get { return typeof( RadialInitializer ); } 9 | } 10 | 11 | public string ID { 12 | get { return "std.RadialInitializer.1"; } 13 | } 14 | 15 | public ModuleFunction Function { 16 | get { return ModuleFunction.Initializer; } 17 | } 18 | 19 | public ModulePreset[] Presets { 20 | get { 21 | return new[] { 22 | new ModulePreset( "Radial", () => ( new RadialInitializer( Color.Black ) ), this ) 23 | }; 24 | } 25 | } 26 | 27 | 28 | public IModule GetInstance() { 29 | return new RadialInitializer( Color.Black ); 30 | } 31 | } 32 | 33 | 34 | public sealed class RadialInitializer : IInitializer { 35 | public Color Color { get; set; } 36 | [DefaultValue(6)] 37 | public int MaxOverlap { get; set; } 38 | [DefaultValue(1)] 39 | public byte StartingAlpha { get; set; } 40 | [DefaultValue(2)] 41 | public int MinRadius { get; set; } 42 | [DefaultValue(0.5)] 43 | public double MaxRadiusRatio { get; set; } 44 | [DefaultValue(0)] 45 | public double Angle { get; set; } 46 | [DefaultValue(1)] 47 | public double Revolutions { get; set; } 48 | 49 | 50 | public RadialInitializer( Color color ) { 51 | Color = color; 52 | MaxOverlap = 6; 53 | StartingAlpha = 1; 54 | MinRadius = 2; 55 | MaxRadiusRatio = 0.5; 56 | Angle = 0; 57 | Revolutions = 1; 58 | } 59 | 60 | 61 | public DNA Initialize(Random rand, TaskState task) { 62 | var dna = new DNA { 63 | Shapes = new Shape[task.Shapes] 64 | }; 65 | for (int s = 0; s < task.Shapes; s++) { 66 | var shape = new Shape { 67 | Color = Color.FromArgb(StartingAlpha, Color.R, Color.G, Color.B), 68 | Points = new PointF[task.Vertices] 69 | }; 70 | int maxRadius = (int)Math.Round(Math.Min(task.ImageWidth, task.ImageHeight)*MaxRadiusRatio); 71 | int radius = rand.Next(MinRadius, maxRadius); 72 | var center = new Point(rand.Next(radius - MaxOverlap, task.ImageWidth - radius + MaxOverlap), 73 | rand.Next(radius - MaxOverlap, task.ImageHeight - radius + MaxOverlap)); 74 | for (int v = 0; v < task.Vertices; v++) { 75 | double t = v*Math.PI*2*Revolutions/task.Vertices + Angle*Math.PI*2 + Math.PI/task.Vertices; 76 | shape.Points[v].X = (float)(center.X + Math.Cos(t)*radius); 77 | shape.Points[v].Y = (float)(center.Y + Math.Sin(t)*radius); 78 | } 79 | if (shape.GetBoundaries().Width < 1 || shape.GetBoundaries().Height < 1) { 80 | continue; 81 | } 82 | dna.Shapes[s] = shape; 83 | } 84 | return dna; 85 | } 86 | 87 | 88 | object ICloneable.Clone() { 89 | return new RadialInitializer(Color) { 90 | MaxOverlap = MaxOverlap, 91 | StartingAlpha = StartingAlpha, 92 | MinRadius = MinRadius, 93 | MaxRadiusRatio = MaxRadiusRatio, 94 | Revolutions = Revolutions 95 | }; 96 | } 97 | 98 | 99 | void IModule.ReadSettings( NBTag tag ) {} 100 | 101 | void IModule.WriteSettings( NBTag tag ) {} 102 | } 103 | } -------------------------------------------------------------------------------- /SuperImageEvolver/Initializers/SegmentedInitializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | 4 | namespace SuperImageEvolver { 5 | public class SegmentedInitializerFactory : IModuleFactory { 6 | public Type ModuleType { 7 | get { return typeof( SegmentedInitializer ); } 8 | } 9 | 10 | public string ID { 11 | get { return "std.SegmentedInitializer.1"; } 12 | } 13 | 14 | public ModuleFunction Function { 15 | get { return ModuleFunction.Initializer; } 16 | } 17 | 18 | public ModulePreset[] Presets { 19 | get { 20 | return new[] { 21 | new ModulePreset( "Segmented", () => ( new SegmentedInitializer( Color.Black ) ), this ) 22 | }; 23 | } 24 | } 25 | 26 | 27 | public IModule GetInstance() { 28 | return new SegmentedInitializer( Color.Black ); 29 | } 30 | } 31 | 32 | 33 | public sealed class SegmentedInitializer : IInitializer { 34 | public Color Color { get; set; } 35 | public int MaxOverlap { get; set; } 36 | public byte StartingAlpha { get; set; } 37 | 38 | 39 | public SegmentedInitializer( Color color ) { 40 | Color = color; 41 | MaxOverlap = 6; 42 | StartingAlpha = 1; 43 | } 44 | 45 | 46 | public DNA Initialize( Random rand, TaskState task ) { 47 | DNA dna = new DNA { 48 | Shapes = new Shape[task.Shapes] 49 | }; 50 | int shapesPerSegment = task.Shapes / 9; 51 | int shapeCounter = 0; 52 | 53 | for( int i = 0; i < task.Shapes - shapesPerSegment * 9; i++ ) { 54 | Shape shape = new Shape { 55 | Color = Color.FromArgb( StartingAlpha, Color.R, Color.G, Color.B ), 56 | Points = new PointF[task.Vertices] 57 | }; 58 | for( int j = 0; j < shape.Points.Length; j++ ) { 59 | shape.Points[j] = new PointF( rand.NextFloat( -MaxOverlap, task.ImageWidth + MaxOverlap ), 60 | rand.NextFloat( -MaxOverlap, task.ImageHeight + MaxOverlap ) ); 61 | } 62 | dna.Shapes[i] = shape; 63 | shapeCounter++; 64 | } 65 | 66 | for( int x = 0; x < 3; x++ ) { 67 | for( int y = 0; y < 3; y++ ) { 68 | for( int i = 0; i < shapesPerSegment; i++ ) { 69 | Shape shape = new Shape { 70 | Color = Color.FromArgb( StartingAlpha, Color.R, Color.G, Color.B ), 71 | Points = new PointF[task.Vertices] 72 | }; 73 | for( int j = 0; j < shape.Points.Length; j++ ) { 74 | shape.Points[j] = 75 | new PointF( 76 | rand.NextFloat( task.ImageWidth / 3f * x - MaxOverlap, 77 | task.ImageWidth / 3f * ( x + 1 ) + MaxOverlap ), 78 | rand.NextFloat( task.ImageHeight / 3f * y - MaxOverlap, 79 | task.ImageHeight / 3f * ( y + 1 ) + MaxOverlap ) ); 80 | } 81 | dna.Shapes[shapeCounter] = shape; 82 | shapeCounter++; 83 | } 84 | } 85 | } 86 | return dna; 87 | } 88 | 89 | 90 | object ICloneable.Clone() { 91 | return new SegmentedInitializer( Color ) { 92 | MaxOverlap = MaxOverlap 93 | }; 94 | } 95 | 96 | 97 | void IModule.ReadSettings( NBTag tag ) {} 98 | 99 | void IModule.WriteSettings( NBTag tag ) {} 100 | } 101 | } -------------------------------------------------------------------------------- /SuperImageEvolver/GraphWindow.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.Drawing.Drawing2D; 5 | using System.Windows.Forms; 6 | 7 | namespace SuperImageEvolver { 8 | public sealed partial class GraphWindow : UserControl { 9 | PointF[] Points { get; set; } 10 | readonly Font font = new Font( FontFamily.GenericSansSerif, 15, FontStyle.Bold ); 11 | const float LogSteepness = 100; 12 | 13 | 14 | public GraphWindow() { 15 | InitializeComponent(); 16 | DoubleBuffered = true; 17 | } 18 | 19 | 20 | protected override void OnPaint( PaintEventArgs e ) { 21 | Graphics g = e.Graphics; 22 | g.Clear( Color.White ); 23 | for( int i = 1; i < 10; i++ ) { 24 | float level = (float)( Math.Log( i / 10f * LogSteepness + 1 ) / Math.Log( LogSteepness + 1 ) ) * Height; 25 | g.DrawLine( Pens.Silver, 0, level, Width, level ); 26 | } 27 | if( Points != null && Points.Length > 1 ) { 28 | try { 29 | g.DrawLines( Pens.Black, Points ); 30 | g.TranslateTransform(0,-1); 31 | g.DrawLines( Pens.Black, Points ); 32 | g.ResetTransform(); 33 | } catch( Exception ex ) { 34 | Console.WriteLine( ex ); 35 | } 36 | } 37 | if( MainForm.State != null && MainForm.State.BestMatch != null ) { 38 | g.DrawString( ( 1 - MainForm.State.BestMatch.Divergence ).ToString( "0.0000%" ), font, Brushes.Black, 39 | PointF.Empty ); 40 | } 41 | base.OnPaint( e ); 42 | } 43 | 44 | 45 | public void SetData( IList input, bool logXAxis, bool logYAxis, bool normalizeYStart, bool normalizeYEnd, 46 | bool normalizeXStart, bool normalizeXEnd ) { 47 | if (input.Count < 2) { 48 | Points = null; 49 | } else { 50 | int count = Math.Min(input.Count, 1000); 51 | int offset = input.Count -count; 52 | var output = new PointF[count]; 53 | 54 | float minX = float.MaxValue, 55 | maxX = float.MinValue, 56 | minY = float.MaxValue, 57 | maxY = float.MinValue; 58 | 59 | for (int i = 0; i < count; i++) { 60 | PointF pt = input[offset + i]; 61 | minX = Math.Min(minX, pt.X); 62 | maxX = Math.Max(maxX, pt.X); 63 | minY = Math.Min(minY, pt.Y); 64 | maxY = Math.Max(maxY, pt.Y); 65 | } 66 | 67 | if (!normalizeXStart) minX = 0; 68 | if (!normalizeYStart) minY = 0; 69 | if (!normalizeXEnd) maxX = 1; 70 | if (!normalizeYEnd) maxY = 1; 71 | 72 | float multiplierX = 1/(maxX - minX); 73 | float constantX = -minX/(maxX - minX); 74 | float multiplierY = 1/(maxY - minY); 75 | float constantY = -minY/(maxY - minY); 76 | 77 | double logScaleMultiplier = 1/Math.Log(LogSteepness + 1); 78 | 79 | for (int i = 0; i < count; i++) { 80 | output[i].X = input[offset+i].X*multiplierX + constantX; // normalize 81 | if (logXAxis) { 82 | output[i].X = (float)(Math.Log(output[i].X*LogSteepness + 1)*logScaleMultiplier); // scale 83 | } 84 | output[i].X = (Width - 1)*output[i].X; 85 | 86 | 87 | output[i].Y = input[offset+i].Y*multiplierY + constantY; // normalize 88 | if (logYAxis) { 89 | output[i].Y = (float)(Math.Log(output[i].Y*LogSteepness + 1)*logScaleMultiplier); // scale 90 | } 91 | output[i].Y = (Height - 1)*output[i].Y; 92 | } 93 | 94 | Points = output; 95 | } 96 | } 97 | } 98 | } -------------------------------------------------------------------------------- /SuperImageEvolver/ModuleSettingsDisplay.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace SuperImageEvolver { 2 | sealed partial class ModuleSettingsDisplay { 3 | /// 4 | /// Required designer variable. 5 | /// 6 | private System.ComponentModel.IContainer components = null; 7 | 8 | /// 9 | /// Clean up any resources being used. 10 | /// 11 | /// true if managed resources should be disposed; otherwise, false. 12 | protected override void Dispose( bool disposing ) { 13 | if( disposing && (components != null) ) { 14 | components.Dispose(); 15 | } 16 | base.Dispose( disposing ); 17 | } 18 | 19 | #region Windows Form Designer generated code 20 | 21 | /// 22 | /// Required method for Designer support - do not modify 23 | /// the contents of this method with the code editor. 24 | /// 25 | private void InitializeComponent() { 26 | this.pgGrid = new System.Windows.Forms.PropertyGrid(); 27 | this.bCancel = new System.Windows.Forms.Button(); 28 | this.bOK = new System.Windows.Forms.Button(); 29 | this.SuspendLayout(); 30 | // 31 | // pgGrid 32 | // 33 | this.pgGrid.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 34 | | System.Windows.Forms.AnchorStyles.Left) 35 | | System.Windows.Forms.AnchorStyles.Right))); 36 | this.pgGrid.Location = new System.Drawing.Point( 12, 12 ); 37 | this.pgGrid.Name = "pgGrid"; 38 | this.pgGrid.Size = new System.Drawing.Size( 274, 273 ); 39 | this.pgGrid.TabIndex = 0; 40 | // 41 | // bCancel 42 | // 43 | this.bCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 44 | this.bCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; 45 | this.bCancel.Location = new System.Drawing.Point( 211, 291 ); 46 | this.bCancel.Name = "bCancel"; 47 | this.bCancel.Size = new System.Drawing.Size( 75, 23 ); 48 | this.bCancel.TabIndex = 1; 49 | this.bCancel.Text = "Cancel"; 50 | this.bCancel.UseVisualStyleBackColor = true; 51 | // 52 | // bOK 53 | // 54 | this.bOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 55 | this.bOK.DialogResult = System.Windows.Forms.DialogResult.OK; 56 | this.bOK.Location = new System.Drawing.Point( 130, 291 ); 57 | this.bOK.Name = "bOK"; 58 | this.bOK.Size = new System.Drawing.Size( 75, 23 ); 59 | this.bOK.TabIndex = 2; 60 | this.bOK.Text = "OK"; 61 | this.bOK.UseVisualStyleBackColor = true; 62 | // 63 | // ModuleSettingsDisplay 64 | // 65 | this.AcceptButton = this.bOK; 66 | this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 13F ); 67 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 68 | this.CancelButton = this.bCancel; 69 | this.ClientSize = new System.Drawing.Size( 298, 326 ); 70 | this.Controls.Add( this.bOK ); 71 | this.Controls.Add( this.bCancel ); 72 | this.Controls.Add( this.pgGrid ); 73 | this.Name = "ModuleSettingsDisplay"; 74 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 75 | this.Text = "ModuleSettingsDisplay"; 76 | this.ResumeLayout( false ); 77 | 78 | } 79 | 80 | #endregion 81 | 82 | private System.Windows.Forms.PropertyGrid pgGrid; 83 | private System.Windows.Forms.Button bCancel; 84 | private System.Windows.Forms.Button bOK; 85 | } 86 | } -------------------------------------------------------------------------------- /SuperImageEvolver/Mutators/MediumMutator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | 4 | namespace SuperImageEvolver { 5 | public class MediumMutatorFactory : IModuleFactory { 6 | public Type ModuleType { 7 | get { return typeof( MediumMutator ); } 8 | } 9 | 10 | public string ID { 11 | get { return "std.MediumMutator.1"; } 12 | } 13 | 14 | public ModuleFunction Function { 15 | get { return ModuleFunction.Mutator; } 16 | } 17 | 18 | public ModulePreset[] Presets { 19 | get { 20 | return new[] { 21 | new ModulePreset( "Medium", () => new MediumMutator(), this ) 22 | }; 23 | } 24 | } 25 | 26 | 27 | public IModule GetInstance() { 28 | return new MediumMutator(); 29 | } 30 | } 31 | 32 | 33 | public sealed class MediumMutator : IMutator { 34 | DNA IMutator.Mutate( Random rand, DNA oldDNA, TaskState task ) { 35 | DNA newDNA = new DNA( oldDNA ); 36 | if( rand.Next( 20 ) == 0 ) { 37 | newDNA.SwapShapes( rand ); 38 | } else { 39 | MutateShape( rand, newDNA, newDNA.Shapes[rand.Next( newDNA.Shapes.Length )], task ); 40 | } 41 | 42 | return newDNA; 43 | } 44 | 45 | 46 | static void MutateShape( Random rand, DNA dna, Shape shape, TaskState task ) { 47 | int maxOverlap = task.ProjectOptions.MaxOverlap; 48 | shape.PreviousState = shape.Clone() as Shape; 49 | switch( rand.Next( 9 ) ) { 50 | case 0: 51 | shape.Color = Color.FromArgb( (byte)rand.Next( task.ProjectOptions.MinAlpha, 256 ), shape.Color.R, 52 | shape.Color.G, shape.Color.B ); 53 | dna.LastMutation = MutationType.ReplaceColor; 54 | break; 55 | case 1: 56 | shape.Color = Color.FromArgb( shape.Color.A, (byte)rand.Next( 256 ), shape.Color.G, shape.Color.B ); 57 | dna.LastMutation = MutationType.ReplaceColor; 58 | break; 59 | case 2: 60 | shape.Color = Color.FromArgb( shape.Color.A, shape.Color.R, (byte)rand.Next( 256 ), shape.Color.B ); 61 | dna.LastMutation = MutationType.ReplaceColor; 62 | break; 63 | case 3: 64 | shape.Color = Color.FromArgb( shape.Color.A, shape.Color.R, shape.Color.G, (byte)rand.Next( 256 ) ); 65 | dna.LastMutation = MutationType.ReplaceColor; 66 | break; 67 | case 4: 68 | case 5: 69 | shape.Points[rand.Next( shape.Points.Length )].X = rand.NextFloat( -maxOverlap, 70 | task.ImageWidth + maxOverlap ); 71 | dna.LastMutation = MutationType.ReplacePoint; 72 | break; 73 | case 6: 74 | case 7: 75 | shape.Points[rand.Next( shape.Points.Length )].Y = rand.NextFloat( -maxOverlap, 76 | task.ImageHeight + maxOverlap ); 77 | dna.LastMutation = MutationType.ReplacePoint; 78 | break; 79 | case 8: 80 | shape.Points[rand.Next( shape.Points.Length )].X = rand.NextFloat( -maxOverlap, 81 | task.ImageWidth + maxOverlap ); 82 | shape.Points[rand.Next( shape.Points.Length )].Y = rand.NextFloat( -maxOverlap, 83 | task.ImageHeight + maxOverlap ); 84 | dna.LastMutation = MutationType.ReplacePoints; 85 | break; 86 | } 87 | } 88 | 89 | 90 | object ICloneable.Clone() { 91 | return new MediumMutator(); 92 | } 93 | 94 | 95 | void IModule.ReadSettings( NBTag tag ) {} 96 | 97 | void IModule.WriteSettings( NBTag tag ) {} 98 | } 99 | } -------------------------------------------------------------------------------- /SuperImageEvolver/Canvas.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.Drawing.Drawing2D; 4 | using System.Windows.Forms; 5 | 6 | namespace SuperImageEvolver { 7 | sealed partial class Canvas : UserControl { 8 | public Canvas() { 9 | InitializeComponent(); 10 | DoubleBuffered = true; 11 | } 12 | 13 | 14 | public TaskState State { 15 | get { return state; } 16 | set { 17 | state = value; 18 | if( state != null ) { 19 | Size = new Size { 20 | Width = (int)Math.Ceiling( state.ImageWidth*Zoom ), 21 | Height = (int)Math.Ceiling( state.ImageHeight*Zoom ) 22 | }; 23 | } 24 | Invalidate(); 25 | } 26 | } 27 | 28 | TaskState state; 29 | 30 | 31 | public float Zoom { 32 | get { return zoom; } 33 | set { 34 | zoom = value; 35 | if( state != null ) { 36 | Size = new Size { 37 | Width = (int)Math.Ceiling( state.ImageWidth*Zoom ), 38 | Height = (int)Math.Ceiling( state.ImageHeight*Zoom ) 39 | }; 40 | } 41 | Invalidate(); 42 | } 43 | } 44 | 45 | float zoom = 1; 46 | 47 | 48 | public bool Wireframe { 49 | get { return wireframe; } 50 | set { 51 | wireframe = value; 52 | Invalidate(); 53 | } 54 | } 55 | 56 | bool wireframe; 57 | 58 | 59 | public bool ShowLastChange { 60 | get { return showLastChange; } 61 | set { 62 | showLastChange = value; 63 | Invalidate(); 64 | } 65 | } 66 | 67 | bool showLastChange; 68 | 69 | 70 | const string PlaceholderText = "best match"; 71 | 72 | protected override void OnPaint( PaintEventArgs e ) { 73 | Graphics g = e.Graphics; 74 | if( state != null && state.CurrentMatch != null ) { 75 | g.Clear( state.ProjectOptions.Matte ); 76 | e.Graphics.ScaleTransform( zoom, zoom ); 77 | DNA tempDNA = state.CurrentMatch; 78 | g.SmoothingMode = (state.Evaluator.Smooth ? SmoothingMode.HighQuality : SmoothingMode.HighSpeed); 79 | 80 | Pen wireframePen = new Pen( state.ProjectOptions.WireframeColor, 1/zoom ); 81 | 82 | for( int i = 0; i < tempDNA.Shapes.Length; i++ ) { 83 | g.FillPolygon(new SolidBrush(tempDNA.Shapes[i].Color), tempDNA.Shapes[i].Points, 84 | FillMode.Winding); 85 | if (Wireframe) { 86 | g.DrawPolygon(wireframePen, tempDNA.Shapes[i].Points); 87 | } 88 | } 89 | for (int i = 0; i < tempDNA.Shapes.Length; i++) { 90 | if (tempDNA.Shapes[i].OutlineColor != Color.Transparent) { 91 | wireframePen.Color = tempDNA.Shapes[i].OutlineColor; 92 | g.DrawPolygon(wireframePen, tempDNA.Shapes[i].Points); 93 | } 94 | } 95 | if( showLastChange ) { 96 | Pen lastChangePen1 = new Pen( state.ProjectOptions.LastChangeColor1, 2/zoom ); 97 | Pen lastChangePen2 = new Pen( state.ProjectOptions.LastChangeColor2, 1/zoom ); 98 | for( int i = 0; i < tempDNA.Shapes.Length; i++ ) { 99 | if( tempDNA.Shapes[i].PreviousState != null ) { 100 | g.DrawPolygon( lastChangePen1, tempDNA.Shapes[i].Points ); 101 | g.DrawPolygon( lastChangePen2, tempDNA.Shapes[i].PreviousState.Points ); 102 | } 103 | } 104 | } 105 | } else { 106 | g.Clear( Color.White ); 107 | SizeF align = g.MeasureString( PlaceholderText, Font ); 108 | g.DrawString( PlaceholderText, 109 | Font, 110 | Brushes.Black, 111 | Width/2f - align.Width/2, 112 | Height/2f - align.Height/2 ); 113 | } 114 | base.OnPaint( e ); 115 | } 116 | } 117 | } -------------------------------------------------------------------------------- /SuperImageEvolver/DNAImportWindow.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace SuperImageEvolver { 2 | sealed partial class DNAImportWindow { 3 | /// 4 | /// Required designer variable. 5 | /// 6 | private System.ComponentModel.IContainer components = null; 7 | 8 | /// 9 | /// Clean up any resources being used. 10 | /// 11 | /// true if managed resources should be disposed; otherwise, false. 12 | protected override void Dispose( bool disposing ) { 13 | if( disposing && (components != null) ) { 14 | components.Dispose(); 15 | } 16 | base.Dispose( disposing ); 17 | } 18 | 19 | #region Windows Form Designer generated code 20 | 21 | /// 22 | /// Required method for Designer support - do not modify 23 | /// the contents of this method with the code editor. 24 | /// 25 | private void InitializeComponent() { 26 | this.tPasteArea = new System.Windows.Forms.TextBox(); 27 | this.bImport = new System.Windows.Forms.Button(); 28 | this.bCancel = new System.Windows.Forms.Button(); 29 | this.label1 = new System.Windows.Forms.Label(); 30 | this.SuspendLayout(); 31 | // 32 | // tPasteArea 33 | // 34 | this.tPasteArea.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 35 | | System.Windows.Forms.AnchorStyles.Left) 36 | | System.Windows.Forms.AnchorStyles.Right))); 37 | this.tPasteArea.Location = new System.Drawing.Point( 12, 12 ); 38 | this.tPasteArea.Multiline = true; 39 | this.tPasteArea.Name = "tPasteArea"; 40 | this.tPasteArea.Size = new System.Drawing.Size( 206, 112 ); 41 | this.tPasteArea.TabIndex = 0; 42 | this.tPasteArea.TextChanged += new System.EventHandler( this.tPasteArea_TextChanged ); 43 | // 44 | // bImport 45 | // 46 | this.bImport.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 47 | this.bImport.DialogResult = System.Windows.Forms.DialogResult.OK; 48 | this.bImport.Enabled = false; 49 | this.bImport.Location = new System.Drawing.Point( 12, 188 ); 50 | this.bImport.Name = "bImport"; 51 | this.bImport.Size = new System.Drawing.Size( 100, 23 ); 52 | this.bImport.TabIndex = 1; 53 | this.bImport.Text = "Import"; 54 | this.bImport.UseVisualStyleBackColor = true; 55 | // 56 | // bCancel 57 | // 58 | this.bCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 59 | this.bCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; 60 | this.bCancel.Location = new System.Drawing.Point( 118, 188 ); 61 | this.bCancel.Name = "bCancel"; 62 | this.bCancel.Size = new System.Drawing.Size( 100, 23 ); 63 | this.bCancel.TabIndex = 2; 64 | this.bCancel.Text = "Cancel"; 65 | this.bCancel.UseVisualStyleBackColor = true; 66 | // 67 | // label1 68 | // 69 | this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); 70 | this.label1.AutoSize = true; 71 | this.label1.Location = new System.Drawing.Point( 12, 137 ); 72 | this.label1.Name = "label1"; 73 | this.label1.Size = new System.Drawing.Size( 201, 39 ); 74 | this.label1.TabIndex = 3; 75 | this.label1.Text = "WARNING: You are about to replace the\r\ncurrent DNA with this. The only way to\r\nun" + 76 | "do this will be to load an earlier save."; 77 | // 78 | // DNAImportWindow 79 | // 80 | this.AcceptButton = this.bImport; 81 | this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 13F ); 82 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 83 | this.CancelButton = this.bCancel; 84 | this.ClientSize = new System.Drawing.Size( 230, 223 ); 85 | this.Controls.Add( this.label1 ); 86 | this.Controls.Add( this.bCancel ); 87 | this.Controls.Add( this.bImport ); 88 | this.Controls.Add( this.tPasteArea ); 89 | this.Name = "DNAImportWindow"; 90 | this.Text = "Importing DNA"; 91 | this.ResumeLayout( false ); 92 | this.PerformLayout(); 93 | 94 | } 95 | 96 | #endregion 97 | 98 | private System.Windows.Forms.TextBox tPasteArea; 99 | private System.Windows.Forms.Button bImport; 100 | private System.Windows.Forms.Button bCancel; 101 | private System.Windows.Forms.Label label1; 102 | } 103 | } -------------------------------------------------------------------------------- /SuperImageEvolver/Evaluators/LumaEvaluator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.Drawing.Drawing2D; 4 | using System.Drawing.Imaging; 5 | 6 | namespace SuperImageEvolver { 7 | public class LumaEvaluatorFactory : IModuleFactory { 8 | public Type ModuleType { 9 | get { return typeof( LumaEvaluator ); } 10 | } 11 | 12 | public string ID { 13 | get { return "std.LumaEvaluator.1"; } 14 | } 15 | 16 | public ModuleFunction Function { 17 | get { return ModuleFunction.Evaluator; } 18 | } 19 | 20 | public ModulePreset[] Presets { 21 | get { 22 | return new[] { 23 | new ModulePreset( "RGB+Luma (Fast)", () => ( new LumaEvaluator( false ) ), this ), 24 | new ModulePreset( "RGB+Luma (Smooth)", () => ( new LumaEvaluator( true ) ), this ) 25 | }; 26 | } 27 | } 28 | 29 | 30 | public IModule GetInstance() { 31 | return new LumaEvaluator(); 32 | } 33 | } 34 | 35 | 36 | sealed unsafe class LumaEvaluator : IEvaluator { 37 | 38 | public void Initialize( TaskState state ) {} 39 | 40 | public bool Smooth { get; set; } 41 | 42 | public LumaEvaluator() {} 43 | 44 | 45 | public LumaEvaluator( bool smooth ) { 46 | Smooth = smooth; 47 | } 48 | 49 | 50 | public double CalculateDivergence( Bitmap testImage, DNA dna, TaskState state, double maxAcceptableDivergence ) { 51 | double maxDivergence = state.ImageWidth * state.ImageHeight * 2 * 255; 52 | long sum = 0; 53 | long roundedMax = (long)( maxAcceptableDivergence * maxDivergence + 1 ); 54 | using( Graphics g = Graphics.FromImage( testImage ) ) { 55 | g.Clear( state.ProjectOptions.Matte ); 56 | g.SmoothingMode = ( Smooth ? SmoothingMode.HighQuality : SmoothingMode.HighSpeed ); 57 | for( int i = 0; i < dna.Shapes.Length; i++ ) { 58 | g.FillPolygon( new SolidBrush( dna.Shapes[i].Color ), dna.Shapes[i].Points, FillMode.Alternate ); 59 | } 60 | } 61 | 62 | BitmapData testData = testImage.LockBits( new Rectangle( Point.Empty, testImage.Size ), 63 | ImageLockMode.ReadOnly, 64 | PixelFormat.Format32bppArgb ); 65 | for( int i = 0; i < state.ImageHeight; i++ ) { 66 | byte* originalPointer = (byte*)state.WorkingImageData.Scan0 + state.WorkingImageData.Stride * i; 67 | byte* testPointer = (byte*)testData.Scan0 + testData.Stride * i; 68 | for( int j = 0; j < state.ImageWidth; j++ ) { 69 | 70 | /* 71 | int originalLuma = (299 * originalPointer[2] + 587 * originalPointer[1] + 114 * *originalPointer) / 1000; 72 | int testLuma = (299 * testPointer[2] + 587 * testPointer[1] + 114 * *testPointer) / 1000; 73 | int deltaLuma = (299 * Math.Abs( originalPointer[2] - testPointer[2] ) + 74 | 587 * Math.Abs( originalPointer[1] - testPointer[1] ) + 75 | 114 * Math.Abs( *originalPointer - *testPointer )) / 1500; // 0-511 76 | 77 | int deltaU = Math.Abs( (originalPointer[2] - originalLuma) - (testPointer[2] - testLuma) ); // 0-255 78 | int deltaV = Math.Abs( (*originalPointer - originalLuma) - (*testPointer - testLuma) ); // 0-255 79 | 80 | sum += deltaLuma + (deltaU + deltaV)/2; 81 | */ 82 | 83 | 84 | int originalLumi = 85 | ( Math.Min( Math.Min( originalPointer[2], originalPointer[1] ), *originalPointer ) + 86 | Math.Max( Math.Max( originalPointer[2], originalPointer[1] ), *originalPointer ) ) / 2; 87 | int testLumi = ( Math.Min( Math.Min( testPointer[2], testPointer[1] ), *testPointer ) + 88 | Math.Max( Math.Max( testPointer[2], testPointer[1] ), *testPointer ) ) / 2; 89 | 90 | byte lumiDelta = (byte)Math.Abs( originalLumi - testLumi ); 91 | 92 | 93 | int oringinalChroma = 94 | ( Math.Max( Math.Max( originalPointer[2], originalPointer[1] ), *originalPointer ) - 95 | Math.Min( Math.Min( originalPointer[2], originalPointer[1] ), *originalPointer ) ); 96 | int testChroma = ( Math.Max( Math.Max( testPointer[2], testPointer[1] ), *testPointer ) - 97 | Math.Min( Math.Min( testPointer[2], testPointer[1] ), *testPointer ) ); 98 | 99 | 100 | sum += lumiDelta * 2 + (byte)( Math.Abs( oringinalChroma - testChroma ) * lumiDelta / 255 ); 101 | 102 | originalPointer += 4; 103 | testPointer += 4; 104 | } 105 | if( sum > roundedMax ) break; 106 | } 107 | testImage.UnlockBits( testData ); 108 | return sum / maxDivergence; 109 | } 110 | 111 | 112 | object ICloneable.Clone() { 113 | return new LumaEvaluator( Smooth ); 114 | } 115 | 116 | 117 | void IModule.ReadSettings( NBTag tag ) {} 118 | 119 | void IModule.WriteSettings( NBTag tag ) {} 120 | } 121 | } -------------------------------------------------------------------------------- /SuperImageEvolver/Evaluators/SloppyRGBEvaluator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.Drawing.Drawing2D; 4 | using System.Drawing.Imaging; 5 | 6 | namespace SuperImageEvolver { 7 | public class SloppyRGBEvaluatorFactory : IModuleFactory { 8 | public Type ModuleType { 9 | get { return typeof( SloppyRGBEvaluator ); } 10 | } 11 | 12 | public string ID { 13 | get { return "std.SloppyRGBEvaluator.1"; } 14 | } 15 | 16 | public ModuleFunction Function { 17 | get { return ModuleFunction.Evaluator; } 18 | } 19 | 20 | public ModulePreset[] Presets { 21 | get { 22 | return new[] { 23 | new ModulePreset( "RGB (Sloppy)", () => ( new SloppyRGBEvaluator() ), this ) 24 | }; 25 | } 26 | } 27 | 28 | 29 | public IModule GetInstance() { 30 | return new SloppyRGBEvaluator(); 31 | } 32 | } 33 | 34 | 35 | sealed unsafe class SloppyRGBEvaluator : IEvaluator { 36 | 37 | double maxDivergence; 38 | Bitmap halfResImage; 39 | BitmapData halfResData; 40 | 41 | public bool Smooth { get; set; } 42 | public bool Emphasized { get; set; } 43 | public double EmphasisAmount { get; set; } 44 | 45 | 46 | public SloppyRGBEvaluator() { 47 | Smooth = true; 48 | Emphasized = false; 49 | EmphasisAmount = 2; 50 | } 51 | 52 | 53 | public void Initialize( TaskState state ) { 54 | halfResImage = new Bitmap( state.ImageWidth / 2, state.ImageHeight / 2, PixelFormat.Format32bppArgb ); 55 | using( Graphics g = Graphics.FromImage( halfResImage ) ) { 56 | g.InterpolationMode = InterpolationMode.HighQualityBicubic; 57 | g.SmoothingMode = SmoothingMode.HighQuality; 58 | g.DrawImage( state.WorkingImageCopy, 0, 0, halfResImage.Width, halfResImage.Height ); 59 | } 60 | halfResData = halfResImage.LockBits( new Rectangle( Point.Empty, halfResImage.Size ), 61 | ImageLockMode.ReadOnly, 62 | PixelFormat.Format32bppArgb ); 63 | } 64 | 65 | 66 | public double CalculateDivergence( Bitmap testImage, DNA dna, TaskState state, double maxAcceptableDivergence ) { 67 | if( Emphasized ) { 68 | if( EmphasisAmount == 2 ) { 69 | maxDivergence = 3L * state.ImageWidth / 2L * state.ImageHeight / 2L * 255L * 255L; 70 | } else { 71 | maxDivergence = 72 | (long)( 3L * state.ImageWidth / 2L * state.ImageHeight / 2L * Math.Pow( 255, EmphasisAmount ) ); 73 | } 74 | } else { 75 | maxDivergence = 3L * state.ImageWidth / 2L * state.ImageHeight / 2L * 255L; 76 | } 77 | 78 | long sum = 0; 79 | long roundedMax = (long)( maxAcceptableDivergence * maxDivergence + 1 ); 80 | using( Graphics g = Graphics.FromImage( testImage ) ) { 81 | g.Clear( state.ProjectOptions.Matte ); 82 | g.Transform = new Matrix( .5f, 0, 0, .5f, 0, 0 ); 83 | g.SmoothingMode = ( Smooth ? SmoothingMode.HighQuality : SmoothingMode.HighSpeed ); 84 | for( int i = 0; i < dna.Shapes.Length; i++ ) { 85 | g.FillPolygon( new SolidBrush( dna.Shapes[i].Color ), dna.Shapes[i].Points, FillMode.Alternate ); 86 | } 87 | } 88 | 89 | BitmapData testData = testImage.LockBits( new Rectangle( Point.Empty, testImage.Size ), 90 | ImageLockMode.ReadOnly, 91 | PixelFormat.Format32bppArgb ); 92 | for( int i = 0; i < state.ImageHeight / 2; i++ ) { 93 | byte* originalPointer = (byte*)halfResData.Scan0 + halfResData.Stride * i; 94 | byte* testPointer = (byte*)testData.Scan0 + testData.Stride * i; 95 | for( int j = 0; j < state.ImageWidth / 2; j++ ) { 96 | int b = Math.Abs( *originalPointer - *testPointer ); 97 | int g = Math.Abs( originalPointer[1] - testPointer[1] ); 98 | int r = Math.Abs( originalPointer[2] - testPointer[2] ); 99 | if( Emphasized ) { 100 | if( EmphasisAmount == 2 ) { 101 | sum += r * r + b * b + g * g; 102 | } else { 103 | sum += 104 | (long) 105 | ( Math.Pow( r, EmphasisAmount ) + Math.Pow( g, EmphasisAmount ) + 106 | Math.Pow( b, EmphasisAmount ) ); 107 | } 108 | } else { 109 | sum += r + b + g; 110 | } 111 | originalPointer += 4; 112 | testPointer += 4; 113 | } 114 | if( sum > roundedMax ) { 115 | sum = (long)maxDivergence; 116 | break; 117 | } 118 | } 119 | testImage.UnlockBits( testData ); 120 | if( Emphasized ) { 121 | return Math.Pow( sum / maxDivergence, 1 / EmphasisAmount ); 122 | } else { 123 | return sum / maxDivergence; 124 | } 125 | } 126 | 127 | 128 | object ICloneable.Clone() { 129 | return new SloppyRGBEvaluator { 130 | Smooth = Smooth, 131 | Emphasized = Emphasized, 132 | EmphasisAmount = EmphasisAmount 133 | }; 134 | } 135 | 136 | 137 | void IModule.ReadSettings( NBTag tag ) {} 138 | 139 | void IModule.WriteSettings( NBTag tag ) {} 140 | } 141 | } -------------------------------------------------------------------------------- /SuperImageEvolver/Mutators/SoftMutator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | 4 | namespace SuperImageEvolver { 5 | public class SoftMutatorFactory : IModuleFactory { 6 | public Type ModuleType { 7 | get { return typeof( SoftMutator ); } 8 | } 9 | 10 | public string ID { 11 | get { return "std.SoftMutator.1"; } 12 | } 13 | 14 | public ModuleFunction Function { 15 | get { return ModuleFunction.Mutator; } 16 | } 17 | 18 | public ModulePreset[] Presets { 19 | get { 20 | return new[] { 21 | new ModulePreset( "Soft", () => ( new SoftMutator( 8, 12 ) ), this ), 22 | new ModulePreset( "Softer", () => ( new SoftMutator( 1, 2 ) ), this ) 23 | }; 24 | } 25 | } 26 | 27 | 28 | public IModule GetInstance() { 29 | return new SoftMutator( 1, 2 ); 30 | } 31 | } 32 | 33 | 34 | sealed class SoftMutator : IMutator { 35 | public int MaxPosDelta { get; set; } 36 | public int MaxColorDelta { get; set; } 37 | 38 | 39 | public SoftMutator() { 40 | MaxPosDelta = 12; 41 | MaxColorDelta = 12; 42 | } 43 | 44 | 45 | public SoftMutator( int maxColorDelta, int maxPosDelta ) 46 | : this() { 47 | MaxColorDelta = maxColorDelta; 48 | MaxPosDelta = maxPosDelta; 49 | } 50 | 51 | 52 | public DNA Mutate( Random rand, DNA oldDNA, TaskState task ) { 53 | DNA newDNA = new DNA( oldDNA ); 54 | if( rand.Next( 20 ) == 0 ) { 55 | newDNA.SwapShapes( rand ); 56 | } else { 57 | MutateShape( rand, newDNA, newDNA.Shapes[rand.Next( newDNA.Shapes.Length )], task ); 58 | } 59 | 60 | return newDNA; 61 | } 62 | 63 | 64 | void MutateShape( Random rand, DNA dna, Shape shape, TaskState task ) { 65 | int maxOverlap = task.ProjectOptions.MaxOverlap; 66 | shape.PreviousState = shape.Clone() as Shape; 67 | int colorDelta = (byte)rand.Next( 1, MaxColorDelta + 1 ) * ( rand.Next( 2 ) == 0 ? 1 : -1 ); 68 | float posDelta = (float)rand.NextDouble() * MaxPosDelta * ( rand.Next( 2 ) == 0 ? 1 : -1 ); 69 | switch( rand.Next( 9 ) ) { 70 | case 0: 71 | shape.Color = 72 | Color.FromArgb( 73 | Math.Max( task.ProjectOptions.MinAlpha, Math.Min( 255, shape.Color.A + colorDelta ) ), 74 | shape.Color.R, shape.Color.G, shape.Color.B ); 75 | dna.LastMutation = MutationType.AdjustColor; 76 | break; 77 | case 1: 78 | shape.Color = Color.FromArgb( shape.Color.A, 79 | Math.Max( 0, Math.Min( 255, shape.Color.R + colorDelta ) ), 80 | shape.Color.G, shape.Color.B ); 81 | dna.LastMutation = MutationType.AdjustColor; 82 | break; 83 | case 2: 84 | shape.Color = Color.FromArgb( shape.Color.A, shape.Color.R, 85 | Math.Max( 0, Math.Min( 255, shape.Color.G + colorDelta ) ), 86 | shape.Color.B ); 87 | dna.LastMutation = MutationType.AdjustColor; 88 | break; 89 | case 3: 90 | shape.Color = Color.FromArgb( shape.Color.A, shape.Color.R, shape.Color.G, 91 | Math.Max( 0, Math.Min( 255, shape.Color.B + colorDelta ) ) ); 92 | dna.LastMutation = MutationType.AdjustColor; 93 | break; 94 | case 4: 95 | case 5: 96 | int pt1 = rand.Next( shape.Points.Length ); 97 | shape.Points[pt1].X = Math.Max( -maxOverlap, 98 | Math.Min( task.ImageWidth - 1 + maxOverlap, 99 | shape.Points[pt1].X + posDelta ) ); 100 | dna.LastMutation = MutationType.AdjustPoint; 101 | break; 102 | case 6: 103 | case 7: 104 | int pt2 = rand.Next( shape.Points.Length ); 105 | shape.Points[pt2].Y = Math.Max( -maxOverlap, 106 | Math.Min( task.ImageHeight - 1 + maxOverlap, 107 | shape.Points[pt2].Y + posDelta ) ); 108 | dna.LastMutation = MutationType.AdjustPoint; 109 | break; 110 | case 8: 111 | int pt3 = rand.Next( shape.Points.Length ); 112 | shape.Points[pt3].X = Math.Max( -maxOverlap, 113 | Math.Min( task.ImageWidth - 1 + maxOverlap, 114 | shape.Points[pt3].X + posDelta ) ); 115 | shape.Points[pt3].Y = Math.Max( -maxOverlap, 116 | Math.Min( task.ImageHeight - 1 + maxOverlap, 117 | shape.Points[pt3].Y + posDelta ) ); 118 | dna.LastMutation = MutationType.AdjustPoints; 119 | break; 120 | } 121 | } 122 | 123 | 124 | object ICloneable.Clone() { 125 | return new SoftMutator { 126 | MaxColorDelta = MaxColorDelta, 127 | MaxPosDelta = MaxPosDelta 128 | }; 129 | } 130 | 131 | 132 | void IModule.ReadSettings( NBTag tag ) {} 133 | 134 | void IModule.WriteSettings( NBTag tag ) {} 135 | } 136 | } -------------------------------------------------------------------------------- /SuperImageEvolver/DNAImportWindow.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /SuperImageEvolver/ModuleSettingsDisplay.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /SuperImageEvolver/Mutators/HardMutator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | 4 | namespace SuperImageEvolver { 5 | public class HardMutatorFactory : IModuleFactory { 6 | public Type ModuleType { 7 | get { return typeof( HardMutator ); } 8 | } 9 | 10 | public string ID { 11 | get { return "std.HardMutator.1"; } 12 | } 13 | 14 | public ModuleFunction Function { 15 | get { return ModuleFunction.Mutator; } 16 | } 17 | 18 | public ModulePreset[] Presets { 19 | get { 20 | return new[] { 21 | new ModulePreset( "Hard", () => new HardMutator(), this ) 22 | }; 23 | } 24 | } 25 | 26 | 27 | public IModule GetInstance() { 28 | return new HardMutator(); 29 | } 30 | } 31 | 32 | 33 | sealed class HardMutator : IMutator { 34 | 35 | public DNA Mutate( Random rand, DNA oldDNA, TaskState task ) { 36 | DNA newDNA = new DNA( oldDNA ); 37 | int s1 = rand.Next( newDNA.Shapes.Length ); 38 | Shape shape = newDNA.Shapes[s1]; 39 | switch( rand.Next( 20 ) ) { 40 | case 0: 41 | newDNA.SwapShapes( rand ); 42 | break; 43 | case 1: 44 | RandomizeShape( rand, shape, task ); 45 | newDNA.LastMutation = MutationType.ReplaceShape; 46 | break; 47 | default: 48 | MutateShape( rand, newDNA, shape, task ); 49 | break; 50 | } 51 | return newDNA; 52 | } 53 | 54 | 55 | void MutateShape( Random rand, DNA dna, Shape shape, TaskState task ) { 56 | shape.PreviousState = shape.Clone() as Shape; 57 | switch( rand.Next( 10 ) ) { 58 | case 0: 59 | shape.Color = Color.FromArgb( (byte)rand.Next( task.ProjectOptions.MinAlpha, 256 ), shape.Color.R, 60 | shape.Color.G, shape.Color.B ); 61 | dna.LastMutation = MutationType.ReplaceColor; 62 | if( rand.Next( 10 ) == 0 ) { 63 | MutateMultiplePoints( shape, rand, dna, task ); 64 | dna.LastMutation = MutationType.ReplaceShape; 65 | } 66 | break; 67 | 68 | case 1: 69 | shape.Color = Color.FromArgb( shape.Color.A, rand.NextByte(), shape.Color.G, shape.Color.B ); 70 | dna.LastMutation = MutationType.ReplaceColor; 71 | if( rand.Next( 10 ) == 0 ) { 72 | MutateMultiplePoints( shape, rand, dna, task ); 73 | dna.LastMutation = MutationType.ReplaceShape; 74 | } 75 | break; 76 | 77 | case 2: 78 | shape.Color = Color.FromArgb( shape.Color.A, shape.Color.R, rand.NextByte(), shape.Color.B ); 79 | dna.LastMutation = MutationType.ReplaceColor; 80 | if( rand.Next( 10 ) == 0 ) { 81 | MutateMultiplePoints( shape, rand, dna, task ); 82 | dna.LastMutation = MutationType.ReplaceShape; 83 | } 84 | break; 85 | 86 | case 3: 87 | shape.Color = Color.FromArgb( shape.Color.A, shape.Color.R, shape.Color.G, rand.NextByte() ); 88 | dna.LastMutation = MutationType.ReplaceColor; 89 | if( rand.Next( 10 ) == 0 ) { 90 | MutateMultiplePoints( shape, rand, dna, task ); 91 | dna.LastMutation = MutationType.ReplaceShape; 92 | } 93 | break; 94 | 95 | default: 96 | MutateMultiplePoints( shape, rand, dna, task ); 97 | break; 98 | } 99 | } 100 | 101 | 102 | void MutateMultiplePoints( Shape shape, Random rand, DNA dna, TaskState task ) { 103 | int index = rand.Next( shape.Points.Length ); 104 | shape.Points[index] = MutatePoint( rand, dna, shape.Points[index], task ); 105 | if( rand.Next( 2 ) == 0 ) { 106 | index = ( index + 1 ) % shape.Points.Length; 107 | shape.Points[index] = MutatePoint( rand, dna, shape.Points[index], task ); 108 | if( rand.Next( 2 ) == 0 ) { 109 | index = ( index + 1 ) % shape.Points.Length; 110 | shape.Points[index] = MutatePoint( rand, dna, shape.Points[index], task ); 111 | } 112 | dna.LastMutation = MutationType.ReplacePoints; 113 | } else { 114 | dna.LastMutation = MutationType.ReplacePoint; 115 | } 116 | } 117 | 118 | 119 | static PointF MutatePoint( Random rand, DNA dna, PointF point, TaskState task ) { 120 | int maxOverlap = task.ProjectOptions.MaxOverlap; 121 | switch( rand.Next( 5 ) ) { 122 | case 0: 123 | case 1: 124 | point.X = rand.NextFloat( -maxOverlap, task.ImageWidth + maxOverlap ); 125 | dna.LastMutation = MutationType.ReplacePoint; 126 | break; 127 | case 2: 128 | case 3: 129 | point.Y = rand.NextFloat( -maxOverlap, task.ImageHeight + maxOverlap ); 130 | dna.LastMutation = MutationType.ReplacePoint; 131 | break; 132 | case 4: 133 | point.X = rand.NextFloat( -maxOverlap, task.ImageWidth + maxOverlap ); 134 | point.Y = rand.NextFloat( -maxOverlap, task.ImageHeight + maxOverlap ); 135 | dna.LastMutation = MutationType.ReplacePoints; 136 | break; 137 | } 138 | return point; 139 | } 140 | 141 | 142 | static void RandomizeShape( Random rand, Shape shape, TaskState task ) { 143 | int maxOverlap = task.ProjectOptions.MaxOverlap; 144 | shape.PreviousState = shape.Clone() as Shape; 145 | shape.Color = Color.FromArgb( rand.Next( task.ProjectOptions.MinAlpha, 256 ), rand.Next( 256 ), 146 | rand.Next( 256 ), rand.Next( 256 ) ); 147 | for( int i = 0; i < shape.Points.Length; i++ ) { 148 | shape.Points[i] = new PointF( rand.NextFloat( -maxOverlap, task.ImageWidth + maxOverlap ), 149 | rand.NextFloat( -maxOverlap, task.ImageHeight + maxOverlap ) ); 150 | } 151 | } 152 | 153 | 154 | object ICloneable.Clone() { 155 | return this; 156 | } 157 | 158 | 159 | void IModule.ReadSettings( NBTag tag ) {} 160 | 161 | void IModule.WriteSettings( NBTag tag ) {} 162 | } 163 | } -------------------------------------------------------------------------------- /SuperImageEvolver/Evaluators/RGBEvaluator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.Drawing.Drawing2D; 4 | using System.Drawing.Imaging; 5 | 6 | namespace SuperImageEvolver { 7 | public class RGBEvaluatorFactory : IModuleFactory { 8 | public Type ModuleType { 9 | get { return typeof( RGBEvaluator ); } 10 | } 11 | 12 | public string ID { 13 | get { return "std.RGBEvaluator.1"; } 14 | } 15 | 16 | public ModuleFunction Function { 17 | get { return ModuleFunction.Evaluator; } 18 | } 19 | 20 | public ModulePreset[] Presets { 21 | get { 22 | return new[] { 23 | new ModulePreset( "RGB (Fast)", () => ( new RGBEvaluator( false ) ), this ), 24 | new ModulePreset( "RGB (Smooth)", () => ( new RGBEvaluator( true ) ), this ) 25 | }; 26 | } 27 | } 28 | 29 | 30 | public IModule GetInstance() { 31 | return new RGBEvaluator(); 32 | } 33 | } 34 | 35 | 36 | sealed unsafe class RGBEvaluator : IEvaluator { 37 | 38 | public bool Smooth { get; set; } 39 | public bool Emphasized { get; set; } 40 | public double EmphasisAmount { get; set; } 41 | 42 | double maxDivergence; 43 | 44 | 45 | public RGBEvaluator() { 46 | Smooth = true; 47 | Emphasized = false; 48 | EmphasisAmount = 2; 49 | } 50 | 51 | 52 | public RGBEvaluator( bool smooth ) 53 | : this() { 54 | Smooth = smooth; 55 | } 56 | 57 | 58 | public void Initialize( TaskState state ) {} 59 | 60 | 61 | public double CalculateDivergence( Bitmap testImage, DNA dna, TaskState state, double maxAcceptableDivergence ) { 62 | 63 | if( Emphasized ) { 64 | if( EmphasisAmount == 2 ) { 65 | maxDivergence = 3L * state.ImageWidth * state.ImageHeight * 255L * 255L; 66 | } else { 67 | maxDivergence = 3L * state.ImageWidth * state.ImageHeight * Math.Pow( 255, EmphasisAmount ); 68 | } 69 | } else { 70 | maxDivergence = 3L * state.ImageWidth * state.ImageHeight * 255L; 71 | } 72 | 73 | double sum = 0; 74 | double roundedMax = ( maxAcceptableDivergence * maxDivergence + 1 ); 75 | using( Graphics g = Graphics.FromImage( testImage ) ) { 76 | g.Clear( state.ProjectOptions.Matte ); 77 | g.SmoothingMode = ( Smooth ? SmoothingMode.HighQuality : SmoothingMode.HighSpeed ); 78 | 79 | for( int i = 0; i < dna.Shapes.Length; i++ ) { 80 | g.FillPolygon( new SolidBrush( dna.Shapes[i].Color ), dna.Shapes[i].Points, FillMode.Alternate ); 81 | } 82 | } 83 | byte* originalPointer, testPointer; 84 | 85 | BitmapData testData = testImage.LockBits( new Rectangle( Point.Empty, testImage.Size ), 86 | ImageLockMode.ReadOnly, 87 | PixelFormat.Format32bppArgb ); 88 | 89 | if( Emphasized ) { 90 | if( EmphasisAmount == 2 ) { 91 | for( int i = 0; i < state.ImageHeight; i++ ) { 92 | originalPointer = (byte*)state.WorkingImageData.Scan0 + state.WorkingImageData.Stride * i; 93 | testPointer = (byte*)testData.Scan0 + testData.Stride * i; 94 | for( int j = 0; j < state.ImageWidth; j++ ) { 95 | int b = Math.Abs( *originalPointer - *testPointer ); 96 | int g = Math.Abs( originalPointer[1] - testPointer[1] ); 97 | int r = Math.Abs( originalPointer[2] - testPointer[2] ); 98 | sum += r * r + b * b + g * g; 99 | originalPointer += 4; 100 | testPointer += 4; 101 | } 102 | if( sum > roundedMax ) { 103 | sum = maxDivergence; 104 | break; 105 | } 106 | } 107 | } else { 108 | for( int i = 0; i < state.ImageHeight; i++ ) { 109 | originalPointer = (byte*)state.WorkingImageData.Scan0 + state.WorkingImageData.Stride*i; 110 | testPointer = (byte*)testData.Scan0 + testData.Stride*i; 111 | for( int j = 0; j < state.ImageWidth; j++ ) { 112 | int b = Math.Abs( *originalPointer - *testPointer ); 113 | int g = Math.Abs( originalPointer[1] - testPointer[1] ); 114 | int r = Math.Abs( originalPointer[2] - testPointer[2] ); 115 | sum += Math.Pow( r, EmphasisAmount ) + Math.Pow( g, EmphasisAmount ) + 116 | Math.Pow( b, EmphasisAmount ); 117 | originalPointer += 4; 118 | testPointer += 4; 119 | } 120 | if( sum > roundedMax ) { 121 | sum = maxDivergence; 122 | break; 123 | } 124 | } 125 | } 126 | } else { 127 | for( int i = 0; i < state.ImageHeight; i++ ) { 128 | originalPointer = (byte*)state.WorkingImageData.Scan0 + state.WorkingImageData.Stride * i; 129 | testPointer = (byte*)testData.Scan0 + testData.Stride * i; 130 | for( int j = 0; j < state.ImageWidth; j++ ) { 131 | int b = Math.Abs( *originalPointer - *testPointer ); 132 | int g = Math.Abs( originalPointer[1] - testPointer[1] ); 133 | int r = Math.Abs( originalPointer[2] - testPointer[2] ); 134 | sum += r + b + g; 135 | originalPointer += 4; 136 | testPointer += 4; 137 | } 138 | if( sum > roundedMax ) { 139 | sum = maxDivergence; 140 | break; 141 | } 142 | } 143 | } 144 | 145 | testImage.UnlockBits( testData ); 146 | if( Emphasized ) { 147 | return Math.Pow( sum / maxDivergence, 1 / EmphasisAmount ); 148 | } else { 149 | return sum / maxDivergence; 150 | } 151 | } 152 | 153 | 154 | object ICloneable.Clone() { 155 | return new RGBEvaluator { 156 | Smooth = Smooth, 157 | Emphasized = Emphasized, 158 | EmphasisAmount = EmphasisAmount 159 | }; 160 | } 161 | 162 | 163 | void IModule.ReadSettings( NBTag tag ) {} 164 | 165 | void IModule.WriteSettings( NBTag tag ) {} 166 | } 167 | } -------------------------------------------------------------------------------- /SuperImageEvolver/Mutators/HardishMutator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | 4 | namespace SuperImageEvolver { 5 | public class HardishMutatorFactory : IModuleFactory { 6 | public Type ModuleType { 7 | get { return typeof( HardishMutator ); } 8 | } 9 | 10 | public string ID { 11 | get { return "std.HardishMutator.1"; } 12 | } 13 | 14 | public ModuleFunction Function { 15 | get { return ModuleFunction.Mutator; } 16 | } 17 | 18 | public ModulePreset[] Presets { 19 | get { 20 | return new[] { 21 | new ModulePreset( "Hardish", () => new HardishMutator(), this ) 22 | }; 23 | } 24 | } 25 | 26 | 27 | public IModule GetInstance() { 28 | return new HardishMutator(); 29 | } 30 | } 31 | 32 | 33 | sealed class HardishMutator : IMutator { 34 | 35 | public int MaxPosDelta { get; set; } 36 | public int MaxColorDelta { get; set; } 37 | 38 | 39 | public HardishMutator() { 40 | MaxPosDelta = 10; 41 | MaxColorDelta = 10; 42 | } 43 | 44 | 45 | public DNA Mutate( Random rand, DNA oldDNA, TaskState task ) { 46 | DNA newDNA = new DNA( oldDNA ); 47 | int s1 = rand.Next( newDNA.Shapes.Length ); 48 | Shape shape = newDNA.Shapes[s1]; 49 | if( rand.Next( 20 ) == 0 ) { 50 | newDNA.SwapShapes( rand ); 51 | } else { 52 | MutateShape( rand, newDNA, shape, task ); 53 | } 54 | return newDNA; 55 | } 56 | 57 | 58 | 59 | void MutateShape( Random rand, DNA dna, Shape shape, TaskState task ) { 60 | shape.PreviousState = shape.Clone() as Shape; 61 | int colorDelta = (byte)rand.Next( 1, MaxColorDelta + 1 ) * ( rand.Next( 2 ) == 0 ? 1 : -1 ); 62 | switch( rand.Next( 10 ) ) { 63 | case 0: 64 | shape.Color = 65 | Color.FromArgb( 66 | Math.Max( task.ProjectOptions.MinAlpha, Math.Min( 255, shape.Color.A + colorDelta ) ), 67 | shape.Color.R, shape.Color.G, shape.Color.B ); 68 | dna.LastMutation = MutationType.AdjustColor; 69 | if( rand.Next( 10 ) == 0 ) { 70 | MutateMultiplePoints( shape, rand, dna, task ); 71 | dna.LastMutation = MutationType.ReplaceShape; 72 | } 73 | break; 74 | 75 | case 1: 76 | shape.Color = Color.FromArgb( shape.Color.A, 77 | Math.Max( 0, Math.Min( 255, shape.Color.R + colorDelta ) ), 78 | shape.Color.G, shape.Color.B ); 79 | dna.LastMutation = MutationType.AdjustColor; 80 | if( rand.Next( 10 ) == 0 ) { 81 | MutateMultiplePoints( shape, rand, dna, task ); 82 | dna.LastMutation = MutationType.ReplaceShape; 83 | } 84 | break; 85 | 86 | case 2: 87 | shape.Color = Color.FromArgb( shape.Color.A, shape.Color.R, 88 | Math.Max( 0, Math.Min( 255, shape.Color.G + colorDelta ) ), 89 | shape.Color.B ); 90 | dna.LastMutation = MutationType.AdjustColor; 91 | if( rand.Next( 10 ) == 0 ) { 92 | MutateMultiplePoints( shape, rand, dna, task ); 93 | dna.LastMutation = MutationType.ReplaceShape; 94 | } 95 | break; 96 | 97 | case 3: 98 | shape.Color = Color.FromArgb( shape.Color.A, shape.Color.R, shape.Color.G, 99 | Math.Max( 0, Math.Min( 255, shape.Color.B + colorDelta ) ) ); 100 | dna.LastMutation = MutationType.AdjustColor; 101 | if( rand.Next( 10 ) == 0 ) { 102 | MutateMultiplePoints( shape, rand, dna, task ); 103 | dna.LastMutation = MutationType.ReplaceShape; 104 | } 105 | break; 106 | 107 | default: 108 | MutateMultiplePoints( shape, rand, dna, task ); 109 | break; 110 | } 111 | } 112 | 113 | 114 | void MutateMultiplePoints( Shape shape, Random rand, DNA dna, TaskState task ) { 115 | int index = rand.Next( shape.Points.Length ); 116 | shape.Points[index] = MutatePoint( rand, dna, shape.Points[index], task ); 117 | if( rand.Next( 2 ) == 0 ) { 118 | index = ( index + 1 ) % shape.Points.Length; 119 | shape.Points[index] = MutatePoint( rand, dna, shape.Points[index], task ); 120 | if( rand.Next( 2 ) == 0 ) { 121 | index = ( index + 1 ) % shape.Points.Length; 122 | shape.Points[index] = MutatePoint( rand, dna, shape.Points[index], task ); 123 | } 124 | dna.LastMutation = MutationType.AdjustPoints; 125 | } else { 126 | dna.LastMutation = MutationType.AdjustPoint; 127 | } 128 | } 129 | 130 | 131 | PointF MutatePoint( Random rand, DNA dna, PointF point, TaskState task ) { 132 | float posDelta = (float)rand.NextDouble() * MaxPosDelta * ( rand.Next( 2 ) == 0 ? 1 : -1 ); 133 | int maxOverlap = task.ProjectOptions.MaxOverlap; 134 | switch( rand.Next( 5 ) ) { 135 | case 0: 136 | case 1: 137 | point.X = Math.Max( -maxOverlap, Math.Min( task.ImageWidth - 1 + maxOverlap, point.X + posDelta ) ); 138 | dna.LastMutation = MutationType.AdjustPoint; 139 | break; 140 | case 2: 141 | case 3: 142 | point.Y = Math.Max( -maxOverlap, Math.Min( task.ImageHeight - 1 + maxOverlap, point.Y + posDelta ) ); 143 | dna.LastMutation = MutationType.AdjustPoint; 144 | break; 145 | case 4: 146 | point.X = Math.Max( -maxOverlap, Math.Min( task.ImageWidth - 1 + maxOverlap, point.X + posDelta ) ); 147 | point.Y = Math.Max( -maxOverlap, Math.Min( task.ImageHeight - 1 + maxOverlap, point.Y + posDelta ) ); 148 | dna.LastMutation = MutationType.AdjustPoints; 149 | break; 150 | } 151 | return point; 152 | } 153 | 154 | 155 | object ICloneable.Clone() { 156 | return new HardishMutator { 157 | MaxColorDelta = MaxColorDelta, 158 | MaxPosDelta = MaxPosDelta 159 | }; 160 | } 161 | 162 | 163 | void IModule.ReadSettings( NBTag tag ) {} 164 | 165 | void IModule.WriteSettings( NBTag tag ) {} 166 | } 167 | } -------------------------------------------------------------------------------- /SuperImageEvolver/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.269 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace SuperImageEvolver.Properties { 12 | /// 13 | /// A strongly-typed resource class, for looking up localized strings, etc. 14 | /// 15 | // This class was auto-generated by the StronglyTypedResourceBuilder 16 | // class via a tool like ResGen or Visual Studio. 17 | // To add or remove a member, edit your .ResX file then rerun ResGen 18 | // with the /str option, or rebuild your VS project. 19 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 20 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 21 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 22 | internal class Resources { 23 | 24 | private static global::System.Resources.ResourceManager resourceMan; 25 | 26 | private static global::System.Globalization.CultureInfo resourceCulture; 27 | 28 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 29 | internal Resources() { 30 | } 31 | 32 | /// 33 | /// Returns the cached ResourceManager instance used by this class. 34 | /// 35 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 36 | internal static global::System.Resources.ResourceManager ResourceManager { 37 | get { 38 | if (object.ReferenceEquals(resourceMan, null)) { 39 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SuperImageEvolver.Properties.Resources", typeof(Resources).Assembly); 40 | resourceMan = temp; 41 | } 42 | return resourceMan; 43 | } 44 | } 45 | 46 | /// 47 | /// Overrides the current thread's CurrentUICulture property for all 48 | /// resource lookups using this strongly typed resource class. 49 | /// 50 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 51 | internal static global::System.Globalization.CultureInfo Culture { 52 | get { 53 | return resourceCulture; 54 | } 55 | set { 56 | resourceCulture = value; 57 | } 58 | } 59 | 60 | internal static System.Drawing.Bitmap arrow_stop_180 { 61 | get { 62 | object obj = ResourceManager.GetObject("arrow_stop_180", resourceCulture); 63 | return ((System.Drawing.Bitmap)(obj)); 64 | } 65 | } 66 | 67 | internal static System.Drawing.Bitmap control { 68 | get { 69 | object obj = ResourceManager.GetObject("control", resourceCulture); 70 | return ((System.Drawing.Bitmap)(obj)); 71 | } 72 | } 73 | 74 | internal static System.Drawing.Bitmap control_stop_square { 75 | get { 76 | object obj = ResourceManager.GetObject("control_stop_square", resourceCulture); 77 | return ((System.Drawing.Bitmap)(obj)); 78 | } 79 | } 80 | 81 | internal static System.Drawing.Bitmap disk { 82 | get { 83 | object obj = ResourceManager.GetObject("disk", resourceCulture); 84 | return ((System.Drawing.Bitmap)(obj)); 85 | } 86 | } 87 | 88 | internal static System.Drawing.Bitmap disk__pencil { 89 | get { 90 | object obj = ResourceManager.GetObject("disk__pencil", resourceCulture); 91 | return ((System.Drawing.Bitmap)(obj)); 92 | } 93 | } 94 | 95 | internal static System.Drawing.Bitmap disk_black { 96 | get { 97 | object obj = ResourceManager.GetObject("disk_black", resourceCulture); 98 | return ((System.Drawing.Bitmap)(obj)); 99 | } 100 | } 101 | 102 | internal static System.Drawing.Bitmap document { 103 | get { 104 | object obj = ResourceManager.GetObject("document", resourceCulture); 105 | return ((System.Drawing.Bitmap)(obj)); 106 | } 107 | } 108 | 109 | internal static System.Drawing.Bitmap document_export { 110 | get { 111 | object obj = ResourceManager.GetObject("document_export", resourceCulture); 112 | return ((System.Drawing.Bitmap)(obj)); 113 | } 114 | } 115 | 116 | internal static System.Drawing.Bitmap document_import { 117 | get { 118 | object obj = ResourceManager.GetObject("document_import", resourceCulture); 119 | return ((System.Drawing.Bitmap)(obj)); 120 | } 121 | } 122 | 123 | internal static System.Drawing.Bitmap folder_horizontal_open { 124 | get { 125 | object obj = ResourceManager.GetObject("folder_horizontal_open", resourceCulture); 126 | return ((System.Drawing.Bitmap)(obj)); 127 | } 128 | } 129 | 130 | internal static System.Drawing.Bitmap gear { 131 | get { 132 | object obj = ResourceManager.GetObject("gear", resourceCulture); 133 | return ((System.Drawing.Bitmap)(obj)); 134 | } 135 | } 136 | 137 | internal static System.Drawing.Bitmap image_export { 138 | get { 139 | object obj = ResourceManager.GetObject("image_export", resourceCulture); 140 | return ((System.Drawing.Bitmap)(obj)); 141 | } 142 | } 143 | 144 | internal static System.Drawing.Bitmap images { 145 | get { 146 | object obj = ResourceManager.GetObject("images", resourceCulture); 147 | return ((System.Drawing.Bitmap)(obj)); 148 | } 149 | } 150 | 151 | internal static System.Drawing.Bitmap information { 152 | get { 153 | object obj = ResourceManager.GetObject("information", resourceCulture); 154 | return ((System.Drawing.Bitmap)(obj)); 155 | } 156 | } 157 | 158 | internal static System.Drawing.Bitmap layer_shape_polygon { 159 | get { 160 | object obj = ResourceManager.GetObject("layer_shape_polygon", resourceCulture); 161 | return ((System.Drawing.Bitmap)(obj)); 162 | } 163 | } 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | -------------------------------------------------------------------------------- /SuperImageEvolver/MainForm.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | False 122 | 123 | 124 | False 125 | 126 | 127 | False 128 | 129 | 130 | False 131 | 132 | 133 | False 134 | 135 | 136 | 442, 17 137 | 138 | 139 | 230, 17 140 | 141 | 142 | 355, 17 143 | 144 | 145 | 132, 17 146 | 147 | -------------------------------------------------------------------------------- /SuperImageEvolver/Core/DNA.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.IO; 4 | 5 | namespace SuperImageEvolver { 6 | public sealed class DNA : ICloneable { 7 | public DNA() {} 8 | 9 | 10 | public DNA(DNA other) { 11 | Shapes = new Shape[other.Shapes.Length]; 12 | for (int i = 0; i < Shapes.Length; i++) { 13 | Shapes[i] = new Shape(other.Shapes[i]); 14 | } 15 | Divergence = other.Divergence; 16 | } 17 | 18 | 19 | public object Clone() { 20 | return new DNA(this); 21 | } 22 | 23 | 24 | public MutationType LastMutation; 25 | 26 | public Shape[] Shapes; 27 | public double Divergence; 28 | 29 | 30 | public DNA(NBTag tag) { 31 | Divergence = tag["Divergence"].GetDouble(); 32 | var shapesTag = (NBTList)tag["Shapes"]; 33 | Shapes = new Shape[shapesTag.Tags.Length]; 34 | for (int i = 0; i < Shapes.Length; i++) { 35 | Shapes[i] = new Shape(shapesTag[i]); 36 | } 37 | } 38 | 39 | 40 | public NBTag SerializeNBT(string tagName) { 41 | NBTCompound compound = new NBTCompound(tagName); 42 | compound.Append("Divergence", Divergence); 43 | NBTList tag = new NBTList("Shapes", NBTType.Compound, Shapes.Length); 44 | for (int i = 0; i < Shapes.Length; i++) { 45 | tag[i] = Shapes[i].SerializeNBT(); 46 | } 47 | compound.Append(tag); 48 | return compound; 49 | } 50 | 51 | 52 | public DNA(Stream stream, int shapes, int vertices) { 53 | Shapes = new Shape[shapes]; 54 | for (int i = 0; i < Shapes.Length; i++) { 55 | Shapes[i] = new Shape(stream, vertices); 56 | } 57 | } 58 | 59 | 60 | // Take a polygon and divide it into two, using the slot of a sacrificial polygon for second half 61 | public void DivideShape(Random rand, int shapeToDivide, int shapeToSacrifice) { 62 | Shape original = Shapes[shapeToDivide]; 63 | int points = original.Points.Length; 64 | 65 | // Figure out which dividing vertex produces the shortest dividing edge. 66 | PointF divisionVertex1 = default(PointF); 67 | PointF divisionVertex2 = default(PointF); 68 | double shortestDividingEdgeLength = Double.MaxValue; 69 | Shape shifted = original; 70 | for (int shiftAmount = 0; shiftAmount < points; shiftAmount++) { 71 | Shape shiftedGuess = ShiftPoints(original, shiftAmount); 72 | // Find the two dividing vertices 73 | PointF vertexGuess1; 74 | if (points%2 == 1) { 75 | // odd number of points 76 | vertexGuess1 = shiftedGuess.Points[points/2]; 77 | } else { 78 | // even number of points 79 | vertexGuess1 = Lerp(shiftedGuess.Points[points/2 - 1], shiftedGuess.Points[points/2], 0.5f); 80 | } 81 | PointF vertexGuess2 = Lerp(shiftedGuess.Points[0], shiftedGuess.Points[points - 1], 0.5f); 82 | double dividingEdgeLength = 83 | Math.Sqrt((vertexGuess1.X - vertexGuess2.X)*(vertexGuess1.X - vertexGuess2.X) + 84 | (vertexGuess1.Y - vertexGuess2.Y)*(vertexGuess1.Y - vertexGuess2.Y)); 85 | if (dividingEdgeLength < shortestDividingEdgeLength) { 86 | shortestDividingEdgeLength = dividingEdgeLength; 87 | shifted = shiftedGuess; 88 | divisionVertex1 = vertexGuess1; 89 | divisionVertex2 = vertexGuess2; 90 | } 91 | } 92 | 93 | var half1 = new Shape(shifted); 94 | var half2 = new Shape(shifted); 95 | 96 | // Construct half-shape #1 97 | half1.Points[0] = divisionVertex1; 98 | half1.Points[1] = divisionVertex2; 99 | for (int i = 0; i < points/2; i++) { 100 | half1.Points[i + 2] = shifted.Points[i]; 101 | } 102 | 103 | // Construct half-shape #2 104 | half2.Points[0] = divisionVertex2; 105 | half2.Points[1] = divisionVertex1; 106 | for (int i = 0; i < points/2; i++) { 107 | half2.Points[i + 2] = shifted.Points[points/2 + i + 1]; 108 | } 109 | 110 | // Randomly redistribute extra vertices for each half (if there are any) 111 | int extraVertices = (points - 3)/2; 112 | Subdivide(rand, half1, extraVertices); 113 | Subdivide(rand, half2, extraVertices); 114 | 115 | // Write back the changes 116 | Shapes[shapeToDivide] = half1; 117 | Shapes[shapeToSacrifice] = half2; 118 | half1.OutlineColor = Color.Green; 119 | half2.OutlineColor = Color.Red; 120 | ShiftShapeIndex(shapeToSacrifice, shapeToDivide); 121 | } 122 | 123 | 124 | static Shape ShiftPoints(Shape shape, int shift) { 125 | var copy = new Shape(shape); 126 | int offset = shift%shape.Points.Length; 127 | Array.Copy(shape.Points, offset, copy.Points, 0, shape.Points.Length - offset); 128 | Array.Copy(shape.Points, 0, copy.Points, shape.Points.Length - offset, offset); 129 | return copy; 130 | } 131 | 132 | 133 | // Randomly redistribute extra vertices by dividing edges of a given polygon 134 | static void Subdivide(Random rand, Shape shape, int extraVertices) { 135 | int points = shape.Points.Length; 136 | int assignedPoints = points - extraVertices; 137 | while (assignedPoints < points) { 138 | int p1 = rand.Next(0, assignedPoints); 139 | if (p1 == assignedPoints - 1) { 140 | shape.Points[assignedPoints] = Lerp(shape.Points[p1], shape.Points[0], 0.5f); 141 | } else { 142 | Array.Copy(shape.Points, p1 + 1, shape.Points, p1 + 2, assignedPoints - p1 - 1); 143 | shape.Points[p1 + 1] = Lerp(shape.Points[p1], shape.Points[p1 + 2], 0.5f); 144 | } 145 | assignedPoints++; 146 | } 147 | } 148 | 149 | 150 | // Find a point on the Linear intERPolant of two given points, separated from p1 by given amount 151 | static PointF Lerp(PointF p1, PointF p2, float amount) { 152 | return new PointF { 153 | X = p1.X + (p2.X - p1.X)*amount, 154 | Y = p1.Y + (p2.Y - p1.Y)*amount 155 | }; 156 | } 157 | 158 | 159 | void ShiftShapeIndex(int source, int dest) { 160 | Shape shape = Shapes[source]; 161 | if (source < dest) { 162 | for (int i = source; i < dest; i++) { 163 | Shapes[i] = Shapes[i + 1]; 164 | } 165 | } else { 166 | for (int i = source; i > dest; i--) { 167 | Shapes[i] = Shapes[i - 1]; 168 | } 169 | } 170 | Shapes[dest] = shape; 171 | } 172 | 173 | 174 | public void SwapShapes(Random rand) { 175 | int s1 = rand.Next(Shapes.Length); 176 | Shape shape = Shapes[s1]; 177 | shape.PreviousState = shape.Clone() as Shape; 178 | if (rand.Next(2) == 0) { 179 | int s2; 180 | do { 181 | s2 = rand.Next(Shapes.Length); 182 | } while (s1 == s2); 183 | ShiftShapeIndex(s1, s2); 184 | } else { 185 | int s2 = rand.Next(Shapes.Length); 186 | Shapes[s1] = Shapes[s2]; 187 | Shapes[s2] = shape; 188 | } 189 | LastMutation = MutationType.SwapShapes; 190 | } 191 | } 192 | } 193 | -------------------------------------------------------------------------------- /SuperImageEvolver/Core/TaskState.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.Drawing.Imaging; 5 | using System.IO; 6 | using System.Xml.Linq; 7 | 8 | namespace SuperImageEvolver { 9 | public sealed class TaskState { 10 | public int Shapes, Vertices; 11 | public int ImageWidth, ImageHeight; 12 | 13 | public volatile DNA CurrentMatch; 14 | public volatile DNA BestMatch; 15 | 16 | public ProjectOptions ProjectOptions = new ProjectOptions(); 17 | public int ImprovementCounter, MutationCounter, RiskyMoveCounter, FailedRiskCounter; 18 | 19 | public Bitmap OriginalImage; 20 | public Bitmap WorkingImageCopy; 21 | public Bitmap WorkingImageCopyClone; 22 | public BitmapData WorkingImageData; 23 | public string ProjectFileName; 24 | 25 | public readonly List MutationDataLog = new List(); 26 | 27 | public volatile IInitializer Initializer = new SegmentedInitializer( Color.Black ); 28 | public volatile IMutator Mutator = new HardMutator(); 29 | public volatile IEvaluator Evaluator = new RGBEvaluator( false ); 30 | 31 | public DateTime TaskStart; 32 | public DateTime LastImprovementTime; 33 | public long LastImprovementMutationCount; 34 | 35 | public bool HasChangedSinceSave = true; 36 | 37 | public const int FormatVersion = 1; 38 | 39 | public readonly object ImprovementLock = new object(); 40 | 41 | public readonly Dictionary MutationCounts = new Dictionary(); 42 | public readonly Dictionary MutationImprovements = new Dictionary(); 43 | 44 | 45 | public void SetEvaluator( IEvaluator newEvaluator ) { 46 | lock( ImprovementLock ) { 47 | if( OriginalImage != null && BestMatch != null ) { 48 | using( Bitmap testCanvas = new Bitmap( ImageWidth, ImageHeight ) ) { 49 | newEvaluator.Initialize( this ); 50 | BestMatch.Divergence = newEvaluator.CalculateDivergence( testCanvas, BestMatch, this, 1 ); 51 | CurrentMatch = BestMatch; 52 | } 53 | } 54 | Evaluator = newEvaluator; 55 | } 56 | } 57 | 58 | 59 | public NBTCompound SerializeNBT() { 60 | HasChangedSinceSave = false; 61 | NBTCompound tag = new NBTCompound( "SuperImageEvolver" ); 62 | tag.Append( "FormatVersion", FormatVersion ); 63 | tag.Append( "Shapes", Shapes ); 64 | tag.Append( "Vertices", Vertices ); 65 | tag.Append( "ImprovementCounter", ImprovementCounter ); 66 | tag.Append( "MutationCounter", MutationCounter ); 67 | tag.Append( "RiskyMoveCounter", RiskyMoveCounter ); 68 | tag.Append( "ElapsedTime", DateTime.UtcNow.Subtract( TaskStart ).Ticks ); 69 | 70 | tag.Append( ProjectOptions.SerializeNBT() ); 71 | 72 | tag.Append( BestMatch.SerializeNBT( "BestMatch" ) ); 73 | 74 | NBTag initializerTag = ModuleManager.WriteModule( "Initializer", Initializer ); 75 | tag.Append( initializerTag ); 76 | 77 | NBTag mutatorTag = ModuleManager.WriteModule( "Mutator", Mutator ); 78 | tag.Append( mutatorTag ); 79 | 80 | NBTag evaluatorTag = ModuleManager.WriteModule( "Evaluator", Evaluator ); 81 | tag.Append( evaluatorTag ); 82 | 83 | byte[] imageData; 84 | using( MemoryStream ms = new MemoryStream() ) { 85 | lock( OriginalImage ) { 86 | OriginalImage.Save( ms, ImageFormat.Png ); 87 | } 88 | ms.Flush(); 89 | imageData = new byte[ms.Length]; 90 | Buffer.BlockCopy( ms.GetBuffer(), 0, imageData, 0, imageData.Length ); 91 | } 92 | 93 | tag.Append( "ImageData", imageData ); 94 | 95 | List statTags = new List(); 96 | foreach( MutationType mtype in Enum.GetValues( typeof( MutationType ) ) ) { 97 | NBTCompound stat = new NBTCompound( "MutationTypeStat" ); 98 | stat.Append( "Type", mtype.ToString() ); 99 | stat.Append( "Count", MutationCounts[mtype] ); 100 | stat.Append( "Sum", MutationImprovements[mtype] ); 101 | statTags.Add( stat ); 102 | } 103 | var stats = new NBTList( "MutationStats", NBTType.Compound, statTags.ToArray() ); 104 | tag.Append( stats ); 105 | 106 | return tag; 107 | } 108 | 109 | 110 | public TaskState( NBTag tag ) { 111 | if( FormatVersion != tag["FormatVersion"].GetInt() ) throw new FormatException( "Incompatible format." ); 112 | Shapes = tag["Shapes"].GetInt(); 113 | Vertices = tag["Vertices"].GetInt(); 114 | ImprovementCounter = tag["ImprovementCounter"].GetInt(); 115 | MutationCounter = tag["MutationCounter"].GetInt(); 116 | TaskStart = DateTime.UtcNow.Subtract( TimeSpan.FromTicks( tag["ElapsedTime"].GetLong() ) ); 117 | 118 | ProjectOptions = new ProjectOptions( tag["ProjectOptions"] ); 119 | 120 | BestMatch = new DNA( tag["BestMatch"] ); 121 | CurrentMatch = BestMatch; 122 | 123 | Initializer = (IInitializer)ModuleManager.ReadModule( tag["Initializer"] ); 124 | Mutator = (IMutator)ModuleManager.ReadModule( tag["Mutator"] ); 125 | Evaluator = (IEvaluator)ModuleManager.ReadModule( tag["Evaluator"] ); 126 | 127 | byte[] imageBytes = tag["ImageData"].GetBytes(); 128 | using( MemoryStream ms = new MemoryStream( imageBytes ) ) { 129 | OriginalImage = new Bitmap( ms ); 130 | } 131 | 132 | var statsTag = (NBTList)tag["MutationStats"]; 133 | foreach( NBTag stat in statsTag ) { 134 | MutationType mutationType = (MutationType)Enum.Parse( typeof( MutationType ), stat["Type"].GetString() ); 135 | MutationCounts[mutationType] = stat["Count"].GetInt(); 136 | MutationImprovements[mutationType] = stat["Sum"].GetDouble(); 137 | } 138 | } 139 | 140 | 141 | public TaskState() { 142 | foreach( MutationType mutype in Enum.GetValues( typeof( MutationType ) ) ) { 143 | MutationCounts[mutype] = 0; 144 | MutationImprovements[mutype] = 0; 145 | } 146 | } 147 | 148 | 149 | public XDocument SerializeSVG() { 150 | XDocument doc = new XDocument(); 151 | XNamespace svg = "http://www.w3.org/2000/svg"; 152 | XElement root = new XElement( svg + "svg", 153 | new XAttribute( "xmlns", svg ), 154 | new XAttribute( XNamespace.Xmlns + "xlink", "http://www.w3.org/1999/xlink" ), 155 | new XAttribute( "width", ImageWidth ), 156 | new XAttribute( "height", ImageHeight ) ); 157 | 158 | if( ProjectOptions.Matte != Color.White ) { 159 | string matteRGB = String.Format( "rgb({0},{1},{2})", 160 | ProjectOptions.Matte.R, 161 | ProjectOptions.Matte.G, 162 | ProjectOptions.Matte.B ); 163 | XElement fill = new XElement( svg+ "rect", 164 | new XAttribute( "x", 0 ), 165 | new XAttribute( "y", 0 ), 166 | new XAttribute( "width", ImageWidth ), 167 | new XAttribute( "height", ImageHeight ), 168 | new XAttribute( "fill", matteRGB ), 169 | new XAttribute( "fill-opacity", ProjectOptions.Matte.A/255f ) ); 170 | root.Add( fill ); 171 | } 172 | 173 | DNA currentBestMatch = BestMatch; 174 | foreach( Shape shape in currentBestMatch.Shapes ) { 175 | root.Add( shape.SerializeSVG( svg ) ); 176 | } 177 | doc.Add( root ); 178 | 179 | return doc; 180 | } 181 | } 182 | } -------------------------------------------------------------------------------- /SuperImageEvolver/SuperImageEvolver.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.30729 7 | 2.0 8 | {F0E25CA0-3887-4BE7-BB3D-EF40DEA7F1B8} 9 | WinExe 10 | Properties 11 | SuperImageEvolver 12 | SuperImageEvolver 13 | v3.5 14 | 512 15 | SuperImageEvolver.Program 16 | 17 | 18 | 3.5 19 | 20 | 21 | 22 | true 23 | full 24 | false 25 | bin\Debug\ 26 | DEBUG;TRACE 27 | prompt 28 | 4 29 | true 30 | AllRules.ruleset 31 | 32 | 33 | pdbonly 34 | true 35 | bin\Release\ 36 | 37 | 38 | prompt 39 | 4 40 | true 41 | Off 42 | AllRules.ruleset 43 | 44 | 45 | 46 | 47 | 3.5 48 | 49 | 50 | 51 | 52 | 53 | 3.5 54 | 55 | 56 | 57 | 58 | UserControl 59 | 60 | 61 | Canvas.cs 62 | 63 | 64 | 65 | 66 | UserControl 67 | 68 | 69 | DiffCanvas.cs 70 | 71 | 72 | 73 | Form 74 | 75 | 76 | DNAImportWindow.cs 77 | 78 | 79 | 80 | 81 | 82 | 83 | UserControl 84 | 85 | 86 | GraphWindow.cs 87 | 88 | 89 | 90 | 91 | 92 | 93 | Form 94 | 95 | 96 | MainForm.cs 97 | 98 | 99 | 100 | 101 | 102 | Form 103 | 104 | 105 | ModuleSettingsDisplay.cs 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | Component 122 | 123 | 124 | DNAImportWindow.cs 125 | 126 | 127 | MainForm.cs 128 | 129 | 130 | ModuleSettingsDisplay.cs 131 | 132 | 133 | ResXFileCodeGenerator 134 | Resources.Designer.cs 135 | Designer 136 | 137 | 138 | True 139 | Resources.resx 140 | True 141 | 142 | 143 | SettingsSingleFileGenerator 144 | Settings.Designer.cs 145 | 146 | 147 | True 148 | Settings.settings 149 | True 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 208 | -------------------------------------------------------------------------------- /SuperImageEvolver/Core/ModuleManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Reflection; 7 | 8 | namespace SuperImageEvolver { 9 | public static class ModuleManager { 10 | static readonly Dictionary FactoriesById = new Dictionary(); 11 | static readonly Dictionary Presets = new Dictionary(); 12 | static readonly Dictionary FactoriesByType = new Dictionary(); 13 | 14 | 15 | public static Dictionary GetPresets( ModuleFunction function ) { 16 | return Presets.Where( p => p.Value.Factory.Function == function ).ToDictionary( k => k.Key, v => v.Value ); 17 | } 18 | 19 | 20 | public static void LoadAllPluginAssemblies( string path ) { 21 | foreach( string file in Directory.GetFiles( path, "*.SIE.dll" ) ) { 22 | LoadFactories( Assembly.LoadFile( file ) ); 23 | } 24 | } 25 | 26 | 27 | public static void LoadFactories( Assembly assembly ) { 28 | foreach( Type type in assembly.GetTypes() ) { 29 | if( type.GetInterfaces().Contains( typeof( IModuleFactory ) ) ) { 30 | object newFactory = type.GetConstructor( Type.EmptyTypes ).Invoke( new object[0] ); 31 | AddModule( newFactory as IModuleFactory ); 32 | } 33 | } 34 | } 35 | 36 | 37 | public static void AddModule( IModuleFactory factory ) { 38 | foreach( ModulePreset preset in factory.Presets ) { 39 | Presets.Add( preset.Name, preset ); 40 | } 41 | FactoriesByType.Add( factory.ModuleType, factory ); 42 | FactoriesById.Add( factory.ID, factory ); 43 | } 44 | 45 | 46 | public static IModuleFactory GetFactoryByID( string id ) { 47 | return FactoriesById[id]; 48 | } 49 | 50 | 51 | public static IModuleFactory GetFactoryByType( Type type ) { 52 | return FactoriesByType[type]; 53 | } 54 | 55 | 56 | public static IModule GetPresetByName( string id ) { 57 | return Presets[id].GetInstance(); 58 | } 59 | 60 | 61 | public static IModule ReadModule( Stream stream ) { 62 | BinaryReader reader = new BinaryReader( stream ); 63 | string moduleID = reader.ReadString(); 64 | int settingsLength = reader.ReadInt32(); 65 | if( FactoriesById.ContainsKey( moduleID ) ) { 66 | IModuleFactory factory = GetFactoryByID( moduleID ); 67 | IModule module = factory.GetInstance(); 68 | //module.ReadSettings( reader, settingsLength ); 69 | return module; 70 | } else { 71 | stream.Seek( settingsLength, SeekOrigin.Current ); 72 | return null; 73 | } 74 | } 75 | 76 | 77 | public static IModuleFactory[] ListAllModules() { 78 | return FactoriesById.Values.ToArray(); 79 | } 80 | 81 | 82 | #region Reading Modules 83 | 84 | public static IModule ReadModule( NBTag tag ) { 85 | string moduleID = tag["ID"].GetString(); 86 | if( !FactoriesById.ContainsKey( moduleID ) ) { 87 | return null; 88 | } 89 | IModuleFactory factory = GetFactoryByID( moduleID ); 90 | IModule module = factory.GetInstance(); 91 | 92 | if( tag.Contains( "Properties" ) ) {} 93 | 94 | module.ReadSettings( tag["Settings"] ); 95 | 96 | return module; 97 | } 98 | 99 | 100 | public static void ReadModuleProperties( IModule module, NBTag tag ) { 101 | IModuleFactory factory = GetFactoryByType( module.GetType() ); 102 | foreach( PropertyInfo p in factory.ModuleType.GetProperties() ) { 103 | if( !tag.Contains( p.Name ) ) continue; 104 | if( p.PropertyType == typeof( byte ) ) { 105 | p.SetValue( module, tag.GetByte(), null ); 106 | } else if( p.PropertyType == typeof( short ) ) { 107 | p.SetValue( module, tag.GetShort(), null ); 108 | } else if( p.PropertyType == typeof( int ) ) { 109 | p.SetValue( module, tag.GetInt(), null ); 110 | } else if( p.PropertyType == typeof( long ) ) { 111 | p.SetValue( module, tag.GetLong(), null ); 112 | } else if( p.PropertyType == typeof( float ) ) { 113 | p.SetValue( module, tag.GetFloat(), null ); 114 | } else if( p.PropertyType == typeof( double ) ) { 115 | p.SetValue( module, tag.GetDouble(), null ); 116 | } else if( p.PropertyType == typeof( byte[] ) ) { 117 | p.SetValue( module, tag.GetBytes(), null ); 118 | } else if( p.PropertyType == typeof( string ) ) { 119 | p.SetValue( module, tag.GetString(), null ); 120 | } else if( p.PropertyType == typeof( bool ) ) { 121 | p.SetValue( module, tag.GetBool(), null ); 122 | } else if( p.PropertyType == typeof( Color ) ) { 123 | p.SetValue( module, tag.GetColor(), null ); 124 | } else if( p.PropertyType == typeof( Point ) ) { 125 | p.SetValue( module, tag.GetBool(), null ); 126 | } else if( p.PropertyType == typeof( PointF ) ) { 127 | p.SetValue( module, tag.GetPointF(), null ); 128 | } else { 129 | throw new NotSupportedException( "Unknown property type." ); 130 | } 131 | } 132 | } 133 | 134 | #endregion 135 | 136 | 137 | #region Writing Modules 138 | 139 | public static NBTag WriteModule( string tagName, IModule module ) { 140 | NBTCompound root = new NBTCompound( tagName ); 141 | IModuleFactory factory = GetFactoryByType( module.GetType() ); 142 | root.Append( "ID", factory.ID ); 143 | 144 | bool auto = 145 | !factory.ModuleType.GetCustomAttributes( typeof( DisableAutoSerializationAttribute ), true ).Any(); 146 | if( auto ) { 147 | root.Append( WriteModuleProperties( module ) ); 148 | } 149 | NBTag customSettings = new NBTCompound( "Settings" ); 150 | module.WriteSettings( customSettings ); 151 | root.Append( customSettings ); 152 | return root; 153 | } 154 | 155 | 156 | public static NBTag WriteModuleProperties( IModule module ) { 157 | IModuleFactory factory = GetFactoryByType( module.GetType() ); 158 | NBTag root = new NBTCompound( "Properties" ); 159 | foreach( PropertyInfo p in factory.ModuleType.GetProperties() ) { 160 | object val = p.GetValue( module, null ); 161 | if( p.PropertyType == typeof( byte ) ) { 162 | root.Append( p.Name, (byte)val ); 163 | } else if( p.PropertyType == typeof( short ) ) { 164 | root.Append( p.Name, (short)val ); 165 | } else if( p.PropertyType == typeof( int ) ) { 166 | root.Append( p.Name, (int)val ); 167 | } else if( p.PropertyType == typeof( long ) ) { 168 | root.Append( p.Name, (long)val ); 169 | } else if( p.PropertyType == typeof( float ) ) { 170 | root.Append( p.Name, (float)val ); 171 | } else if( p.PropertyType == typeof( double ) ) { 172 | root.Append( p.Name, (double)val ); 173 | } else if( p.PropertyType == typeof( byte[] ) ) { 174 | root.Append( p.Name, (byte[])val ); 175 | } else if( p.PropertyType == typeof( string ) ) { 176 | root.Append( p.Name, (string)val ); 177 | } else if( p.PropertyType == typeof( bool ) ) { 178 | root.Append( p.Name, (bool)val ); 179 | } else if( p.PropertyType == typeof( Color ) ) { 180 | root.Append( p.Name, (Color)val ); 181 | } else if( p.PropertyType == typeof( Point ) ) { 182 | root.Append( p.Name, (Point)val ); 183 | } else if( p.PropertyType == typeof( PointF ) ) { 184 | root.Append( p.Name, (PointF)val ); 185 | } else { 186 | throw new NotSupportedException( "Unknown property type." ); 187 | } 188 | } 189 | return root; 190 | } 191 | 192 | #endregion 193 | } 194 | } -------------------------------------------------------------------------------- /SuperImageEvolver/Mutators/TranslateMutator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | 4 | namespace SuperImageEvolver { 5 | public class TranslateMutatorFactory : IModuleFactory { 6 | public Type ModuleType { 7 | get { return typeof( TranslateMutator ); } 8 | } 9 | 10 | public string ID { 11 | get { return "std.TranslateMutator.1"; } 12 | } 13 | 14 | public ModuleFunction Function { 15 | get { return ModuleFunction.Mutator; } 16 | } 17 | 18 | public ModulePreset[] Presets { 19 | get { 20 | return new[] { 21 | new ModulePreset( "Translate", () => ( new TranslateMutator { 22 | PreserveAspectRatio = true 23 | } ), this ), 24 | new ModulePreset( "Translate/Skew", () => ( new TranslateMutator { 25 | PreserveAspectRatio = false 26 | } ), this ) 27 | }; 28 | } 29 | } 30 | 31 | 32 | public IModule GetInstance() { 33 | return new TranslateMutator { 34 | PreserveAspectRatio = true 35 | }; 36 | } 37 | } 38 | 39 | 40 | sealed class TranslateMutator : IMutator { 41 | public bool PreserveAspectRatio { get; set; } 42 | public bool EnableRotation { get; set; } 43 | 44 | 45 | public DNA Mutate( Random rand, DNA oldDNA, TaskState task ) { 46 | DNA newDNA = new DNA( oldDNA ); 47 | 48 | Shape shape = newDNA.Shapes[rand.Next( newDNA.Shapes.Length )]; 49 | int choice = rand.Next( ( EnableRotation ? 16 : 12 ) ); 50 | switch( choice ) { 51 | case 0: 52 | case 1: 53 | shape.PreviousState = shape.Clone() as Shape; 54 | MoveShape( rand, shape, task ); 55 | newDNA.LastMutation = MutationType.Move; 56 | break; 57 | case 2: 58 | case 3: 59 | shape.PreviousState = shape.Clone() as Shape; 60 | ScaleShape( rand, shape, task ); 61 | newDNA.LastMutation = MutationType.Scale; 62 | break; 63 | case 4: 64 | shape.PreviousState = shape.Clone() as Shape; 65 | ScaleShape( rand, shape, task ); 66 | MoveShape( rand, shape, task ); 67 | newDNA.LastMutation = MutationType.Transform; 68 | break; 69 | case 5: 70 | shape.PreviousState = shape.Clone() as Shape; 71 | MoveShape( rand, shape, task ); 72 | ScaleShape( rand, shape, task ); 73 | newDNA.LastMutation = MutationType.Transform; 74 | break; 75 | case 6: 76 | case 7: 77 | case 8: 78 | case 9: 79 | shape.PreviousState = shape.Clone() as Shape; 80 | ChangeColor( rand, shape, task ); 81 | newDNA.LastMutation = MutationType.ReplaceColor; 82 | break; 83 | case 10: 84 | newDNA.SwapShapes( rand ); 85 | break; 86 | case 11: 87 | shape.PreviousState = shape.Clone() as Shape; 88 | MoveShape( rand, shape, task ); 89 | ScaleShape( rand, shape, task ); 90 | ChangeColor( rand, shape, task ); 91 | newDNA.LastMutation = MutationType.Transform; 92 | break; 93 | case 12: 94 | case 13: 95 | shape.PreviousState = shape.Clone() as Shape; 96 | RotateShape( rand, shape ); 97 | newDNA.LastMutation = MutationType.Rotate; 98 | break; 99 | case 14: 100 | shape.PreviousState = shape.Clone() as Shape; 101 | MoveShape( rand, shape, task ); 102 | RotateShape( rand, shape ); 103 | newDNA.LastMutation = MutationType.Transform; 104 | break; 105 | case 15: 106 | shape.PreviousState = shape.Clone() as Shape; 107 | ChangeColor( rand, shape, task ); 108 | newDNA.LastMutation = MutationType.ReplaceColor; 109 | break; 110 | } 111 | return newDNA; 112 | } 113 | 114 | 115 | static void MoveShape( Random rand, Shape shape, TaskState task ) { 116 | RectangleF rect = shape.GetBoundaries(); 117 | int maxOverlap = task.ProjectOptions.MaxOverlap; 118 | PointF delta = new PointF { 119 | X = rand.NextFloat( -rect.X - maxOverlap, task.ImageWidth - rect.Right + maxOverlap ), 120 | Y = rand.NextFloat( -rect.Y - maxOverlap, task.ImageHeight - rect.Bottom + maxOverlap ) 121 | }; 122 | for( int i = 0; i < shape.Points.Length; i++ ) { 123 | shape.Points[i].X += delta.X; 124 | shape.Points[i].Y += delta.Y; 125 | } 126 | } 127 | 128 | 129 | void ScaleShape( Random rand, Shape shape, TaskState task ) { 130 | RectangleF rect = shape.GetBoundaries(); 131 | int maxOverlap = task.ProjectOptions.MaxOverlap; 132 | 133 | int maxWidth = (int)( Math.Min( rect.X, task.ImageWidth - rect.Right ) + rect.Width ) + maxOverlap * 2; 134 | int maxHeight = (int)( Math.Min( rect.Y, task.ImageHeight - rect.Bottom ) + rect.Height ) + maxOverlap * 2; 135 | 136 | double newWidthRatio = rand.Next( 3, maxWidth + 1 ) / rect.Width; 137 | double newHeightRatio = rand.Next( 3, maxHeight + 1 ) / rect.Height; 138 | 139 | if( PreserveAspectRatio ) { 140 | newWidthRatio = Math.Min( newWidthRatio, newHeightRatio ); 141 | newHeightRatio = newWidthRatio; 142 | } 143 | 144 | PointF rectCenter = new PointF { 145 | X = rect.X + rect.Width / 2f, 146 | Y = rect.Y + rect.Height / 2f 147 | }; 148 | 149 | for( int i = 0; i < shape.Points.Length; i++ ) { 150 | shape.Points[i].X = (float)( rectCenter.X + ( shape.Points[i].X - rectCenter.X ) * newWidthRatio ); 151 | shape.Points[i].Y = (float)( rectCenter.Y + ( shape.Points[i].Y - rectCenter.Y ) * newHeightRatio ); 152 | } 153 | } 154 | 155 | 156 | static void ChangeColor( Random rand, Shape shape, TaskState task ) { 157 | shape.PreviousState = shape.Clone() as Shape; 158 | switch( rand.Next( 4 ) ) { 159 | case 0: 160 | shape.Color = Color.FromArgb( rand.NextByte( task.ProjectOptions.MinAlpha, 256 ), shape.Color.R, 161 | shape.Color.G, shape.Color.B ); 162 | break; 163 | case 1: 164 | shape.Color = Color.FromArgb( shape.Color.A, rand.NextByte(), shape.Color.G, shape.Color.B ); 165 | break; 166 | case 2: 167 | shape.Color = Color.FromArgb( shape.Color.A, shape.Color.R, rand.NextByte(), shape.Color.B ); 168 | break; 169 | case 3: 170 | shape.Color = Color.FromArgb( shape.Color.A, shape.Color.R, shape.Color.G, rand.NextByte() ); 171 | break; 172 | } 173 | } 174 | 175 | 176 | static void RotateShape( Random rand, Shape shape ) { 177 | RectangleF rect = shape.GetBoundaries(); 178 | PointF rectCenter = new PointF { 179 | X = rect.X + rect.Width / 2, 180 | Y = rect.Y + rect.Height / 2 181 | }; 182 | 183 | double rotation = rand.NextDouble() * Math.PI * 2; 184 | 185 | for( int i = 0; i < shape.Points.Length; i++ ) { 186 | float alignedX = shape.Points[i].X - rectCenter.X; 187 | float alignedY = shape.Points[i].Y - rectCenter.Y; 188 | shape.Points[i].X = 189 | (float)( rectCenter.X + alignedX * Math.Cos( rotation ) - alignedY * Math.Sin( rotation ) ); 190 | shape.Points[i].Y = 191 | (float)( rectCenter.Y + alignedX * Math.Sin( rotation ) + alignedY * Math.Cos( rotation ) ); 192 | } 193 | } 194 | 195 | 196 | object ICloneable.Clone() { 197 | return new TranslateMutator { 198 | EnableRotation = EnableRotation, 199 | PreserveAspectRatio = PreserveAspectRatio 200 | }; 201 | } 202 | 203 | 204 | void IModule.ReadSettings( NBTag tag ) {} 205 | 206 | void IModule.WriteSettings( NBTag tag ) {} 207 | } 208 | } -------------------------------------------------------------------------------- /SuperImageEvolver/DiffCanvas.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.Drawing.Drawing2D; 4 | using System.Drawing.Imaging; 5 | using System.Windows.Forms; 6 | 7 | namespace SuperImageEvolver { 8 | sealed unsafe partial class DiffCanvas : UserControl { 9 | public DiffCanvas() { 10 | InitializeComponent(); 11 | DoubleBuffered = true; 12 | } 13 | 14 | 15 | public void Init( TaskState _state ) { 16 | state = _state; 17 | canvasImage = new Bitmap( state.ImageWidth, state.ImageHeight ); 18 | Zoom = zoom; 19 | } 20 | 21 | 22 | #region Properties 23 | 24 | public bool Invert { 25 | get { return invert; } 26 | set { 27 | invert = value; 28 | Invalidate(); 29 | } 30 | } 31 | 32 | bool invert; 33 | 34 | 35 | public bool ShowColor { 36 | get { return showColor; } 37 | set { 38 | showColor = value; 39 | Invalidate(); 40 | } 41 | } 42 | 43 | bool showColor = true; 44 | 45 | 46 | public bool Exaggerate { 47 | get { return exaggerate; } 48 | set { 49 | exaggerate = value; 50 | Invalidate(); 51 | } 52 | } 53 | 54 | bool exaggerate = true; 55 | 56 | 57 | public float Zoom { 58 | get { return zoom; } 59 | set { 60 | zoom = value; 61 | if( state != null ) { 62 | Size = new Size { 63 | Width = (int)Math.Ceiling( state.ImageWidth*Zoom ), 64 | Height = (int)Math.Ceiling( state.ImageHeight*Zoom ) 65 | }; 66 | } 67 | Invalidate(); 68 | } 69 | } 70 | 71 | float zoom = 1; 72 | 73 | 74 | public bool ShowLastChange { 75 | get { return showLastChange; } 76 | set { 77 | showLastChange = value; 78 | Invalidate(); 79 | } 80 | } 81 | 82 | bool showLastChange; 83 | 84 | 85 | 86 | public TaskState State { 87 | get { return state; } 88 | set { 89 | state = value; 90 | if( state != null ) { 91 | Size = new Size { 92 | Width = (int)Math.Ceiling( state.ImageWidth*Zoom ), 93 | Height = (int)Math.Ceiling( state.ImageHeight*Zoom ) 94 | }; 95 | } 96 | Invalidate(); 97 | } 98 | } 99 | 100 | TaskState state; 101 | 102 | #endregion 103 | 104 | 105 | const string PlaceholderText = "differences"; 106 | Bitmap canvasImage; 107 | 108 | protected override void OnPaint( PaintEventArgs e ) { 109 | Graphics g2 = e.Graphics; 110 | if( state != null && state.CurrentMatch != null ) { 111 | e.Graphics.ScaleTransform( zoom, zoom ); 112 | DNA tempDNA = state.CurrentMatch; 113 | using( Graphics g = Graphics.FromImage( canvasImage ) ) { 114 | g.Clear( state.ProjectOptions.Matte ); 115 | 116 | g.SmoothingMode = (state.Evaluator.Smooth ? SmoothingMode.HighQuality : SmoothingMode.HighSpeed); 117 | for( int i = 0; i < tempDNA.Shapes.Length; i++ ) { 118 | g.FillPolygon( new SolidBrush( tempDNA.Shapes[i].Color ), 119 | tempDNA.Shapes[i].Points, 120 | FillMode.Alternate ); 121 | } 122 | } 123 | 124 | BitmapData testData = canvasImage.LockBits( new Rectangle( Point.Empty, canvasImage.Size ), 125 | ImageLockMode.ReadOnly, 126 | PixelFormat.Format32bppArgb ); 127 | for( int i = 0; i < canvasImage.Height; i++ ) { 128 | byte* originalPointer = (byte*)state.WorkingImageData.Scan0 + state.WorkingImageData.Stride*i; 129 | byte* testPointer = (byte*)testData.Scan0 + testData.Stride*i; 130 | for( int j = 0; j < state.ImageWidth; j++ ) { 131 | if( !showColor ) { 132 | byte val; 133 | int originalLumi = 134 | (Math.Min( Math.Min( originalPointer[2], originalPointer[1] ), *originalPointer ) + 135 | Math.Max( Math.Max( originalPointer[2], originalPointer[1] ), *originalPointer ))/2; 136 | int testLumi = (Math.Min( Math.Min( testPointer[2], testPointer[1] ), *testPointer ) + 137 | Math.Max( Math.Max( testPointer[2], testPointer[1] ), *testPointer ))/2; 138 | 139 | if( exaggerate ) { 140 | double exaggeratedVal = 127 - 141 | Math.Sign( originalLumi - testLumi )* 142 | Math.Sqrt( Math.Abs( originalLumi - testLumi )/255d )*255d; 143 | val = (byte)Math.Max( 0, Math.Min( 255, exaggeratedVal ) ); 144 | } else { 145 | val = (byte)Math.Max( 0, Math.Min( 255, 127 - (originalLumi - testLumi) ) ); 146 | } 147 | 148 | if( invert ) val = (byte)(255 - val); 149 | testPointer[2] = val; 150 | testPointer[1] = val; 151 | *testPointer = val; 152 | 153 | } else if( invert ) { 154 | if( exaggerate ) { 155 | testPointer[2] = 156 | (byte) 157 | (255 - 158 | (int)(255*Math.Sqrt( Math.Abs( originalPointer[2] - testPointer[2] )/255d ))); 159 | testPointer[1] = 160 | (byte) 161 | (255 - 162 | (int)(255*Math.Sqrt( Math.Abs( originalPointer[1] - testPointer[1] )/255d ))); 163 | *testPointer = 164 | (byte) 165 | (255 - 166 | (int)(255*Math.Sqrt( Math.Abs( *originalPointer - *testPointer )/255d ))); 167 | } else { 168 | testPointer[2] = (byte)(255 - Math.Abs( originalPointer[2] - testPointer[2] )); 169 | testPointer[1] = (byte)(255 - Math.Abs( originalPointer[1] - testPointer[1] )); 170 | *testPointer = (byte)(255 - Math.Abs( *originalPointer - *testPointer )); 171 | } 172 | 173 | } else { 174 | if( exaggerate ) { 175 | testPointer[2] = 176 | (byte)(255*Math.Sqrt( Math.Abs( originalPointer[2] - testPointer[2] )/255d )); 177 | testPointer[1] = 178 | (byte)(255*Math.Sqrt( Math.Abs( originalPointer[1] - testPointer[1] )/255d )); 179 | *testPointer = 180 | (byte)(255*Math.Sqrt( Math.Abs( *originalPointer - *testPointer )/255d )); 181 | } else { 182 | testPointer[2] = (byte)Math.Abs( originalPointer[2] - testPointer[2] ); 183 | testPointer[1] = (byte)Math.Abs( originalPointer[1] - testPointer[1] ); 184 | *testPointer = (byte)Math.Abs( *originalPointer - *testPointer ); 185 | } 186 | } 187 | originalPointer += 4; 188 | testPointer += 4; 189 | } 190 | } 191 | canvasImage.UnlockBits( testData ); 192 | if( zoom == 2 || zoom == 1 ) { 193 | g2.InterpolationMode = InterpolationMode.NearestNeighbor; 194 | } 195 | g2.DrawImageUnscaled( canvasImage, 0, 0 ); 196 | 197 | if( showLastChange ) { 198 | Pen lastChangePen1 = new Pen( state.ProjectOptions.LastChangeColor1, 2/zoom ); 199 | Pen lastChangePen2 = new Pen( state.ProjectOptions.LastChangeColor2, 1/zoom ); 200 | g2.SmoothingMode = (state.Evaluator.Smooth ? SmoothingMode.HighQuality : SmoothingMode.HighSpeed); 201 | for( int i = 0; i < tempDNA.Shapes.Length; i++ ) { 202 | if( tempDNA.Shapes[i].PreviousState != null ) { 203 | g2.DrawPolygon( lastChangePen1, tempDNA.Shapes[i].Points ); 204 | g2.DrawPolygon( lastChangePen2, tempDNA.Shapes[i].PreviousState.Points ); 205 | } 206 | } 207 | } 208 | 209 | } else { 210 | SizeF align = g2.MeasureString( PlaceholderText, Font ); 211 | g2.DrawString( PlaceholderText, 212 | Font, 213 | Brushes.White, 214 | Width/2f - align.Width/2, 215 | Height/2f - align.Height/2 ); 216 | } 217 | base.OnPaint( e ); 218 | } 219 | } 220 | } -------------------------------------------------------------------------------- /SuperImageEvolver/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | ..\Icons\disk-black.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 123 | 124 | 125 | ..\Icons\layer-shape-polygon.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 126 | 127 | 128 | ..\Icons\disk.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 129 | 130 | 131 | ..\Icons\information.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 132 | 133 | 134 | ..\Icons\images.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 135 | 136 | 137 | ..\Icons\image-export.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 138 | 139 | 140 | ..\Icons\control.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 141 | 142 | 143 | ..\Icons\control-stop-square.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 144 | 145 | 146 | ..\Icons\arrow-stop-180.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 147 | 148 | 149 | ..\Icons\document-export.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 150 | 151 | 152 | ..\Icons\disk--pencil.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 153 | 154 | 155 | ..\Icons\document-import.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 156 | 157 | 158 | ..\Icons\document.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 159 | 160 | 161 | ..\Icons\folder-horizontal-open.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 162 | 163 | 164 | ..\Icons\gear.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 165 | 166 | -------------------------------------------------------------------------------- /SuperImageEvolver/Mutators/SoftTranslateMutator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | 4 | namespace SuperImageEvolver { 5 | public class SoftTranslateMutatorFactory : IModuleFactory { 6 | public Type ModuleType { 7 | get { return typeof( SoftTranslateMutator ); } 8 | } 9 | 10 | public string ID { 11 | get { return "std.SoftTranslateMutator.1"; } 12 | } 13 | 14 | public ModuleFunction Function { 15 | get { return ModuleFunction.Mutator; } 16 | } 17 | 18 | public ModulePreset[] Presets { 19 | get { 20 | return new[] { 21 | new ModulePreset( "Soft Translate", () => ( new SoftTranslateMutator { 22 | PreserveAspectRatio = true 23 | } ), this ), 24 | new ModulePreset( "Soft Translate/Skew", () => ( new SoftTranslateMutator { 25 | PreserveAspectRatio = false 26 | } ), this ) 27 | }; 28 | } 29 | } 30 | 31 | 32 | public IModule GetInstance() { 33 | return new SoftTranslateMutator { 34 | PreserveAspectRatio = true 35 | }; 36 | } 37 | } 38 | 39 | 40 | sealed class SoftTranslateMutator : IMutator { 41 | 42 | public bool PreserveAspectRatio { get; set; } 43 | public bool EnableRotation { get; set; } 44 | 45 | public float MaxColorDelta { get; set; } 46 | public float MaxPosDelta { get; set; } 47 | 48 | 49 | public SoftTranslateMutator() { 50 | MaxColorDelta = 8; 51 | MaxPosDelta = 16; 52 | } 53 | 54 | 55 | public DNA Mutate( Random rand, DNA oldDNA, TaskState task ) { 56 | DNA newDNA = new DNA( oldDNA ); 57 | 58 | Shape shape = newDNA.Shapes[rand.Next( newDNA.Shapes.Length )]; 59 | int choice = rand.Next( ( EnableRotation ? 16 : 12 ) ); 60 | switch( choice ) { 61 | case 0: 62 | case 1: 63 | shape.PreviousState = shape.Clone() as Shape; 64 | MoveShape( rand, shape, task ); 65 | newDNA.LastMutation = MutationType.Move; 66 | break; 67 | case 2: 68 | case 3: 69 | shape.PreviousState = shape.Clone() as Shape; 70 | ScaleShape( rand, shape, task ); 71 | newDNA.LastMutation = MutationType.Scale; 72 | break; 73 | case 4: 74 | shape.PreviousState = shape.Clone() as Shape; 75 | ScaleShape( rand, shape, task ); 76 | MoveShape( rand, shape, task ); 77 | newDNA.LastMutation = MutationType.Transform; 78 | break; 79 | case 5: 80 | shape.PreviousState = shape.Clone() as Shape; 81 | MoveShape( rand, shape, task ); 82 | ScaleShape( rand, shape, task ); 83 | newDNA.LastMutation = MutationType.Transform; 84 | break; 85 | case 6: 86 | case 7: 87 | case 8: 88 | case 9: 89 | shape.PreviousState = shape.Clone() as Shape; 90 | ChangeColor( rand, shape, task ); 91 | newDNA.LastMutation = MutationType.AdjustColor; 92 | break; 93 | case 10: 94 | newDNA.SwapShapes( rand ); 95 | break; 96 | case 11: 97 | shape.PreviousState = shape.Clone() as Shape; 98 | MoveShape( rand, shape, task ); 99 | ScaleShape( rand, shape, task ); 100 | ChangeColor( rand, shape, task ); 101 | newDNA.LastMutation = MutationType.Transform; 102 | break; 103 | case 12: 104 | case 13: 105 | shape.PreviousState = shape.Clone() as Shape; 106 | RotateShape( rand, shape ); 107 | newDNA.LastMutation = MutationType.Rotate; 108 | break; 109 | case 14: 110 | shape.PreviousState = shape.Clone() as Shape; 111 | MoveShape( rand, shape, task ); 112 | RotateShape( rand, shape ); 113 | newDNA.LastMutation = MutationType.Transform; 114 | break; 115 | case 15: 116 | shape.PreviousState = shape.Clone() as Shape; 117 | ChangeColor( rand, shape, task ); 118 | newDNA.LastMutation = MutationType.AdjustColor; 119 | break; 120 | } 121 | return newDNA; 122 | } 123 | 124 | 125 | static void MoveShape( Random rand, Shape shape, TaskState task ) { 126 | RectangleF rect = shape.GetBoundaries(); 127 | int maxOverlap = task.ProjectOptions.MaxOverlap; 128 | PointF delta = new PointF { 129 | X = 130 | rand.NextFloat( Math.Max( -maxOverlap, -rect.X - maxOverlap ), 131 | Math.Min( maxOverlap, task.ImageWidth - rect.Right + maxOverlap ) ), 132 | Y = 133 | rand.NextFloat( Math.Max( -maxOverlap, -rect.Y - maxOverlap ), 134 | Math.Min( maxOverlap, task.ImageHeight - rect.Bottom + maxOverlap ) ) 135 | }; 136 | for( int i = 0; i < shape.Points.Length; i++ ) { 137 | shape.Points[i].X += delta.X; 138 | shape.Points[i].Y += delta.Y; 139 | } 140 | } 141 | 142 | 143 | void ScaleShape( Random rand, Shape shape, TaskState task ) { 144 | RectangleF rect = shape.GetBoundaries(); 145 | int maxOverlap = task.ProjectOptions.MaxOverlap; 146 | 147 | int maxWidth = (int)( Math.Min( rect.X, task.ImageWidth - rect.Right ) + rect.Width ) + maxOverlap * 2; 148 | int maxHeight = (int)( Math.Min( rect.Y, task.ImageHeight - rect.Bottom ) + rect.Height ) + maxOverlap * 2; 149 | 150 | int minWidthRatio = (int)Math.Max( 3, rect.Width - maxOverlap ); 151 | int maxWidthRatio = (int)Math.Min( rect.Width + maxOverlap, maxWidth + 1 ); 152 | double newWidthRatio = 153 | rand.Next( Math.Min( minWidthRatio, maxWidthRatio ), Math.Max( minWidthRatio, maxWidthRatio ) ) / 154 | rect.Width; 155 | 156 | int minHeightRatio = (int)Math.Max( 3, rect.Height - maxOverlap ); 157 | int maxHeightRatio = (int)Math.Min( rect.Height + maxOverlap, maxHeight + 1 ); 158 | double newHeightRatio = 159 | rand.Next( Math.Min( minHeightRatio, maxHeightRatio ), Math.Max( minHeightRatio, maxHeightRatio ) ) / 160 | rect.Height; 161 | //double newHeightRatio = rand.Next( 3, maxHeight + 1 ) / rect.Height; 162 | 163 | if( PreserveAspectRatio ) { 164 | newWidthRatio = Math.Min( newWidthRatio, newHeightRatio ); 165 | newHeightRatio = newWidthRatio; 166 | } 167 | 168 | PointF rectCenter = new PointF { 169 | X = rect.X + rect.Width / 2f, 170 | Y = rect.Y + rect.Height / 2f 171 | }; 172 | 173 | for( int i = 0; i < shape.Points.Length; i++ ) { 174 | shape.Points[i].X = (float)( rectCenter.X + ( shape.Points[i].X - rectCenter.X ) * newWidthRatio ); 175 | shape.Points[i].Y = (float)( rectCenter.Y + ( shape.Points[i].Y - rectCenter.Y ) * newHeightRatio ); 176 | } 177 | } 178 | 179 | 180 | void ChangeColor( Random rand, Shape shape, TaskState task ) { 181 | shape.PreviousState = shape.Clone() as Shape; 182 | int delta = rand.NextByte( 1, (int)( MaxColorDelta + 1 ) ) * ( rand.Next( 2 ) == 0 ? 1 : -1 ); 183 | switch( rand.Next( 4 ) ) { 184 | case 0: 185 | shape.Color = 186 | Color.FromArgb( 187 | Math.Max( task.ProjectOptions.MinAlpha, Math.Min( 255, shape.Color.A + delta ) ), 188 | shape.Color.R, shape.Color.G, shape.Color.B ); 189 | break; 190 | case 1: 191 | shape.Color = Color.FromArgb( shape.Color.A, Math.Max( 0, Math.Min( 255, shape.Color.R + delta ) ), 192 | shape.Color.G, shape.Color.B ); 193 | break; 194 | case 2: 195 | shape.Color = Color.FromArgb( shape.Color.A, shape.Color.R, 196 | Math.Max( 0, Math.Min( 255, shape.Color.G + delta ) ), shape.Color.B ); 197 | break; 198 | case 3: 199 | shape.Color = Color.FromArgb( shape.Color.A, shape.Color.R, shape.Color.G, 200 | Math.Max( 0, Math.Min( 255, shape.Color.B + delta ) ) ); 201 | break; 202 | } 203 | } 204 | 205 | 206 | void RotateShape( Random rand, Shape shape ) { 207 | RectangleF rect = shape.GetBoundaries(); 208 | PointF rectCenter = new PointF { 209 | X = rect.X + rect.Width / 2, 210 | Y = rect.Y + rect.Height / 2 211 | }; 212 | 213 | double rotation = rand.NextDouble() * Math.PI * 2 * ( MaxPosDelta / 180 ); 214 | 215 | for( int i = 0; i < shape.Points.Length; i++ ) { 216 | float alignedX = shape.Points[i].X - rectCenter.X; 217 | float alignedY = shape.Points[i].Y - rectCenter.Y; 218 | shape.Points[i].X = 219 | (float)( rectCenter.X + alignedX * Math.Cos( rotation ) - alignedY * Math.Sin( rotation ) ); 220 | shape.Points[i].Y = 221 | (float)( rectCenter.Y + alignedX * Math.Sin( rotation ) + alignedY * Math.Cos( rotation ) ); 222 | } 223 | } 224 | 225 | 226 | object ICloneable.Clone() { 227 | return new SoftTranslateMutator { 228 | EnableRotation = EnableRotation, 229 | MaxColorDelta = MaxColorDelta, 230 | MaxPosDelta = MaxPosDelta, 231 | PreserveAspectRatio = PreserveAspectRatio 232 | }; 233 | } 234 | 235 | 236 | void IModule.ReadSettings( NBTag tag ) {} 237 | 238 | void IModule.WriteSettings( NBTag tag ) {} 239 | } 240 | } --------------------------------------------------------------------------------