algorytm.org

Implementacja w C#

Baza Wiedzy
wersja offline serwisu przeznaczona na urządzenia z systemem Android
Darowizny
darowiznaWspomóż rozwój serwisu
Nagłówki RSS
Artykuły
Implementacje
Komentarze
Forum
Bookmarki






Sonda
Implementacji w jakim języku programowania poszukujesz?

Zbiór Mandelbrot'a - Implementacja w C#
Ocena użytkownikóww: *****  / 4
SłabyŚwietny
Nadesłany przez Tomasz Lubiński, 18 sierpnia 2008 01:00
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.
Pobierz pełne rozwiązanie.

Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.

Mandelbrot - C#/Form1.cs:
// Fraktale - zbior Mandelbrot'a
// www.algorytm.org
// Tomasz Lubinski (c) 2008

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace Mandelbrot
{
	/// <summary>
	/// Fraktale - zbior Mandelbrot'a
	/// www.algorytm.org
	/// Tomasz Lubinski (c) 2008
	/// </summary>
	public class Form1 : System.Windows.Forms.Form
	{
		private System.Windows.Forms.Button button1;
		private System.Windows.Forms.Label label2;
		private System.Windows.Forms.TextBox maxy;
		private System.Windows.Forms.TextBox miny;
		private System.Windows.Forms.Label label1;
		private System.Windows.Forms.TextBox maxx;
		private System.Windows.Forms.TextBox minx;
		private System.Windows.Forms.PictureBox Fractal;
		private Graphics graph;

		//Describes places to render
		private double ratioX;
		private double ratioY;
		private double minX;
		private double minY;
		private double maxX;
		private double maxY;
		private int downX;
		private int downY;

		private Pen [] penColors = new Pen[120];
		private System.Windows.Forms.Panel Selection;
		private System.Windows.Forms.Button button2;
		private System.Windows.Forms.Label label3;

		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;

		public Form1()
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.button1 = new System.Windows.Forms.Button();
			this.label2 = new System.Windows.Forms.Label();
			this.maxy = new System.Windows.Forms.TextBox();
			this.miny = new System.Windows.Forms.TextBox();
			this.label1 = new System.Windows.Forms.Label();
			this.maxx = new System.Windows.Forms.TextBox();
			this.minx = new System.Windows.Forms.TextBox();
			this.Fractal = new System.Windows.Forms.PictureBox();
			this.Selection = new System.Windows.Forms.Panel();
			this.button2 = new System.Windows.Forms.Button();
			this.label3 = new System.Windows.Forms.Label();
			this.SuspendLayout();
			// 
			// button1
			// 
			this.button1.Location = new System.Drawing.Point(376, 121);
			this.button1.Name = "button1";
			this.button1.TabIndex = 15;
			this.button1.Text = "Generuj";
			this.button1.Click += new System.EventHandler(this.button1_Click);
			// 
			// label2
			// 
			this.label2.Location = new System.Drawing.Point(376, 65);
			this.label2.Name = "label2";
			this.label2.Size = new System.Drawing.Size(64, 23);
			this.label2.TabIndex = 14;
			this.label2.Text = "Zakres Y";
			// 
			// maxy
			// 
			this.maxy.Location = new System.Drawing.Point(440, 89);
			this.maxy.Name = "maxy";
			this.maxy.Size = new System.Drawing.Size(120, 20);
			this.maxy.TabIndex = 13;
			this.maxy.Text = "textBox3";
			// 
			// miny
			// 
			this.miny.Location = new System.Drawing.Point(440, 65);
			this.miny.Name = "miny";
			this.miny.Size = new System.Drawing.Size(120, 20);
			this.miny.TabIndex = 12;
			this.miny.Text = "textBox4";
			// 
			// label1
			// 
			this.label1.Location = new System.Drawing.Point(376, 17);
			this.label1.Name = "label1";
			this.label1.Size = new System.Drawing.Size(64, 23);
			this.label1.TabIndex = 11;
			this.label1.Text = "Zakres X";
			// 
			// maxx
			// 
			this.maxx.Location = new System.Drawing.Point(440, 41);
			this.maxx.Name = "maxx";
			this.maxx.Size = new System.Drawing.Size(120, 20);
			this.maxx.TabIndex = 10;
			this.maxx.Text = "textBox2";
			// 
			// minx
			// 
			this.minx.Location = new System.Drawing.Point(440, 17);
			this.minx.Name = "minx";
			this.minx.Size = new System.Drawing.Size(120, 20);
			this.minx.TabIndex = 9;
			this.minx.Text = "textBox1";
			// 
			// Fractal
			// 
			this.Fractal.Cursor = System.Windows.Forms.Cursors.Cross;
			this.Fractal.Location = new System.Drawing.Point(8, 8);
			this.Fractal.Name = "Fractal";
			this.Fractal.Size = new System.Drawing.Size(352, 352);
			this.Fractal.TabIndex = 8;
			this.Fractal.TabStop = false;
			this.Fractal.MouseUp += new System.Windows.Forms.MouseEventHandler(this.Fractal_MouseUp);
			this.Fractal.MouseMove += new System.Windows.Forms.MouseEventHandler(this.Fractal_MouseMove);
			this.Fractal.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Fractal_MouseDown);
			// 
			// Selection
			// 
			this.Selection.BackColor = System.Drawing.SystemColors.HighlightText;
			this.Selection.Location = new System.Drawing.Point(160, 160);
			this.Selection.Name = "Selection";
			this.Selection.Size = new System.Drawing.Size(48, 40);
			this.Selection.TabIndex = 16;
			this.Selection.Visible = false;
			// 
			// button2
			// 
			this.button2.Location = new System.Drawing.Point(464, 120);
			this.button2.Name = "button2";
			this.button2.TabIndex = 17;
			this.button2.Text = "Reset";
			this.button2.Click += new System.EventHandler(this.Form1_Load);
			// 
			// label3
			// 
			this.label3.Location = new System.Drawing.Point(376, 168);
			this.label3.Name = "label3";
			this.label3.Size = new System.Drawing.Size(184, 48);
			this.label3.TabIndex = 18;
			this.label3.Text = "W oknie po lewej zaznacz fragment do powiekszenia, badz wpisz  zakres recznie i n" +
				"acisnij \"Generuj\"";
			// 
			// Form1
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.ClientSize = new System.Drawing.Size(568, 371);
			this.Controls.Add(this.label3);
			this.Controls.Add(this.button2);
			this.Controls.Add(this.Selection);
			this.Controls.Add(this.button1);
			this.Controls.Add(this.label2);
			this.Controls.Add(this.maxy);
			this.Controls.Add(this.miny);
			this.Controls.Add(this.label1);
			this.Controls.Add(this.maxx);
			this.Controls.Add(this.minx);
			this.Controls.Add(this.Fractal);
			this.Name = "Form1";
			this.Text = "Fraktale - zbior Mandelbrot\'a - www.algorytm.org (c) 2008 by Tomasz Lubinski";
			this.Load += new System.EventHandler(this.Form1_Load);
			this.ResumeLayout(false);

		}
		#endregion

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main() 
		{
			Application.Run(new Form1());
		}

		//for HSV colors
		private void HSV2RGB(float hue, float sat, float val, out float red, out float grn, out float blu)
		{
			int i;
			float f, p, q, t;
			red=0; grn=0; blu=0;
			if(val==0) {return;}
			else
			{
				hue/=60;
				i = (int)(hue);
				f = hue-i;
				p = val*(1-sat);
				q = val*(1-(sat*f));
				t = val*(1-(sat*(1-f)));
				if (i==0) {red=val; grn=t; blu=p;}
				else if (i==1) {red=q; grn=val; blu=p;}
				else if (i==2) {red=p; grn=val; blu=t;}
				else if (i==3) {red=p; grn=q; blu=val;}
				else if (i==4) {red=t; grn=p; blu=val;}
				else if (i==5) {red=val; grn=p; blu=q;}
			}
		}

		//initialize color pens
		private void initializeColors()
		{
			float r, g, b;

			for (int i=0; i<penColors.Length-1; i++)
			{
				HSV2RGB((float)2.3*i, (float)0.85, (float)0.6, out r, out g, out b);
				penColors[i] = new Pen(Color.FromArgb((int)(r*255), (int)(g*255), (int)(b*255)));
			}
			penColors[penColors.Length-1] = new Pen(Color.FromArgb(0, 0, 0));
		}

		/// <summary>
		/// Generates fractal - Mandelbrot set
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void button1_Click(object sender, System.EventArgs e)
		{
			int i, j, level;
			complex_t p = new complex_t();

			Fractal.Image = new Bitmap(Fractal.Width, Fractal.Height);
			Graphics graph = Graphics.FromImage(Fractal.Image);
			graph.FillRectangle(new SolidBrush(Color.White), 0, 0, Fractal.Width, Fractal.Height);
			


			minX = double.Parse(minx.Text);
			minY = double.Parse(miny.Text);
			maxX = double.Parse(maxx.Text);
			maxY = double.Parse(maxy.Text);

			ratioX = (maxX - minX) / Fractal.Width;
			ratioY = (maxY - minY) / Fractal.Height;

			for (i=0; i<Fractal.Height; i++)
			{
				p.imaginary = i*ratioY + minY;
				for (j=0; j<Fractal.Width; j++)
				{
					p.real = j*ratioX + minX;
					level = levelSet(p);
					graph.DrawRectangle(penColors[level-1], j, i, 1, 1);
				}
			}
			Fractal.Invalidate();	
		}

		//function z[0]=0
		private complex_t f(complex_t p)
		{
			complex_t result = new complex_t();

			result.real = 0;
			result.imaginary = 0;
			return result;
		}

		//function z[n+1] = z[n]^2 + p
		private complex_t g(complex_t z, complex_t p)
		{
			complex_t result = new complex_t();
			result.real = z.real*z.real - z.imaginary*z.imaginary + p.real;
			result.imaginary = 2*z.real*z.imaginary + p.imaginary;
			return result;
		}

		//value is inside set in the returned level
		private int levelSet(complex_t p)
		{
			complex_t z = new complex_t();
			int iteration;

			iteration = 0;
			z = f(p);

			do
			{
				z = g(z, p);
				iteration++;
			} while (z.complexModSq() < 4 && iteration < 120);

			return iteration;
		}

		//intialize form
		private void Form1_Load(object sender, System.EventArgs e)
		{
			minx.Text = ((double)-2.0).ToString();
			maxx.Text = ((double)0.5).ToString();
			miny.Text = ((double)-1.25).ToString();
			maxy.Text = ((double)1.25).ToString();

			minX = double.Parse(minx.Text);
			minY = double.Parse(miny.Text);
			maxX = double.Parse(maxx.Text);
			maxY = double.Parse(maxy.Text);

			ratioX = (maxX - minX) / Fractal.Width;
			ratioY = (maxY - minY) / Fractal.Height;

			initializeColors();

			Fractal.Image = new Bitmap(Fractal.Width, Fractal.Height);
			graph = Graphics.FromImage(Fractal.Image);

			//render new fractal
			button1_Click(sender, e);
		}

		//draw selection
		private void Fractal_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
		{
			if (e.Button == MouseButtons.Left)
			{
				downX = e.X;
				downY = e.Y;

				Selection.Width = 0;
				Selection.Height = 0;
				Selection.Visible = true;
			}
		}

		//redraw selection
		private void Fractal_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
		{
			if (e.Button == MouseButtons.Left)
			{
				Selection.Width = Math.Abs(downX - e.X);
				Selection.Height = Math.Abs(downY - e.Y);
				Selection.Left = Fractal.Left + Math.Min(downX, e.X);
				Selection.Top = Fractal.Top + Math.Min(downY, e.Y);
			}
		}

		//clear selection - render new fractal for given selection
		private void Fractal_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
		{
			//remove selection
			Selection.Visible = false;

			//get new range to render
			minx.Text = (Math.Min(downX, e.X)*ratioX + minX).ToString();
			maxx.Text = (Math.Max(downX, e.X)*ratioX + minX).ToString();
			miny.Text = (Math.Min(downY, e.Y)*ratioY + minY).ToString();
			maxy.Text = (Math.Max(downY, e.Y)*ratioY + minY).ToString();

			minX = double.Parse(minx.Text);
			minY = double.Parse(miny.Text);
			maxX = double.Parse(maxx.Text);
			maxY = double.Parse(maxy.Text);

			//render new fractal
			button1_Click(sender, e);		
		}
	}

	/// <summary>
	/// Class for complex numbers x = x.real + i*x.imaginary
	/// </summary>
	public class complex_t
	{
		public double real;
		public double imaginary;

		//calculate squared modus of given complex c
		public double complexModSq()
		{
			return (real*real + imaginary*imaginary);
		}
	}
}
Dodaj komentarz