Juliova množina z JS – .NET – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Juliova množina z JS – .NET – Fórum – Programujte.comJuliova množina z JS – .NET – Fórum – Programujte.com

 

Toto vlákno bylo označeno za vyřešené — příspěvek s řešením.
Matěj Andrle+1
Grafoman
5. 3. 2014   #1
-
0
-

Dobrý den,
potřebuji do svého webu nějaké fajné pozadí. Co vystihne programátora a nebude takovým klišé? Napadá mne fraktál. Jako algoritmus patří k programování a navíc dává pěkný výstup... A tak si chci udělat pořádný generátor. Pročež jsem předělal JS Juliovu množinu - zatím do této podoby:

using System;
using System.Drawing;

namespace FraGtal
{
	public class JuliaSet
	{
		public int OffsetX { get; set; }

		public int OffsetY { get; set; }

		public int ExtentX { get; set; }

		public int ExtentY { get; set; }

		public Action<int, int, Color> Draw { get; set; }

		float

			realMin = -1.8f,
			realMax = 1.8f,
			imagMin = -1,
			imagMax = 1,
			CI = .156f,
			CR = -.8f;

		int

			maxIter = 2000,
			x = 0,
			y = 0;

		bool done = false;

		public JuliaSet(int offsetX, int offsetY, int extentX, int extentY)
		{
			OffsetX = offsetX;
			OffsetY = offsetY;

			ExtentX = extentX;
			ExtentY = extentY;
		}

		private int Iterate(float real, float imag)
		{
			int iterations = 0;

			while(real < 4 && imag < 4)
			{
				iterations++;

				if(iterations > maxIter)
					return 0;

				float

					realN = real * real - imag * imag + CR,
					imagN = 2 * imag * real + CI;

				real = realN;
				imag = imagN;
			}

			return iterations;
		}

		public bool Render()
		{
			if(!done)
			{
				float

					real = realMax - realMin,
					imag = imagMax - imagMin;

				for(int xp = x + 10; x < xp; ++x)
					for(y = 0; y < ExtentY; ++y)
						Draw
						(
							x + OffsetX,
							y + OffsetY,
							GetColor(Iterate((x / ExtentX) * real + realMin, (y / ExtentY) * imag + imagMin))
						);

				done = x >= ExtentX;
			}

			return done;
		}

		private Color GetColor(int i)
		{
			float

				r = 0,
				g = 0,
				b = 0,
				p = (i / 200) * 180;

			if(p > 0)
			{
				if(i > 400)
					r = g = (i / 400) * (i > 800 ? 255 : 128);
				else if(p > 120)
					r = (p / 180 * 255) * .55f;
				else if(p > 60)
				{
					g = 75 - (p / 120 * 255);
					r = 50 - g;
				}
				else
				{
					b = 75 - (p / 60 * 255);
					g = 50 - b;
				}
			}

			return Color.FromArgb((int)r, (int)g, (int)b);
		}
	}
}
public void Generate(int width, int height)
{
	JuliaSet algorithm = new JuliaSet(0, 0, width, height);

	algorithm.Draw = (x, y, color) => Canvas.DrawRectangle(new Pen(new SolidBrush(color)), x, y, 1, 1);

	while(!algorithm.Render());
}

Nejsem si jistý některými datovými typy a ještě to bude chtít lepší návrh, avšak fungovat by to již mělo. Break u barvy nasvědčuje tomu, že to jede. Jenže výsledkem je černý obrázek... Nevidí nějaká dobrá duše chybu?
Děkuji...

Nahlásit jako SPAM
IP: 78.136.162.–
Řešení
Matěj Andrle+1
Grafoman
5. 3. 2014   #2
-
0
-
Vyřešeno Nejlepší odpověď

   

using System;
using System.Drawing;

namespace FraGtal
{
	public class JuliaSet
	{
		public int OffsetX { get; set; }

		public int OffsetY { get; set; }

		public int ExtentX { get; set; }

		public int ExtentY { get; set; }

		public Action<float, float, Color> Draw { get; set; }

		float

			realMin = -1.8f,
			realMax = 1.8f,
			imagMin = -1,
			imagMax = 1,
			CI = .156f,
			CR = -.8f,
			x = 0;

		int maxIter = 2000;

		bool done = false;

		public JuliaSet(int offsetX, int offsetY, int extentX, int extentY)
		{
			OffsetX = offsetX;
			OffsetY = offsetY;

			ExtentX = extentX;
			ExtentY = extentY;
		}

		private int Iterate(float real, float imag)
		{
			int iterations = 0;

			while(real < 4 && imag < 4)
			{
				if(iterations++ > maxIter)
					return 0;

				float nextReal = real * real - imag * imag + CR;

				imag = 2 * imag * real + CI;
				real = nextReal;
			}

			return iterations;
		}

