Aller au contenu

Triangle de Sierpiński

Un livre de Wikilivres.

Consultez également ces pages dans d’autres projets Wikimedia :

Article encyclopédique sur Wikipédia.
Définition sur Wiktionnaire.
Ressources éducatives sur Wikiversité.

Ces programmes récursifs écrits en C et en Java, permettent de générer des triangles de Sierpiński.

Ce programme utilise la bibliothèque graphique Allegro.

/* pour compiler taper en ligne de commande :
   gcc triangle.c -o triangle `allegro-config --libs`
   pour exécuter taper triangle suivi du nombre d'itérations :
   triangle 7
   */

#include <stdlib.h>
#include <math.h>
#include "allegro.h"

#define MAXX 768
#define MAXY 665
#define OX 5 
#define OY 5
#define TX 758
#define TY 655

BITMAP *bmp;

/* fonction récursive, qui a pour paramètres :
   les coordonnées (x, y) de l'extrémité gauche de la base d'un triangle équilatéral, 
   a la longueur d'un de ses côtés et 
   n le nombre d'itérations */

void triangle_Sierpinski(double x, double y, double a, int n)
{
  double b=-a*sqrt(3.0)/2;
  /* négatif à cause de l'orientation 
     de l'axe des ordonnées vers le bas */
  if (n>0)
    {
      /* on dessine un triangle plein */
      triangle(bmp, (int) x, (int) y, (int) (x+a), (int)y, (int)(x+a/2),(int)(y+b), 4);
      /* et on supprime le petit triangle central */
      triangle(bmp, (int) (x+a/2), (int) y, (int) (x+3*a/4), (int)(y+b/2), (int)(x+a/4),(int)(y+b/2), 0);
      /* appels récursifs */
      triangle_Sierpinski(x, y, a/2, n-1);
      triangle_Sierpinski(x+a/2, y, a/2, n-1);
      triangle_Sierpinski(x+a/4, y+b/2, a/2, n-1);
    }  
}

int main(int argc, char *argv[])
{
  
  unsigned long n=1;
  if (argc>1) n=strtoul(argv[1], NULL, 10);
  
  /* initialisation de allegro */
  allegro_init();
  
  set_color_depth(8);
  
  /* fixe la palette */
  set_palette(desktop_palette);
  
  bmp = create_bitmap(MAXX, MAXY);
  if(!bmp)
    {
      allegro_message("Ne peut pas créer l'image\n");
      return 1;
    }
  
  triangle_Sierpinski(OX, OY+TY, TX, (int)n);
  
  save_bitmap("Triangle_de_Sierpinski.pcx", bmp, desktop_palette);
  destroy_bitmap(bmp);
  
  return 0;
}

END_OF_MAIN();
/* note finale des programmes allegro */

Le programme ci-dessous dessine un triangle de Sierpiński dans une fenêtre en utilisant la bibliothèque Swing pour l'interface utilisateur.

La méthode récursive private void drawSierpinskiTriangle(Graphics g, int[] x, int[] y, int d) accepte des coordonnées de trois points (coins du triangle principal) plus ou moins arbitraires.

Pour compiler (vous devez disposez du JDK Java) : javac SierpinskiTriangle.java

Source de SierpinskiTriangle.java :

/* Nom du fichier : SierpinskiTriangle.java */
package org.wikibooks.fr.swing;

import java.awt.*;

import javax.swing.*;

/**
 * Triangle de Sierpiński
 * @author fr.wikibooks.org
 */
public class SierpinskiTriangle extends JComponent
{
	private final int size;
	private final int d_min = 8;

	public SierpinskiTriangle(int size)
	{
		this.size = size;
		Dimension d = new Dimension(size, size);
		setPreferredSize(d);
		setMinimumSize(d);
	}

	@Override
	protected void paintComponent(Graphics g)
	{
		g.setColor(getBackground());
		g.clearRect(0, 0, size, size);
		g.setColor(getForeground());

		int x0 = 0; // distance de gauche
		int y0 = 0; // distance du haut
		int h = (int) (size * Math.sqrt(3) / 2); // hauteur
		// adapté à un triangle équilatéral

		// spécification du triangle principal: points A, B, C
		int xA = x0, yA = y0 + h; // (bas-gauche)
		int xB = x0 + size, yB = y0 + h; // (bas-droite)
		// int xB=x0, yB=y0; // (haut-gauche)
		// int xB=x0+d, yB=y0; // (haut-droite)
		int xC = x0 + size / 2, yC = y0; // triangle équilatéral (haut-milieu)
		// int xC=x0, yC=y0; // (haut-gauche)
		// triangle perpendiculaire, angle droit près A
		// int xC=x0+d, yC=y0; // (haut-droite)
		// triangle perpendiculaire, angle droit près B
		int[] x = { xA, xB, xC };
		int[] y = { yA, yB, yC };

		drawSierpinskiTriangle(g, x, y, size / 2); // démarrer la récursion
	}

	private void drawSierpinskiTriangle(Graphics g, int[] x, int[] y, int d)
	{
		if (d < d_min)
			g.fillPolygon(x, y, 3); // fin de la récursion
		else
		{
			// milieux des côtés du triangle:
			int xMc = (x[0] + x[1]) / 2, yMc = (y[0] + y[1]) / 2;
			int xMb = (x[0] + x[2]) / 2, yMb = (y[0] + y[2]) / 2;
			int xMa = (x[1] + x[2]) / 2, yMa = (y[1] + y[2]) / 2;

			int[] xNouveau1 =
				{ x[0], xMc, xMb };
			int[] yNouveau1 =
				{ y[0], yMc, yMb };
			drawSierpinskiTriangle(g, xNouveau1, yNouveau1, d / 2); // récursion

			int[] xNouveau2 =
				{ x[1], xMc, xMa };
			int[] yNouveau2 =
				{ y[1], yMc, yMa };
			drawSierpinskiTriangle(g, xNouveau2, yNouveau2, d / 2); // récursion

			int[] xNouveau3 =
				{ x[2], xMb, xMa };
			int[] yNouveau3 =
				{ y[2], yMb, yMa };
			drawSierpinskiTriangle(g, xNouveau3, yNouveau3, d / 2); // récursion
		}
	}

	public static void main(String[] args)
	{
		JFrame f = new JFrame("Triangle de Sierpiński");
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.getContentPane().add(new SierpinskiTriangle(1024));
		f.pack();
		f.setVisible(true);
	}
}