Click here to Skip to main content
12,450,101 members (42,035 online)
Click here to Skip to main content
Articles » Languages » C# » Applications » Downloads

Tagged as

Stats

110.8K views
9.8K downloads
161 bookmarked
Posted

The beauty of fractals - A simple fractal rendering program done in C#

, 27 Jul 2009 CPOL
A fractal rendering application demonstrating many .NET programming techniques.
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Threading;
using System.Runtime.Serialization;
using System.Runtime.InteropServices;
using System.Drawing.Imaging;

namespace FracMaster
{
    public class Generic2DFractal : GenericFractal
    {
        public Generic2DFractal()
        {
            pars.SetValue("X", 0.0);
            pars.SetValue("Y", 0.0);
            pars.SetValue("XC", 0.0);
            pars.SetValue("YC", 0.0);
            pars.SetValue("W", 1.0);
            pars.SetValue("H", 1.0);
            pars.SetValue("WIDTH", 640);
            pars.SetValue("HEIGHT", 480);
            pars.SetValue("VERSION", "1.0.0");
            pars.AddValue("ITERATIONS", 64);
            pars.AddValue("ZOOMABLE", 1);
            pars.AddValue("SCROLLABLE", 1);
            pars.AddValue("NUM_THREADS", Environment.ProcessorCount);
            pars.AddValue("APPLY_BILINEAR_FILTER", 0);            
        }

        virtual public void SetOrigin(double dx, double dy)
        {
             
            double CurWpix = (int)pars.GetValue("WIDTH");
            double CurHpix = (int)pars.GetValue("HEIGHT");
            double FracWidth = (double)pars.GetValue("W");
            double FracHeight = (double)pars.GetValue("H");
            double FracX = (double)pars.GetValue("X");
            double FracY = (double)pars.GetValue("Y");

            FracX -= dx * FracWidth / CurWpix;
            FracY -= dy * FracHeight / CurHpix;

            pars.SetValue("X", FracX);
            pars.SetValue("Y", FracY);
        }

        virtual public void SetControlParameter(double dx, double dy)
        {
            double CurWpix = (int)pars.GetValue("WIDTH");
            double CurHpix = (int)pars.GetValue("HEIGHT");
            double FracWidth = (double)pars.GetValue("W");
            double FracHeight = (double)pars.GetValue("H");
            double FracX = (double)pars.GetValue("XC");
            double FracY = (double)pars.GetValue("YC");

            FracX -= dx * FracWidth / CurWpix;
            FracY -= dy * FracHeight / CurHpix;

            pars.SetValue("XC", FracX);
            pars.SetValue("YC", FracY);
        }

        override protected void RenderFunction(object o)
        {
            object[] P = (object[])o;
            RenderResult.RenderComplete clbk = (RenderResult.RenderComplete)P[0];
            RenderResult.RenderStatus status_clbk = (RenderResult.RenderStatus)P[1];

            try
            {
                Random r = new Random();

                int width = (int)pars.GetValue("WIDTH");
                int heigth = (int)pars.GetValue("HEIGHT");
                int iterations = (int)pars.GetValue("ITERATIONS") - 1;
                Int32[] Palette = (Int32[])pars.GetValue("PALETTE");
                int NumThreads = (int)pars.GetValue("NUM_THREADS", 2);
                int BilinearFilter = (int)pars.GetValue("APPLY_BILINEAR_FILTER",0);  

                int[] colrTable = new int[width * heigth];
                
                WaitHandle[] handles = new WaitHandle[NumThreads];
                Thread[] threads = new Thread[NumThreads];

                lines_rendered = 0;

                for (int i = 0; i < NumThreads; i++)
                {
                    handles[i] = new AutoResetEvent(false);
                    threads[i] = new Thread(new ParameterizedThreadStart(PartialRender));
                    threads[i].Start((object)(new object[] { i * heigth / NumThreads, 
                                                             heigth / NumThreads, 
                                                             colrTable, 
                                                             status_clbk, handles[i] }));
                }
 
                while (true)
                {
                    if (WaitHandle.WaitAll(handles, 100, false) == true)
                    {
                        break;
                    }
                    else if (interrupt.WaitOne(100, false) == true)
                    {
                        try
                        {
                            for (int i = 0; i < NumThreads; i++)
                            {
                                threads[i].Abort();
                            }
                        }
                        catch { }

                        clbk(null, -2);

                        return;
                    }
                }
                
                if (BilinearFilter == 1)
                {
                    int [] filteredColorTable =  new int[(width * heigth)];
                    int idxs11 = 0,idxs12 = 0,idxs21 = 0,idxs22 = 0;

                    for (int y = 0; y < heigth-1; y++)
                    {
                        idxs11 = y * (width);
                        idxs12 = idxs11 + 1;
                        idxs21 = idxs11 + width;
                        idxs22 = idxs21 + 1;

                        for (int x = 0; x < width-1; x++)
                        {                            
                            int colf1 = Utils.InterpolateColors(colrTable[idxs11], colrTable[idxs12], 127);
                            int colf2 = Utils.InterpolateColors(colrTable[idxs21], colrTable[idxs22], 127);
                            
                            filteredColorTable[idxs11] = Utils.InterpolateColors(colf1, colf2, 128);
                            
                            idxs11++;
                            idxs12++;
                            idxs21++;
                            idxs22++;
                        }
                    }
                   
                    colrTable = filteredColorTable;
                }

                Bitmap bmp = new Bitmap(width, heigth, PixelFormat.Format32bppPArgb);
                BitmapData pdate = bmp.LockBits(new Rectangle(0, 0, width, heigth),
                                                ImageLockMode.ReadWrite,
                                                PixelFormat.Format32bppPArgb);

                IntPtr pscan0 = pdate.Scan0;
               
                Marshal.Copy(colrTable, 0, pscan0, width * heigth);
 
                bmp.UnlockBits(pdate);

                res.IsCompleted = true;

                ((AutoResetEvent)(res.AsyncWaitHandle)).Set();
                
                clbk(bmp, 0);
            }
            catch
            {
                clbk(null, -1);
            }
        }

        virtual protected void PartialRender(object P)
        {

        }
    }

}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Zimmermann Stephan
Software Developer (Senior)
Austria Austria
I have started programming at the age of 13 on the commodore 64.

Ever since then I have been programming on many systems in many languages.

During the last 12 years I have been working as professional programmer in different companies and different areas.

Now I am working as freelancer programmer / consultant

You may also be interested in...

Pro
Pro
| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160826.1 | Last Updated 27 Jul 2009
Article Copyright 2009 by Zimmermann Stephan
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid