web-dev-qa-db-fra.com

Comment programmer une fractale?

Je n'ai aucune expérience en programmation de fractales. Bien sûr, j'ai vu les célèbres images de Mandelbrot et autres.

Pouvez-vous me fournir des algorithmes simples pour les fractales.

Le langage de programmation n'a pas vraiment d'importance, mais je suis le plus familier avec actionscript, C #, Java.

Je sais que si je google fractals, je reçois beaucoup d'informations (compliquées) mais je voudrais commencer avec un algorithme simple et jouer avec.

Les suggestions pour améliorer l'algorithme de base sont également les bienvenues, comme comment les faire dans ces belles couleurs et autres.

70
Sander Versluys

La programmation du Mandelbrot est facile.
Mon code quick-n-dirty est ci-dessous (non garanti sans bug, mais un bon aperçu).

Voici le contour: l'ensemble de Mandelbrot se trouve dans la grille complexe complètement à l'intérieur d'un cercle de rayon 2.

Commencez donc par balayer chaque point de cette zone rectangulaire. Chaque point représente un nombre complexe (x + yi). Itérer ce nombre complexe:

[new value] = [old-value]^2 + [original-value] tout en gardant une trace de deux choses:

1.) le nombre d'itérations

2.) la distance de [nouvelle valeur] par rapport à l'origine.

Si vous atteignez le nombre maximum d'itérations, vous avez terminé. Si la distance de l'origine est supérieure à 2, vous avez terminé.

Une fois terminé, coloriez le pixel d'origine en fonction du nombre d'itérations que vous avez effectuées. Passez ensuite au pixel suivant.

    public void MBrot()
    {
        float epsilon = 0.0001; // The step size across the X and Y axis
        float x;
        float y;
        int maxIterations = 10; // increasing this will give you a more detailed fractal
        int maxColors = 256; // Change as appropriate for your display.

        Complex Z;
        Complex C;
        int iterations;
        for(x=-2; x<=2; x+= epsilon)
        {
            for(y=-2; y<=2; y+= epsilon)
            {
                iterations = 0;
                C = new Complex(x, y);
                Z = new Complex(0,0);
                while(Complex.Abs(Z) < 2 && iterations < maxIterations)
                {
                    Z = Z*Z + C;
                    iterations++;
                }
                Screen.Plot(x,y, iterations % maxColors); // depending on the number of iterations, color a pixel.
            }
        }
    }

Certains détails omis sont:

1.) Apprenez exactement ce qu'est le carré d'un nombre complexe et comment le calculer.

2.) Découvrez comment traduire la région rectangulaire (-2,2) en coordonnées d'écran.

53
abelenky

Vous devriez en effet commencer par ensemble de Mandelbrot , et comprendre ce que c'est vraiment.

L'idée sous-jacente est relativement simple. Vous commencez avec une fonction de variable complexe

f (z) = z2 + C

où z est une variable complexe et C est une constante complexe . Maintenant, vous l'itérez à partir de z = 0, c'est-à-dire que vous calculez z1 = f (0), z2 = f (z1), z3 = f (z2) etc. L'ensemble de ces constantes C pour lesquelles la séquence z1, z2, z3, ... est borné , c'est-à-dire qu'il ne va pas à l'infini, est l'ensemble de Mandelbrot (l'ensemble noir sur la figure de la page Wikipedia).

En pratique, pour dessiner l'ensemble de Mandelbrot, vous devez:

  • Choisissez un rectangle dans le plan complexe (par exemple, du point -2-2i au point 2 + 2i).
  • Couvrez le rectangle avec une grille rectangulaire appropriée de points (disons 400x400 points), qui sera mappée en pixels sur votre moniteur.
  • Pour chaque point/pixel, soit C ce point, calculons, disons, 20 termes de la séquence itérative correspondante z1, z2, z3, ... et vérifiez si cela "va à l'infini". Dans la pratique, vous pouvez vérifier, tout en itérant, si la valeur absolue de l'un des 20 termes est supérieure à 2 (si l'un des termes le fait, les termes suivants sont garantis sans limite). Si certains z_k le font, la séquence "va à l'infini"; sinon, vous pouvez le considérer comme limité.
  • Si la séquence correspondant à un certain point C est bornée, dessinez le pixel correspondant sur l'image en noir (car il appartient à l'ensemble de Mandelbrot). Sinon, dessinez-le dans une autre couleur. Si vous voulez vous amuser et produire de jolies parcelles, dessinez-le dans différentes couleurs en fonction de l'ampleur des abdos (20e terme).