		public bool Render()
		{
			if(!done)
			{
				float

					real = realMax - realMin,
					imag = imagMax - imagMin;

				for(float xp = x + 10; x < xp; ++x)
					for(float y = 0; y < ExtentY; ++y)
						Draw
						(
							x + OffsetX,
							y + OffsetY,
							GetColor(Iterate((x / ExtentX) * real + realMin, (y / ExtentY) * imag + imagMin))
						);

				done = x >= ExtentX;
			}

			return done;
		}

		private Color GetColor(float i)
		{
			float

				r = 0,
				g = 0,
				b = 0,
				p = (i / 200) * 180;

			if(p > 0)
			{
				if(i > 400)
					r = g = (i / 400) * (i > 800 ? 255 : 128);
				else if(p > 120)
					r = (p / 180 * 255) * .55f;
				else if(p > 60)
				{
					g = 75 - (p / 120 * 255);
					r = 50 - g;
				}
				else
				{
					b = 75 - (p / 60 * 255);
					g = 50 - b;
				}
			}

			if(r > 255)
				r = 255;

			if(g > 255)
				g = 255;

			if(b > 255)
				b = 255;

			return Color.FromArgb(Math.Abs((int)r), Math.Abs((int)g), Math.Abs((int)b));
		}
	}
}

Jdu teď řešit lepší návrh, aby mi kupříkaldu nemohla vyjít hodnota barvy větší než 255....

Nahlásit jako SPAM
IP: 78.136.162.–
Matěj Andrle+1
Grafoman
6. 3. 2014   #3
-
0
-

S tímto se už téměř spokojím:

using System;
using System.Drawing;

namespace FraGtal
{
	public class JuliaSet
	{
		public int OffsetX { get; set; }

		public int OffsetY { get; set; }

		public int Width { get; set; }

		public int Height { get; set; }

		public int MaxIteration { get; set; }

		public ComplexNumber Difference { get; set; }

		public ComplexNumber Max { get; set; }

		public ComplexNumber Min { get; set; }

		public Action<float, float, Color> Draw { get; set; }

		public JuliaSet()
		{
			Initialization(0, 0, 800, 600, 2000, new ComplexNumber(.156F, -.8F), new ComplexNumber(1, 1.8F), new ComplexNumber(-1, -1.8F));
		}

		public JuliaSet(int x, int y, int width, int height, int maxIteration)
		{
			Initialization(x, y, width, height, maxIteration, new ComplexNumber(.156F, -.8F), new ComplexNumber(1, 1.8F), new ComplexNumber(-1, -1.8F));
		}

		public JuliaSet(int x, int y, int width, int height, int maxIteration, ComplexNumber difference, ComplexNumber max, ComplexNumber min)
		{
			Initialization(x, y, width, height, maxIteration, difference, max, min);
		}

		private void Initialization(int x, int y, int width, int height, int maxIteration, ComplexNumber difference, ComplexNumber max, ComplexNumber min)
		{
			OffsetX = x;
			OffsetY = y;

			Width = width;
			Height = height;

			MaxIteration = maxIteration;

			Difference = difference;
			Max = max;
			Min = min;
		}

		private int Iterate(ComplexNumber value)
		{
			int iterations = 0;

			while(value.Real < 4 && value.Imaginary < 4)
			{
				if(iterations++ > MaxIteration)
					return 0;

				float nextReal = value.Real * value.Real - value.Imaginary * value.Imaginary + Difference.Real;

				value.Imaginary = 2 * value.Imaginary * value.Real + Difference.Imaginary;
				value.Real = nextReal;
			}

			return iterations;
		}

		public void Render()
		{
			ComplexNumber range = new ComplexNumber(Max.Imaginary - Min.Imaginary, Max.Real - Min.Real);

			for(float x = 0; x < Width; ++x)
				for(float y = 0; y < Height; ++y)
					Draw
					(
						x + OffsetX,
						y + OffsetY,
						GetColor(Iterate(new ComplexNumber
						(
							(y / Height) * range.Imaginary + Min.Imaginary,
							(x / Width) * range.Real + Min.Real
						)))
					);

		}

		private Color GetColor(float iterations)
		{
			float

				r = 0,
				g = 0,
				b = 0,
				p = (iterations / 200) * 180;

			if(p > 0)
			{
				if(iterations > 800)
					r = g = iterations / MaxIteration * 255;
				else if(iterations > 400)
					r = g = iterations / 400 * 128;
				else if(p > 120)
					r = (p / 180 * 255) * .55F;
				else if(p > 60)
				{
					g = 75 - (p / 120 * 255);
					r = 50 - g;
				}
				else
				{
					b = 75 - (p / 60 * 255);
					g = 50 - b;
				}
			}

			if(r > 255)
				r = 255;

			if(g > 255)
				g = 255;

			return Color.FromArgb((short)r, Math.Abs((short)g), Math.Abs((short)b));
		}
	}
}
Nahlásit jako SPAM
IP: 78.136.184.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 16 hostů

Podobná vlákna

Množina — založil ukulele

Množina relacie — založil Nika

Množina bez násobků — založil Sak

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý