begin process at 2012 02 11 05:13:46
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Graphique

 > FRACTALE DE MANDELBROT

FRACTALE DE MANDELBROT


 Information sur la source

Note :
Aucune note
Catégorie :Graphique Classé sous :fractale, mandelbrot, canvas, zoom Niveau :Initié Date de création :24/12/2008 Vu / téléchargé :5 028 / 213

Auteur : macsou01

Ecrire un message privé
Site perso
Commentaire sur cette source (8)
Ajouter un commentaire et/ou une note

 Description

Cliquez pour voir la capture en taille normale
Petite application Javascript permettant de représenter la fractale de Mandelbrot et de zoomer sur cette dernière.
Si vous voulez juste essayer, l'adresse est la suivante : http://sd-1.archive-host.com/membres/up/70845355/m andelbrot/index.html. Sinon téléchargez le zip qui contient le html, le css et le js.
Si vous constatez un bug ou si vous voulez faire une suggestion n'hésitez pas.

Source

  • var width; //Largeur du canvas.
  • var height; //Hauteur du canvas.
  • var maxIter; //Précision du dessin.
  • var minX, maxX, minY, maxY; //Variables permettant de définir la zone à dessiner.
  • var pressed = false; //Permet de savoir si on a pressé la souris pour définir la zone à zoomer.
  • var rect; //Rectangle de zoom.
  • var rectX; //Coordonnée x du rectangle de zoom.
  • var rectY; //Coordonnée y du rectangle de zoom.
  • var canvas; //Canvas où est dessinée la fractale.
  • //On crée le canvas (on ne le fait pas dans le html pour avoir une page valide).
  • function init() {
  • canvas = document.createElement('canvas');
  • canvas.height = document.getElementById('size').value;
  • canvas.width = document.getElementById('size').value;
  • canvas.setAttribute('onmousedown', 'start(event);');
  • document.getElementById('canvasDiv').appendChild(canvas);
  • draw();
  • }
  • //Fonction permettant de convertir les coordonnées d'un point du canvas en des coordonnées de nombre complexe.
  • function coordComplex(coordXY, isX) {
  • if(isX)
  • return coordXY * ((maxX - minX) / width) + minX;
  • return coordXY * ((maxY - minY) / height) + minY;
  • }
  • //Fonction permettant de déterminer si le nombre complexe correspondant à la position (x, y) appartient à l'ensemble de Mandelbrot.
  • function nbIter(x, y) {
  • var iter = 0;
  • var zReal = 0;
  • var zImag = 0;
  • var zRealTmp = 0;
  • while (zReal * zReal + zImag * zImag < 4 && iter <= maxIter) {
  • zRealTmp = zReal;
  • zReal = zReal * zReal - zImag * zImag + coordComplex(x, true);
  • zImag = 2 * zRealTmp * zImag + coordComplex(y, false);
  • iter++;
  • }
  • return iter;
  • }
  • //Dessine la fractale.
  • function draw() {
  • if (canvas.getContext){
  • minX = parseFloat(document.getElementById('minX').value);
  • maxX = parseFloat(document.getElementById('maxX').value);
  • minY = parseFloat(document.getElementById('minY').value);
  • maxY = parseFloat(document.getElementById('maxY').value);
  • maxIter = document.getElementById('maxIter').value;
  • width = height = document.getElementById('size').value;
  • var coordsInv = 'Coordonnées invalides :\n';
  • if(maxX == minX)
  • coordsInv += 'maxX = minX.\n';
  • if(maxY == minY)
  • coordsInv += 'maxY = minY.';
  • if(coordsInv != 'Coordonnées invalides :\n')
  • return alert(coordsInv);
  • var r = (maxX - minX) / (maxY - minY); //Permet d'adapter la taille du canvas en fonction des coordonnées données (ou de la zone dessinée).
  • if(r >= 1) {
  • width *= r;
  • } else {
  • height /= r;
  • }
  • canvas.width = width;
  • canvas.height = height;
  • var ctx = canvas.getContext('2d');
  • for(var x = 0; x < width; x++) {
  • for(var y = 0; y < height; y++) {
  • var iter = nbIter(x, y);
  • //Si il existe |Zn|² < 4, le nombre complexe n'appartient pas à l'ensemble de Mandelbrot.
  • //On détermine alors une couleur dépendant de iter.
  • if (iter < maxIter) {
  • var color = 255 - Math.floor(255 * (iter / maxIter));
  • ctx.fillStyle = 'rgb(' + color + ', ' + color + ', ' + color + ')';
  • } else {
  • ctx.fillStyle = '#000000';
  • }
  • ctx.fillRect(x, y, 1, 1);
  • }
  • }
  • } else {
  • alert('Vous utilisez un navigateur qui ne supporte pas la technologie Canvas.');
  • }
  • }
  • //Récupère la position de la souris dès l'appui sur un bouton de la souris.
  • function start(e) {
  • rectX = e.pageX;
  • rectY = e.pageY;
  • rect = document.createElement('div');
  • rect.style.cssText = 'border:solid 1px #000000; background-color:#C0C0C0; opacity:0.5; position:absolute; top:' + e.pageY + 'px; left :' + e.pageX + 'px;';
  • document.body.appendChild(rect);
  • pressed = true;
  • }
  • //Dessine le rectangle lors du mouvement de la souris.
  • function move(e) {
  • if(pressed) {
  • if(e.pageX - rectX > 0) {
  • rect.style.width = (e.pageX - rectX) + 'px';
  • } else {
  • rect.style.left = e.pageX + 'px';
  • rect.style.width = (rectX - e.pageX) + 'px';
  • }
  • if(e.pageY - rectY > 0) {
  • rect.style.height = (e.pageY - rectY) + 'px';
  • } else {
  • rect.style.top = e.pageY + 'px';
  • rect.style.height = (rectY - e.pageY) + 'px';
  • }
  • }
  • }
  • //Zoome sur la fractale lors du relâchement de la souris.
  • function stop(e) {
  • if(pressed) {
  • document.body.removeChild(rect);
  • rectX -= canvas.offsetLeft;
  • rectY -= canvas.offsetTop;
  • document.getElementById('minX').value= Math.min(coordComplex(rectX, true), coordComplex(e.pageX - canvas.offsetLeft, true));
  • document.getElementById('maxX').value = Math.max(coordComplex(rectX, true), coordComplex(e.pageX - canvas.offsetLeft, true));
  • document.getElementById('minY').value = Math.min(coordComplex(rectY, false), coordComplex(e.pageY - canvas.offsetTop, false));
  • document.getElementById('maxY').value = Math.max(coordComplex(rectY, false), coordComplex(e.pageY - canvas.offsetTop, false));
  • draw();
  • pressed = false;
  • }
  • }
