Browse Source

Changed coloring

Stephen Downward 1 year ago
parent
commit
efae703408
2 changed files with 119 additions and 119 deletions
  1. 10 76
      MandelbrotCalc/Form1.Designer.cs
  2. 109 43
      MandelbrotCalc/Form1.cs

+ 10 - 76
MandelbrotCalc/Form1.Designer.cs

@ -30,16 +30,11 @@
30 30
        {
31 31
            this.outputFractalImage = new System.Windows.Forms.PictureBox();
32 32
            this.button1 = new System.Windows.Forms.Button();
33
            this.cIndex = new System.Windows.Forms.NumericUpDown();
34
            this.label1 = new System.Windows.Forms.Label();
35
            this.iterationsNumeric = new System.Windows.Forms.NumericUpDown();
36
            this.label2 = new System.Windows.Forms.Label();
33
            this.iterationsLabel = new System.Windows.Forms.Label();
37 34
            this.label3 = new System.Windows.Forms.Label();
38 35
            this.exportBtn = new System.Windows.Forms.Button();
39 36
            this.boundaryCoords = new System.Windows.Forms.Label();
40 37
            ((System.ComponentModel.ISupportInitialize)(this.outputFractalImage)).BeginInit();
41
            ((System.ComponentModel.ISupportInitialize)(this.cIndex)).BeginInit();
42
            ((System.ComponentModel.ISupportInitialize)(this.iterationsNumeric)).BeginInit();
43 38
            this.SuspendLayout();
44 39
            // 
45 40
            // outputFractalImage
@ -64,67 +59,14 @@
64 59
            this.button1.UseVisualStyleBackColor = true;
65 60
            this.button1.Click += new System.EventHandler(this.button1_Click);
66 61
            // 
67
            // cIndex
62
            // iterationsLabel
68 63
            // 
69
            this.cIndex.Increment = new decimal(new int[] {
70
            50,
71
            0,
72
            0,
73
            0});
74
            this.cIndex.Location = new System.Drawing.Point(449, 820);
75
            this.cIndex.Maximum = new decimal(new int[] {
76
            10000,
77
            0,
78
            0,
79
            0});
80
            this.cIndex.Name = "cIndex";
81
            this.cIndex.Size = new System.Drawing.Size(78, 20);
82
            this.cIndex.TabIndex = 2;
83
            this.cIndex.Value = new decimal(new int[] {
84
            2500,
85
            0,
86
            0,
87
            0});
88
            // 
89
            // label1
90
            // 
91
            this.label1.AutoSize = true;
92
            this.label1.Location = new System.Drawing.Point(380, 823);
93
            this.label1.Name = "label1";
94
            this.label1.Size = new System.Drawing.Size(63, 13);
95
            this.label1.TabIndex = 3;
96
            this.label1.Text = "Color Index:";
97
            // 
98
            // iterationsNumeric
99
            // 
100
            this.iterationsNumeric.Increment = new decimal(new int[] {
101
            50,
102
            0,
103
            0,
104
            0});
105
            this.iterationsNumeric.Location = new System.Drawing.Point(291, 820);
106
            this.iterationsNumeric.Maximum = new decimal(new int[] {
107
            10000,
108
            0,
109
            0,
110
            0});
111
            this.iterationsNumeric.Name = "iterationsNumeric";
112
            this.iterationsNumeric.Size = new System.Drawing.Size(83, 20);
113
            this.iterationsNumeric.TabIndex = 4;
114
            this.iterationsNumeric.Value = new decimal(new int[] {
115
            1000,
116
            0,
117
            0,
118
            0});
119
            // 
120
            // label2
121
            // 
122
            this.label2.AutoSize = true;
123
            this.label2.Location = new System.Drawing.Point(201, 823);
124
            this.label2.Name = "label2";
125
            this.label2.Size = new System.Drawing.Size(84, 13);
126
            this.label2.TabIndex = 5;
127
            this.label2.Text = "Iterations Count:";
64
            this.iterationsLabel.AutoSize = true;
65
            this.iterationsLabel.Location = new System.Drawing.Point(201, 823);
66
            this.iterationsLabel.Name = "iterationsLabel";
67
            this.iterationsLabel.Size = new System.Drawing.Size(84, 13);
68
            this.iterationsLabel.TabIndex = 5;
69
            this.iterationsLabel.Text = "";
128 70
            // 
129 71
            // label3
130 72
            // 
@ -162,10 +104,7 @@
162 104
            this.Controls.Add(this.boundaryCoords);
163 105
            this.Controls.Add(this.exportBtn);
164 106
            this.Controls.Add(this.label3);
165
            this.Controls.Add(this.label2);
166
            this.Controls.Add(this.iterationsNumeric);
167
            this.Controls.Add(this.label1);
168
            this.Controls.Add(this.cIndex);
107
            this.Controls.Add(this.iterationsLabel);
169 108
            this.Controls.Add(this.button1);
170 109
            this.Controls.Add(this.outputFractalImage);
171 110
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
@ -174,8 +113,6 @@
174 113
            this.ShowIcon = false;
175 114
            this.Text = "Mandlebrot calculator";
176 115
            ((System.ComponentModel.ISupportInitialize)(this.outputFractalImage)).EndInit();
177
            ((System.ComponentModel.ISupportInitialize)(this.cIndex)).EndInit();
178
            ((System.ComponentModel.ISupportInitialize)(this.iterationsNumeric)).EndInit();
179 116
            this.ResumeLayout(false);
180 117
            this.PerformLayout();
181 118

@ -185,10 +122,7 @@
185 122

186 123
        private System.Windows.Forms.PictureBox outputFractalImage;
187 124
        private System.Windows.Forms.Button button1;
188
        private System.Windows.Forms.NumericUpDown cIndex;
189
        private System.Windows.Forms.Label label1;
190
        private System.Windows.Forms.NumericUpDown iterationsNumeric;
191
        private System.Windows.Forms.Label label2;
125
        private System.Windows.Forms.Label iterationsLabel;
192 126
        private System.Windows.Forms.Label label3;
193 127
        private System.Windows.Forms.Button exportBtn;
194 128
        private System.Windows.Forms.Label boundaryCoords;

+ 109 - 43
MandelbrotCalc/Form1.cs

@ -1,4 +1,5 @@
1 1
using System;
2
using System.CodeDom;
2 3
using System.Collections.Generic;
3 4
using System.ComponentModel;
4 5
using System.Data;
@ -8,6 +9,7 @@ using System.Text;
8 9
using System.Threading.Tasks;
9 10
using System.Windows.Forms;
10 11
using System.Drawing.Imaging;
12
using System.Net.Security;
11 13

12 14
namespace MandelBrotCalc
13 15
{
@ -27,8 +29,6 @@ namespace MandelBrotCalc
27 29

28 30
        private void button1_Click(object sender, EventArgs e)
29 31
        {
30
            int cScale = (int)cIndex.Value;
31
            int iterations = (int)iterationsNumeric.Value;
32 32

33 33
            minX = -2;
34 34
            minY = -2;
@ -56,7 +56,6 @@ namespace MandelBrotCalc
56 56

57 57
        private void outputFractalImage_MouseUp(object sender, MouseEventArgs e)
58 58
        {
59

60 59
            //Change scale and redraw!
61 60
            //int RectSize = Math.Max(Rect.Width, Rect.Height); //Maintain aspect ratio!
62 61
            //int CenterX = Rect.X + Rect.Width / 2;
@ -85,7 +84,8 @@ namespace MandelBrotCalc
85 84
            minY = NminY;
86 85
            maxY = NmaxY;
87 86

88
            boundaryCoords.Text = "X: " + Math.Round(minX, 10) + " to " + Math.Round(maxX, 10) + "\r\nY: " + Math.Round(minY, 10) + " to " + Math.Round(maxY, 10);
87
            boundaryCoords.Text = "X: " + Math.Round(minX, 10) + " to " + Math.Round(maxX, 10) + "\r\nY: " +
88
                                  Math.Round(minY, 10) + " to " + Math.Round(maxY, 10);
89 89

90 90
            outputFractalImage.Image = generateFractal(outputFractalImage.Width, outputFractalImage.Height);
91 91
            Rect.Size = new Size(0, 0);
@ -94,8 +94,8 @@ namespace MandelBrotCalc
94 94

95 95
        private Image generateFractal(int width, int height)
96 96
        {
97
            int cScale = (int)cIndex.Value;
98
            int iterations = (int)iterationsNumeric.Value;
97
            int iterations = numSteps(minX, maxX, minY, maxY);
98
            iterationsLabel.Text = "Iterations Count: " + iterations.ToString();
99 99

100 100
            var tile = new Bitmap(width, height);
101 101
            unsafe
@ -104,35 +104,35 @@ namespace MandelBrotCalc
104 104
                int w = tile.Width;
105 105

106 106
                //Move this to its own function
107
                BitmapData bitmapData = tile.LockBits(new Rectangle(0, 0, tile.Width, tile.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
107
                BitmapData bitmapData = tile.LockBits(new Rectangle(0, 0, tile.Width, tile.Height),
108
                    ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
108 109
                int bytesPerPixel = System.Drawing.Bitmap.GetPixelFormatSize(tile.PixelFormat) / 8;
109 110
                int heightInPixels = bitmapData.Height;
110 111
                int widthInBytes = bitmapData.Width * bytesPerPixel;
111
                byte* ptrFirstPixel = (byte*)bitmapData.Scan0;
112

113
                Parallel.For(0, tile.Height, new ParallelOptions { MaxDegreeOfParallelism = 16 }, y =>//int x = 0; x < imageFrame.Width; x++)
114
                {
115
                    byte* currentLine = ptrFirstPixel + (y * bitmapData.Stride);
112
                byte* ptrFirstPixel = (byte*) bitmapData.Scan0;
116 113

117
                    for (int x = 0; x < w; x++)
114
                Parallel.For(0, tile.Height, new ParallelOptions {MaxDegreeOfParallelism = 16},
115
                    y => //int x = 0; x < imageFrame.Width; x++)
118 116
                    {
119
                        double Ci = ConvertRange(0, h, minY, maxY, y);
120
                        double Cr = ConvertRange(0, w, minX, maxX, x);
121
                        int r = rateOfDiversion(Cr, Ci, cScale, iterations);
122
						int B = r / 65536;
123
						int G = (r / 256) % 256 ^ 2;
124
						int R = r % 256;
125

126
                        currentLine[x * bytesPerPixel] = (byte)B;
127
                        currentLine[x * bytesPerPixel + 1] = (byte)G;
128
                        currentLine[x * bytesPerPixel + 2] = (byte)R;
129
                        currentLine[x * bytesPerPixel + 3] = 255;
130
                    }
131
                });
117
                        byte* currentLine = ptrFirstPixel + (y * bitmapData.Stride);
118

119
                        for (int x = 0; x < w; x++)
120
                        {
121
                            double Ci = ConvertRange(0, h, minY, maxY, y);
122
                            double Cr = ConvertRange(0, w, minX, maxX, x);
123
                            ColorRGB c = rateOfDiversion(Cr, Ci, iterations);
124

125
                            currentLine[x * bytesPerPixel] = (byte) c.b;
126
                            currentLine[x * bytesPerPixel + 1] = (byte) c.g;
127
                            currentLine[x * bytesPerPixel + 2] = (byte) c.r;
128
                            currentLine[x * bytesPerPixel + 3] = 255;
129
                        }
130
                    });
132 131
                //SourceImage.UnlockBits(srcData);
133 132

134 133
                tile.UnlockBits(bitmapData);
135 134
            }
135

136 136
            return tile;
137 137
        }
138 138

@ -152,7 +152,7 @@ namespace MandelBrotCalc
152 152
            SaveFileDialog saveDialog = new SaveFileDialog();
153 153
            saveDialog.Filter = "PNG image (*.png)|*.png";
154 154
            saveDialog.DefaultExt = "png";
155
            if(saveDialog.ShowDialog() == DialogResult.OK)
155
            if (saveDialog.ShowDialog() == DialogResult.OK)
156 156
            {
157 157
                //Generate and save
158 158
                Image img = generateFractal(1920 * 4, 1920 * 4);
@ -161,28 +161,31 @@ namespace MandelBrotCalc
161 161
            }
162 162
        }
163 163

164
        private int rateOfDiversion(double Creal, double Cimaginary, int colorScale, int totalIterations)
164
        private ColorRGB rateOfDiversion(double Creal, double Cimaginary, int totalIterations)
165 165
        {
166 166
            int numRecursions = 0;
167
			double Zr = 0;
168
			double Zrtemp = 0;
169
			double Zi = 0;
167
            double Zr = 0;
168
            double Zrtemp = 0;
169
            double Zi = 0;
170 170

171
			double tot = Zr * Zr + Zi * Zi;
172
			while (Zr * Zr + Zi * Zi < 4)
171
            while (Zr * Zr + Zi * Zi < 4)
173 172
            {
174
                numRecursions++;
175
				Zrtemp = Zr * Zr + Creal - (Zi * Zi);
176
				Zi = 2 * Zi * Zr + Cimaginary;
177
				Zr = Zrtemp;
178
                if (numRecursions > totalIterations) return 0; //Convergent
179
			}
180
			return (int)ConvertRange(0, colorScale, 0, 16777215, numRecursions);
173
                numRecursions++;
174
                Zrtemp = Zr * Zr + Creal - (Zi * Zi);
175
                Zi = 2 * Zi * Zr + Cimaginary;
176
                Zr = Zrtemp;
177
                if (numRecursions > totalIterations) return new ColorRGB(0, 0, 0); //Convergent
178
            }
179

180
            double v = 6 + numRecursions - Math.Log(Math.Log(Zr * Zr + Zi * Zi))*1.4426950408889634d;
181
            
182
            return FromHue(v / (double) totalIterations);
181 183
        }
182 184

183
        public static double ConvertRange(double originalStart, double originalEnd, double newStart, double newEnd, double value)
185
        private static double ConvertRange(double originalStart, double originalEnd, double newStart, double newEnd,
186
            double value)
184 187
        {
185
            double scale = (double)(newEnd - newStart) / (originalEnd - originalStart);
188
            double scale = (double) (newEnd - newStart) / (originalEnd - originalStart);
186 189
            return (newStart + ((value - originalStart) * scale));
187 190
        }
188 191

@ -191,5 +194,68 @@ namespace MandelBrotCalc
191 194
            RectStartPoint = e.Location;
192 195
            Invalidate();
193 196
        }
197

198
        private static int numSteps(double X0, double X1, double Y0, double Y1)
199
        {
200
            return (int)Math.Floor(223.0f/Math.Sqrt(0.001 + 2.0 * Math.Min(X1 - X0, Y1 - Y0)));
201
        }
202

203
        private static ColorRGB FromHue(double H)
204
        {
205
            double r = 1, g = 1, b = 1;
206

207
            H *= 6.0;
208
            int sextant = (int) H;
209
            double x = 1 - Math.Abs((H % 2) - 1);
210
            switch (sextant)
211
            {
212
                case 0:
213
                    r = 1;
214
                    g = x;
215
                    b = 0;
216
                    break;
217
                case 1:
218
                    r = x;
219
                    g = 1;
220
                    b = 0;
221
                    break;
222
                case 2:
223
                    r = 0;
224
                    g = 1;
225
                    b = x;
226
                    break;
227
                case 3:
228
                    r = 0;
229
                    g = x;
230
                    b = 1;
231
                    break;
232
                case 4:
233
                    r = x;
234
                    g = 0;
235
                    b = 1;
236
                    break;
237
                case 5:
238
                    r = 1;
239
                    g = 0;
240
                    b = x;
241
                    break;
242
            }
243

244
            return new ColorRGB((int)(r * 255), (int)(g * 255), (int)(b * 255));
245
        }
246
    }
247
    
248
    class ColorRGB
249
    {
250
        public int r;
251
        public int g;
252
        public int b;
253

254
        public ColorRGB(int R, int G, int B)
255
        {
256
            r = R;
257
            g = G;
258
            b = B;
259
        }
194 260
    }
195
}
261
}