UP | HOME

Séance 4 : Algo & Prog avec R

Table des matières

1 Prélude

Nous allons utiliser le package TurtleGraphics pour dessiner nos premiers graphiques en R.

install.packages("TurtleGraphics")
library("TurtleGraphics")
  • Quelles sont les différences entre la graphisme cartésien et le graphisme polaire ?
  • Quelles sont les primitives essentielles TurtleGraphics pour chacun d’eux ?

Lorsque vous écrivez plusieurs programmes graphiques dans l’éditeur, vous voudrez sans doute faire une pause d’une ou deux secondes entre chaque dessin. Pour cela, il existe une fonction primitive Sys.sleep(dt) qui prend un nombre réel dt et suspend l’exécution du programme pendant dt secondes. Par exemple, Sys.sleep(2) réalise une pause de 2 secondes. Cherchez l'aide de la fonction Sys.sleep. Vérifiez son fonctionnement en exécutant le code ci-dessous.

library("TurtleGraphics")
turtle_init()
## pour ne pas le recalculer 5 fois  
angle = 360 / 5            
for (i in 1:5) {         
  ## dessin d’un pentagone régulier
  turtle_forward(10)
  Sys.sleep(0.5)            
  turtle_right(angle)
  Sys.sleep(0.5)
}

2 Oursin

Programmez une fonction Oursin(n,c) modélisant un oursin ayant n épines, chaque épine étant d'une couleur différente et de longueur aléatoire dans [0,c]. Vous utiliserez les fonctions runif et rainbow dont vous trouverez l’explication dans les docs …

Oursin <- function(n, c) {
  angle <- 360/n;
  cols  <- rainbow(n)
  epines=runif(n,max=c)
  for (i in 1:n) { 
    turtle_col(cols[i])
    turtle_forward(epines[i])
    turtle_up()
    turtle_backward(epines[i])
    turtle_down()
    turtle_right(angle)
  }
}
library("TurtleGraphics")
turtle_init()
turtle_hide()
Oursin(100,50);

oursin.jpg

3 Bissectrices d'un triangle

Programmez une fonction Equi(c) dessinant un triangle équilatéral de côté c dans la direction du cap courant de la tortue, sur sa gauche. Mais vous tracerez aussi dans une autre couleur une portion des bissectrices intérieures du triangle, de même longueur que le côté.

Equi <- function(c) {
  for (i in 1:3) {         
    ## cote du triangle equilateral
    turtle_forward(c)
    ## bissectrice
    turtle_col("blue")
    turtle_left(120+30)
    turtle_forward(c)
    turtle_col("black")
    turtle_up()
    turtle_backward(c)
    turtle_down()
    turtle_right(30)
  }
}
library("TurtleGraphics")
turtle_init()
Equi(40);

triangle.jpg

4 Flocon de Von Koch

N.B. Vous trouverez des informations sur les courbes fractales avec Google. Un petit livre de Benoit Mandelbrot, l’inventeur de cette théorie, est à la B.U. : Les Objets Fractals.

  1. Nous avons vu en cours (page 19) une fonction traçant une courbe de Von Koch.
    VK <- function(n,T) {        
      ## approximant de niveau n et de base T
      if (n == 0) turtle_forward(T)
      else {
        VK(n-1,T/3)
        turtle_left(60)
        VK(n-1,T/3)
        turtle_right(120)
        VK(n-1,T/3)
        turtle_left(60)
        VK(n-1,T/3)
      }
    }
    
    library("TurtleGraphics")
    n <- 5
    T <- 100
    turtle_init(100,40)
    turtle_hide()
    turtle_up()
    turtle_goto(0,1)
    turtle_down()
    turtle_right(90)
    VK(n,T);
    

    courbe_von_koch.jpg

  2. Programmer le flocon de Von Koch, obtenu en greffant une courbe de Von Koch sur chaque côté d’un triangle équilatéral.
    Flocon <- function(n, T, turn) {
      ## le flocon de Von Koch, tourne vers l'interieur ou l'exterieur
      for (i in 1:3) {
        VK(n,t)
        ## turn = left ou right, je passe une fonction en argument !
        turn(120)         
      }
    }
    
    library("TurtleGraphics")
    turtle_init(115,140)
    turtle_hide()
    turtle_up()
    turtle_goto(5,40)
    turtle_down()
    turtle_right(30)
    Flocon(n, T, turtle_right);
    

    flocon_von_koch.jpg

  3. Expérimenter l’alternative de placer la courbe de Von Koch à l’intérieur plutôt qu’à l’extérieur du flocon. Vous obtiendrez l’anti-flocon cristallin …
    library("TurtleGraphics")
    turtle_init(110,100)
    turtle_hide()
    turtle_up()
    turtle_goto(5,10)
    turtle_down()
    turtle_right(90)
    Flocon(n,T, turtle_left);
    

    antiflocon_von_koch.jpg

