// Create the threads public void Generate() { // Create array of WParts WpArray = new WPart[NO_OF_THREADS]; // Create array of ManualResetEvents ManualResetEvent[] doneEvents = new ManualResetEvent[NO_OF_THREADS]; double x_step = (FC.fractalArea.x2 - FC.fractalArea.x1) / NO_OF_THREADS; for (int i = 0; i < NO_OF_THREADS; i++) { doneEvents[i] = new ManualResetEvent(false); FractalArea fa_temp = new FractalArea { x1 = FC.fractalArea.x1 + x_step * i, x2 = FC.fractalArea.x1 + x_step * i + x_step, y1 = FC.fractalArea.y1, y2 = FC.fractalArea.y2 }; WPart WP = new WPart(FC.width / NO_OF_THREADS, FC.height, FC.fractalType, FC.w_max, fa_temp, FC.dx, FC.dy, doneEvents[i]); WpArray[i] = WP; ThreadPool.QueueUserWorkItem(WP.ThreadPoolCallback, i); } Calculating = true; // Wait for all threads in pool to complete foreach (var e in doneEvents) { e.WaitOne(); } Calculating = false; Application.DoEvents(); Draw(); PB.Image = DrawArea; }
//Colorise and display the fractal public void Draw() { int wi; for (int i = 0; i < NO_OF_THREADS; i++) { WPart WP = WpArray[i]; for (int Xcount = 0; Xcount < WP.width; Xcount++) { for (int Ycount = 0; Ycount < WP.height; Ycount++) { // Draw pixel wi = WP.w_data[Xcount, Ycount]; if (wi < FC.w_max) { const byte alpha = 255; byte red = Convert.ToByte(FC.R * wi / FC.w_max); byte green = Convert.ToByte(FC.G * wi / FC.w_max); byte blue = Convert.ToByte(FC.B * wi / FC.w_max); byte[] color = { alpha, red, green, blue }; if (BitConverter.IsLittleEndian) { Array.Reverse(color); } DrawArea.SetPixel(Xcount + WP.width * i, Ycount, Color.FromArgb(BitConverter.ToInt32(color, 0))); } else { DrawArea.SetPixel(Xcount + WP.width * i, Ycount, Color.Black); } } } } }