var width; //Largeur du canvas.
var height; //Hauteur du canvas.
var maxIter; //Précision du dessin.
var minX, maxX, minY, maxY; //Variables permettant de définir la zone à dessiner.
var pressed = false; //Permet de savoir si on a pressé la souris pour définir la zone à zoomer.
var rect; //Rectangle de zoom.
var rectX; //Coordonnée x du rectangle de zoom.
var rectY; //Coordonnée y du rectangle de zoom.
var canvas; //Canvas où est dessinée la fractale.

//On crée le canvas (on ne le fait pas dans le html pour avoir une page valide).
function init() {
	canvas = document.createElement('canvas');
	canvas.height = document.getElementById('size').value;
	canvas.width = document.getElementById('size').value;
	canvas.setAttribute('onmousedown', 'start(event);');
	document.getElementById('canvasDiv').appendChild(canvas);
	draw();
}

//Fonction permettant de convertir les coordonnées d'un point du canvas en des coordonnées de nombre complexe.
function coordComplex(coordXY, isX) {
	if(isX)
		return coordXY * ((maxX - minX) / width) + minX;
	return coordXY * ((maxY - minY) / height) + minY;
}

//Fonction permettant de déterminer si le nombre complexe correspondant à la position (x, y) appartient à l'ensemble de Mandelbrot.
function nbIter(x, y) {
	var iter = 0;
	var zReal = 0;
	var zImag = 0;
	var zRealTmp = 0;
	while (zReal * zReal + zImag * zImag < 4 && iter <= maxIter) {
		zRealTmp = zReal;
		zReal = zReal * zReal - zImag * zImag + coordComplex(x, true);
		zImag = 2 * zRealTmp * zImag + coordComplex(y, false);
		iter++;
	}
	return iter;
}

//Dessine la fractale.
function draw() {
	if (canvas.getContext){
		minX = parseFloat(document.getElementById('minX').value);
		maxX = parseFloat(document.getElementById('maxX').value);
		minY = parseFloat(document.getElementById('minY').value);
		maxY = parseFloat(document.getElementById('maxY').value);
		maxIter = document.getElementById('maxIter').value;
		width = height = document.getElementById('size').value;
		var coordsInv = 'Coordonnées invalides :\n';
		if(maxX == minX)
			coordsInv += 'maxX = minX.\n';
		if(maxY == minY)
			coordsInv += 'maxY = minY.';
		if(coordsInv != 'Coordonnées invalides :\n')
			return alert(coordsInv);
		var r = (maxX - minX) / (maxY - minY); //Permet d'adapter la taille du canvas en fonction des coordonnées données (ou de la zone dessinée).
		if(r >= 1) {
			width *= r;
		} else {
			height /= r;
		}
		canvas.width = width;
		canvas.height = height;
		var ctx = canvas.getContext('2d');
		for(var x = 0; x < width; x++) {
			for(var y = 0; y < height; y++) {
				var iter = nbIter(x, y);
				//Si il existe |Zn|² < 4, le nombre complexe n'appartient pas à l'ensemble de Mandelbrot.
				//On détermine alors une couleur dépendant de iter.
				if (iter < maxIter) {
					var color = 255 - Math.floor(255 * (iter / maxIter));
					ctx.fillStyle = 'rgb(' + color + ', ' + color + ', ' + color + ')';
				} else {
					ctx.fillStyle = '#000000';
				}
				ctx.fillRect(x, y, 1, 1);
			}
		}
	} else {
		alert('Vous utilisez un navigateur qui ne supporte pas la technologie Canvas.');
	}
}

//Récupère la position de la souris dès l'appui sur un bouton de la souris.
function start(e) {
	rectX = e.pageX;
	rectY = e.pageY;
	rect = document.createElement('div');
	rect.style.cssText = 'border:solid 1px #000000; background-color:#C0C0C0; opacity:0.5; position:absolute; top:' + e.pageY + 'px; left :' + e.pageX + 'px;';
	document.body.appendChild(rect);
	pressed = true;
}

//Dessine le rectangle lors du mouvement de la souris.
function move(e) {
	if(pressed) {
		if(e.pageX - rectX > 0) {
			rect.style.width = (e.pageX - rectX) + 'px';
		} else {
			rect.style.left = e.pageX + 'px';
			rect.style.width = (rectX - e.pageX) + 'px';
		}
		if(e.pageY - rectY > 0) {
			rect.style.height = (e.pageY - rectY) + 'px';
		} else {
			rect.style.top = e.pageY + 'px';
			rect.style.height = (rectY - e.pageY) + 'px';
		}
	}
}

//Zoome sur la fractale lors du relâchement de la souris.
function stop(e) {
	if(pressed) {
		document.body.removeChild(rect);
		rectX -= canvas.offsetLeft;
		rectY -= canvas.offsetTop;
		document.getElementById('minX').value= Math.min(coordComplex(rectX, true), coordComplex(e.pageX - canvas.offsetLeft, true));
		document.getElementById('maxX').value = Math.max(coordComplex(rectX, true), coordComplex(e.pageX - canvas.offsetLeft, true));
		document.getElementById('minY').value = Math.min(coordComplex(rectY, false), coordComplex(e.pageY - canvas.offsetTop, false));
		document.getElementById('maxY').value = Math.max(coordComplex(rectY, false), coordComplex(e.pageY - canvas.offsetTop, false));
		draw();
		pressed = false;
	}
}

 Conclusion