5 Fils tendus I

  1. Définissez une fonction Line(x1,y1,x2,y2) traçant le segment reliant les points de coordonnées (x1, y1) et (x2, y2). L’état de la tortue après l’exécution de cette fonction est non spécifié.
    Line <- function(x1, y1, x2, y2) {
      turtle_up();
      turtle_goto(x1,y1);
      turtle_down()
      turtle_goto(x2,y2);
    }
    
    library("TurtleGraphics")
    turtle_init()
    turtle_lwd(3)
    Line(0, 0, 25, 25)
    turtle_col("red")
    Line(25, 25, 75,75)
    turtle_col("blue")
    Line(75, 75, 100, 100)
    

    fils_tendus_0.jpg

  2. Programmez une fonction FilsTendus(length=100, step=10) qui résout l’exercice pour enfants proposé ci-dessous.

    fils2.jpg

    FilsTendus <- function(length=100, step=10) {    
      ## http://jlsigrist.com/images/fils2.jpg
      for (i in seq(step,length-step,step)) {
        turtle_col("gold");
        Line(0,length-i,i,0)
        turtle_col("forestgreen");
        Line(i,length,length,length-i)
      }
    }
    library("TurtleGraphics")
    turtle_init()
    turtle_hide()
    FilsTendus( 100, 2);
    

    fils_tendus_1.jpg

6 Courbes du Dragon

6.1 Courbe de Levy

Programmez l’approximant de niveau n et de taille T de la célèbre courbe fractale de Levy.

Elle est construite de la manière suivante. La courbe de niveau 0 est un segment AB de longueur T. La courbe de niveau 1 est la ligne brisée ACB, toujours avec AB = T. Le triangle isocèle ACB est rectangle en C. Cette transformation est itérée sur chacun des sous-segments AC et CB, et ainsi de suite.

  1. Dessinez à la main les niveaux 3, 4 et 5.
  2. Programmez la fonction Levy(n,T), en traduisant la description ci-dessus en récurrence sur n.

L’argument T [la taille] représente la distance entre le point de départ A et le point d’arrivée B.

Levy <- function(n,T) {
  if (n == 0) turtle_forward(T)
  else {
    Ts <- T / sqrt(2)
    turtle_left(45)
    Dragon(n-1,Ts)
    turtle_right(90)
    Dragon(n-1,Ts)
    turtle_left(45)
  }
}    
library("TurtleGraphics")
n <- 13
T <- 120
turtle_init(200,300)
turtle_hide()
turtle_up()
turtle_goto(150,100)
turtle_down()
Levy(n, T)
turtle_hide()

dragon_1.jpg

6.2 Courbe du dragon

Programmez l’approximant de niveau n et de taille T de la célèbre courbe fractale du dragon.

Dragon <- function(n,T) {
  if (n == 0) turtle_forward(T)
  else {
    Dragon(n-1,T)
    turtle_left(90)
    Nogard(n-1,T)
  }
}

Nogard <- function(n,T) {
  if (n == 0) turtle_forward(T)
  else {
    Dragon(n-1,T)
    turtle_right(90)
    Nogard(n-1,T)
  }
}

library("TurtleGraphics")
n <- 13
T <- 10
turtle_init(2000,1150)
turtle_hide()
turtle_up()
turtle_goto(750,900)
turtle_down()
turtle_hide()
Dragon(n, T)

dragon_2.jpg

7 Le Jeu du Chaos

Il s’agit d’un programme célèbre montrant la possible émergence d’une figure régulière à partir de l’aléatoire. On considère les sommets A(0, T), B(-T, -T) et C(T, -T) d’un triangle isocèle, et le processus suivant. On part d’un point quelconque du canevas M(x0 ; y0) et :

  1. Soit H l’un des sommets A, B, ou C au hasard.
  2. Soit I le milieu du segment MH. On dessine le point I.
  3. M devient I. Continuer à l’étape 1.

Écrire un programme répétant n fois l’affichage du point I décrite ci-dessus. Pour n grand, on voit une figure bien connue des chaoticiens émerger du brouillard !

N.B. Pour afficher un point, vous vous documenterez sur les fonctions sample et plot.

JeuChaos <- function(n, T) {
  ## trianle ABC
  xABC <- c(0, -T,  T);
  yABC <- c(T, -T, -T);
  ## points I
  x <- numeric(n+1);
  y <- numeric(n+1);
  ## tirage des sommets H
  abc<-sample(1:3,n+1, replace = TRUE)
  ## point de départ M quelquonque 
  x[1] <- 0; 
  y[1] <- 0; 
  for (i in 2:(n+1)) {
    ## calcul du milieu I du segment MH 
    x[i] <- (xABC[abc[i]] + x[i-1])/2
    y[i] <- (yABC[abc[i]] + y[i-1])/2
  }
  ## suppression du point de départ
  x <- x[-1]
  y <- y[-1];
  ## tracer les points I
  par(mar = c(1, 1, 1, 1))
  plot(x, y, pch='.', xlab = NA, ylab = NA, labels = FALSE)
}
n <- 20000;
T <- 500  
JeuChaos(n,T)

jeu_chaos.jpg

8 Fils tendus II   HOME

  1. Prolongez l’exercice des fils tendus avec cette image.
    FilsTendusII <- function(n, x0, y0, radius) {
      for (i in 1:(n-1)) {
        angle <- (i*2*pi)/n
        x1 <- x0 + radius * cos(angle)
        y1 <- y0 + radius * sin(angle)
        angle <- ((2*i %% n)*2*pi)/n
        x2 <- x0 + radius * cos(angle)
        y2 <- y0 + radius * sin(angle)
        Line(x1, y1, x2, y2)
       }
    }
    library("TurtleGraphics")
    turtle_init(101,101)
    turtle_hide()
    n <- 200;
    radius <- 50
    FilsTendusII(n, 50, 50, radius)
    

    fils_tendus_2.jpg

  2. Programmez un joli travail en fils tendus : string art.

9 Fleur II   HOME

Programmer une fonction Fleur dont chacun des n pétales est dessinée avec la fonction fleur vue en cours. Étendez la fonction pour choisir le nombre nc de côtés du polygone utilisé pour les pétales.

Polygone <- function(n, c) {
  a <- 360 / n
  for(i in seq(n)) {
    turtle_forward(c)
    turtle_left(a)
  }
}

Fleur <- function(n, np, nc, c) {
   a1 <- 360 / n
   a2 <- 360 / np
   for(i in seq_len(n)) {
     for(j in seq_len(np)) {
       Polygone(nc,c)
       turtle_left(a2)
     }  
     turtle_left(a1)
     turtle_forward(3*c)
   }
 }
library("TurtleGraphics") 
turtle_init()
turtle_hide()  
turtle_up()
turtle_forward(30)
turtle_left(90)
turtle_forward(10)
turtle_down()
Fleur(6,3,4,10)

fleur_demo.jpg

library("TurtleGraphics") 
turtle_init()
turtle_hide()  
turtle_up()
turtle_forward(40)
turtle_left(90)
turtle_forward(5)
turtle_down()
fleur(16,10,5,5)

fleur_penta.jpg

library("TurtleGraphics") 
turtle_init()
turtle_hide()  
turtle_up()
turtle_forward(40)
turtle_left(90)
turtle_forward(5)
turtle_down()
Fleur(16,10,4,5)

fleur_carre.jpg

10 Spirale   HOME

Programmez le dessin sur cette page en vous aidant du pseudo-code.

PolySpiral <- function(dist, angle, incr, segs, width) 
{
  ## start in the center of a square, facing east
  for (i in 1:segs) {
    turtle_forward(dist * 0.6 * width)
    turtle_right(angle)
    dist = dist + incr
  }
}
library("TurtleGraphics")
turtle_init(120,120)
turtle_hide()
turtle_right(90)
PolySpiral(.01, 89.5, .01, 184, 100)

polyspiral.jpg

Created: 2017-11-02 jeu. 13:59