Le fait étonnant sur les fractales est de savoir comment nous pouvons obtenir un ensemble extrêmement complexe (en particulier, la frontière de l'ensemble Mandelbrot) à partir d'exigences faciles et apparemment inoffensives.

Prendre plaisir!

26

Si les nombres complexes vous donnent mal à la tête, il existe un large éventail de fractales qui peuvent être formulées à l'aide d'un système en L. Cela nécessite quelques couches interagissant, mais chacune est intéressante en soi.

Vous avez d'abord besoin d'une tortue. Avant, arrière, gauche, droite, Pen-up, Pen-down. Il y a beaucoup de formes amusantes à faire avec des graphiques de tortues utilisant la géométrie des tortues même sans système L qui les pilote. Recherchez "LOGO graphics" ou "Turtle graphics". Un système LOGO complet est en fait un environnement de programmation LISP utilisant un Cambridge Polish syntaxe. Mais vous n'avez pas besoin d'aller aussi loin pour obtenir de jolies photos en utilisant le concept de tortue.

Ensuite, vous avez besoin d'une couche pour exécuter un système L. Les systèmes L sont liés à Post-systèmes et Systèmes Semi-Thue , et comme virii, ils chevauchent la frontière de la complétude de Turing. Le concept est réécriture de chaînes . Il peut être implémenté comme une macro-expansion ou un ensemble de procédures avec des contrôles supplémentaires pour limiter la récursivité. Si vous utilisez une macro-expansion (comme dans l'exemple ci-dessous), vous aurez toujours besoin d'une procédure définie pour mapper les symboles aux commandes de tortue et une procédure pour parcourir la chaîne ou le tableau pour exécuter le programme de tortue codé. Pour un ensemble de procédures de récursivité bornée ( par exemple. ), vous intégrez les commandes tortue dans les procédures et ajoutez des vérifications au niveau de la récursivité à chaque procédure ou factorisez-les dans une fonction de gestionnaire.

Voici un exemple d'arbre de Pythagore en postscript utilisant une macro-expansion et un ensemble très abrégé de commandes de tortues. Pour quelques exemples dans python et mathématique, voir mon code golf challenge .

ps l-system pythagoras tree luser-droog

9
luser droog

Il y a un grand livre appelé Chaos et fractales qui a un exemple de code simple à la fin de chaque chapitre qui implémente un exemple fractal ou autre. Il y a longtemps, lorsque j'ai lu ce livre, j'ai converti chaque exemple de programme (dans un dialecte de base) en une applet Java qui s'exécute sur une page Web. Les applets sont ici: http://hewgill.com/chaos-and-fractals/

L'un des exemples est une implémentation simple de Mandelbrot.

8
Greg Hewgill

Le triangle de Sierpinski et la courbe de Koch sont des types particuliers de fractales de flamme. Les fractales de flamme sont un type très généralisé de système de fonction itéré, car il utilise des fonctions non linéaires.

Un algorithme pour IFS: es est le suivant:

Start with a random point.

Répétez les opérations suivantes plusieurs fois (un million au moins, selon la taille finale de l'image):

Apply one of N predefined transformations (matrix transformations or similar) to the point. An example would be that multiply each coordinate with 0.5. Plot the new point on the screen.

Si le point est en dehors de l'écran, choisissez plutôt un nouveau au hasard à l'intérieur de l'écran.

Si vous voulez de belles couleurs, laissez la couleur dépendre de la dernière transformation utilisée.

6
Per Alexandersson

Une autre excellente fractale à apprendre est la fractale du triangle de Sierpinski.

Fondamentalement, dessinez trois coins d'un triangle (un équilatéral est préférable, mais n'importe quel triangle fonctionnera), puis démarrez un point P à l'un de ces coins. Déplacez P à mi-chemin dans l'un des 3 coins au hasard et tracez un point là-bas. Déplacer à nouveau P à mi-chemin vers n'importe quel coin aléatoire, dessiner et répéter.

On pourrait penser que le mouvement aléatoire créerait un résultat aléatoire, mais ce n'est vraiment pas le cas.