Ca reste assez lent mais on peut pas vraiment faire mieux je pense en Javascript (j'ai utilisé Canvas pour la représentation graphique).
PS : j'ai un peu commenté le javascript, mais pour mieux comprendre, il est mieux de connaître les nombres complexes et de se renseigner sur la fractale de Mandelbrot.

 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Sources du même auteur

Source avec Zip Source avec une capture MISE EN ÉVIDENCE DES ZONES AREA SUR UNE MAP HTML
Source avec Zip Source avec une capture CRÉER UN REFLET D'UNE IMAGE
Source avec Zip Source avec une capture DESSINER DES CERCLES/DISQUES/LIGNES EN JAVASCRIPT
GÉNÉRATEUR DE DÉGRADÉS

 Sources de la même categorie

Source avec Zip Source avec une capture EFFET DE ROTATION A 360° D'IMAGE AVEC ACCELERATION DECELERAT... par kazma
Source avec Zip Source avec une capture PETIT LOGICIEL DE DESSIN, RETOUCHE AVEC CANVAS par kazma
Source avec Zip Source avec une capture CALCULATRICE HEURE par m22001111
Source avec Zip Source avec une capture DRAG & DROP VERS UN CANVAS par kazma
Source avec Zip ROTATION D'UNE IMAGE, ANIMATION par william voirol

 Sources en rapport avec celle ci

Source avec Zip DOODLE JUMP EN JAVASCRIPT par Toshy62
Source avec Zip Source avec une capture CENTRAGE D'IMAGE AVEC PETIT EFFET par kazma
Source avec Zip Source avec une capture LOUPE ET ZOOM par kazma
Source avec Zip Source avec une capture ACTIONJS - FRAMEWORK JAVASCRIPT (HTML5 CANVAS) par Neoziro
Source avec Zip Source avec une capture CANVAS I3D : 3D SOUS JAVASCRIPT SANS WEGGL par Hakumbaya

Commentaires et avis

Commentaire de daguero le 25/12/2008 17:53:06

J'ai factorisé le code ainsi (sans optimisations) et il affiche les résultats en couleur.
Salutations et merci
Dimitri


function draw() {
        var color = 0 ;
var color1 = 0 ;
var color2 = 0 ;
var color3 = 0 ;
if (canvas.getContext){

minX = parseFloat(document.getElementById('minX').value);

maxX = parseFloat(document.getElementById('maxX').value);

minY = parseFloat(document.getElementById('minY').value);

maxY = parseFloat(document.getElementById('maxY').value);

maxIter = document.getElementById('maxIter').value;

width = height = document.getElementById('size').value;

var coordsInv = 'Coordonnées invalides :\n';

if(maxX == minX)

coordsInv += 'maxX = minX.\n';

if(maxY == minY)

coordsInv += 'maxY = minY.';

if(coordsInv != 'Coordonnées invalides :\n')

return alert(coordsInv);

var r = (maxX - minX) / (maxY - minY); //Permet d'adapter la taille du canvas en fonction des coordonnées données (ou de la zone dessinée).

if(r >= 1) {

width *= r;

} else {

height /= r;

}

canvas.width = width;

canvas.height = height;

var ctx = canvas.getContext('2d');

for(var x = 0; x < width; x++) {

for(var y = 0; y < height; y++) {

var iter = nbIter(x, y);

//Si il existe |Zn|² < 4, le nombre complexe n'appartient pas à l'ensemble de Mandelbrot.

//On détermine alors une couleur dépendant de iter.

if (iter < maxIter) {

color = 3*255 - Math.floor(3*255 * (iter / maxIter));
color1 = 0;
color2 = 0;
color3 = 0;
if (color <= 255)                color1 = color;
if (color > 255 && color <= 511) color2 = color-255;
if (color > 511)                 color3 = color-511;
ctx.fillStyle = 'rgb(' + (color1) + ', ' + (color2) + ', ' + (color3) + ')';

} else {

ctx.fillStyle = '#000000';

}

ctx.fillRect(x, y, 1, 1);

}

}

} else {

alert('Vous utilisez un navigateur qui ne supporte pas la technologie Canvas.');

}

}

Commentaire de grobs le 01/01/2009 20:37:57

Afin d'éviter l'effet de pixelisation (et pour rendre la chose un peu plus amusante :) ), tu pourrais retracer la fractale au fur et à mesure que l'on zoom ;-)

Grobs

Commentaire de macsou01 le 01/01/2009 21:43:40