Référence: http://en.wikipedia.org/wiki/Sierpinski_triangle

6
abelenky

Je commencerais par quelque chose de simple, comme un Koch Snowflake . C'est un processus simple de prendre une ligne et de la transformer, puis de répéter le processus de manière récursive jusqu'à ce qu'il semble net.

Quelque chose de super simple comme prendre 2 points (une ligne) et ajouter un 3ème point (faire un coin), puis répéter sur chaque nouvelle section créée.

fractal(p0, p1){
    Pmid = midpoint(p0,p1) + moved some distance perpendicular to p0 or p1;
    fractal(p0,Pmid);
    fractal(Pmid, p1);
}
5
Dave Baghdanov

Je pense que vous pourriez ne pas voir les fractales comme un algorithme ou quelque chose à programmer. Les fractales sont un concept! Il s'agit d'un concept mathématique de motif détaillé se répétant.

Par conséquent, vous pouvez créer une fractale de plusieurs façons, en utilisant différentes approches, comme indiqué dans l'image ci-dessous.

enter image description here

Choisissez une approche, puis étudiez comment la mettre en œuvre. Ces quatre exemples ont été implémentés en utilisant Marvin Framework . Les codes sources sont disponibles ici

L'ensemble mandelbrot est généré en évaluant à plusieurs reprises une fonction jusqu'à ce qu'elle déborde (une limite définie), puis en vérifiant le temps qu'il vous a fallu pour déborder.

Pseudocode:

MAX_COUNT = 64 // if we haven't escaped to infinity after 64 iterations, 
               // then we're inside the mandelbrot set!!!

foreach (x-pixel)
  foreach (y-pixel)
    calculate x,y as mathematical coordinates from your pixel coordinates
    value = (x, y)
    count = 0
    while value.absolutevalue < 1 billion and count < MAX_COUNT
        value = value * value + (x, y)
        count = count + 1

    // the following should really be one statement, but I split it for clarity
    if count == MAX_COUNT 
        pixel_at (x-pixel, y-pixel) = BLACK
    else 
        pixel_at (x-pixel, y-pixel) = colors[count] // some color map. 

Remarques:

la valeur est un nombre complexe. un nombre complexe (a + b i) est carré pour donner (a a-b * b + 2 * a b i). Vous devrez utiliser un type complexe ou inclure ce calcul dans votre boucle.

3
Jimmy

Voici un code simple et facile à comprendre en Java pour mandelbrot et d'autres exemples fractals

http://code.google.com/p/gaima/wiki/VLFImages

Téléchargez simplement BuildFractal.jar pour le tester dans Java et exécutez avec la commande:

Java -Xmx1500M -jar BuildFractal.jar 1000 1000 par défaut MANDELBROT

Le code source est également gratuit à télécharger/explorer/éditer/développer.

3
reddev

Eh bien, simple et graphiquement attrayant ne vont pas vraiment de pair. Si vous êtes sérieux au sujet de la programmation des fractales, je vous suggère de lire sur les systèmes de fonctions itérés et les progrès qui ont été réalisés dans leur rendu.

http://flam3.com/flame_draves.pdf

2
Algorias

Les personnes ci-dessus utilisent la recherche de points médians pour sierpinski et Koch, je recommanderais beaucoup plus de copier des formes, de les mettre à l'échelle, puis de les traduire pour obtenir l'effet "fractal". Le pseudo-code dans Java pour sierpinski ressemblerait à ceci:

public ShapeObject transform(ShapeObject originalCurve)
    {
        Make a copy of the original curve
        Scale x and y to half of the original
        make a copy of the copied shape, and translate it to the right so it touches the first copied shape
        make a third shape that is a copy of the first copy, and translate it halfway between the first and second shape,and translate it up
        Group the 3 new shapes into one
        return the new shape
    }
1
faeophyta

Parfois, je programme des fractales pour le plaisir et comme défi. Vous pouvez les trouver ici . Le code est écrit en Javascript à l'aide de la bibliothèque P5.js et peut être lu directement à partir du code source HTML.

Pour ceux que j'ai vus, les algorithmes sont assez simples, il suffit de trouver l'élément central et de le répéter encore et encore. Je le fais avec des fonctions récursives, mais cela peut être fait différemment.

1
2dvisio