Je ne comprend pas ce que tu veux dire...
L'effet de pixelisation ne dépend pas de la façon dont c'est dessiné mais de la précision de calcul.
De plus, j'ai déjà pensé à dessiner à fur et à mesure, mais je ne sais pas comment faire (car l'instruction qui dessine le pixel est dans des des boucles for et en javascript, ça bloque le navigateur. Mais peut-être qu'avec un timeout... Faut voir ;).

Commentaire de grobs le 01/01/2009 22:05:45

Ma fois, tu sembles avoir très bien compris ce que je veux dire ;)
En gros, il faut recalculer l'affichage de l'endroit précis où l'on est en train de zoomer, comme ça le zoom est parfaitement infini.
Pour ce qui est de la pratique maintenant je ne saurait pas te dire comment y parvenir étant donné que je ne sais pas programmer en JS. Si cela s'avère impossible en JS, fais-le dans un autre langage ^^

Commentaire de macsou01 le 01/01/2009 23:32:38

Oui c'est ça le principe, mais le zoom est en fait défini par des intervalles (xmin, xmax, ymin, ymax), et comme il n'y a que 17 chiffres après la virgule en JS (il me semble), et bien à un moment donné on ne peut plus zoomer (par exemple xmax devient égal à xmin) ;).
Sinon j'ai eu à faire ça en C++ pour un petit projet à faire dans mon IUT (mais sans fonction de zoom à la souris) mais je n'ai pas testé de zoom important avec.

Commentaire de naruto sama le 02/01/2009 11:17:59

je vais surement dire une bêtise, mais pourquoi, ne pas faire ça de manière scientifique et privilégier les puissances de 10 a la virgule, ce qui enlèverai toute limite a ton code :D

Commentaire de macsou01 le 02/01/2009 13:22:50

1.268654869556 * 10^4 par exemple ? Si c'est ça alors c'est la mantisse qui limitera la précision ;).

Commentaire de daguero le 02/01/2009 13:44:53

Pour naruto sama: macsou01 a raison. En virgule flottante, la précision dépend de la quantité de chiffres significatives, dont la limite est définie en dur par l'implémentation du langage de programmation.

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

Zoom sur une image en temps réel [ par EnaelHoly ] Salut à tousVoila en fait je me prend la tête sur une broutille certainement. Mon problème c'est que j'aimerai faire un zoom progressif sur une image Zoom sous Netscape? [ par kimuz ] BonjourPourquoi ce script ne fonctionne pas sous Netscape? &lt;script language="javascript"&gt;&lt;!--<FONT color=#0080 script Zoom image IE firefox [ par tropik99 ] Bonjour,J'ai trouv&#233; sur le net un javascript qui permet de zoomez et d&#233;zoomer sur une image, je l'ai adapt&#233; pour le faire fonctionner a incompatibilité de code [ par J4Gu4R ] voila j'ai 2 javascript: - l'un pour avoir un titre qui zoom - l'autre pour avoir une phrase qui suit la souris comme il y avait une incompatibilité Zoom sur image au passage dur curseur et affichage dans une même fenêtre [ par amewole ] Voici mon problème :Je dois mettre en place un système d'affichage d'un ensemble de photos (vignettes) rangé dans un tableau html et qui s'affiche une Images avec zoom [ par blackoo ] Salut !  Je voulais savoir si quelqu'un connaissait le code pour avoir des images avec zoom / dézoom comme sur ce site www.livewii.fr (ouvrez une news Augmenter le Zoom dans Internt Explorer 7 ! [ par Roulio52 ] Salut à tous,je bloque sur un petit truc avec IE7 (oui je sais c'est pas bien IE :) ).Je cherche en Javascript à créer soit un bouton, soit directemen Zoom "décalé" sur image [ par aloisio11 ] Bonjour à tous, Voici un lien :http://www.habitat.fr/fcp/product/browse/Structure-de-chaise-longue-(toiles-vendues-sépa Zoom sur une image en ajax [ par ircland ] Bonjour,mes niveau de ajax etant nul, et de javascript moyen, je cherche une source qui me permet de zoomer sur une image onmouseover, enfait je veux zoom au passage de la sourie [ par shefentekheux ] Bonjour, j'aimerais savoir si c'est possible et comment faire un effet de zoom sur certaines parties d'une image lorsqu'on passe la souris sur ces zo


Nos sponsors


Sondage...

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 5,912 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales