Série 9 – Fractales IFS, jokers : corrigé

Partie 1 : fractales IFS

Le code du corrigé de la première partie vous est fourni sous la forme d'une archive Zip et les solutions aux différents exercices sont rapidement présentées ci-dessous.

Exercice 1

La première version de la méthode points est relativement facile à définir, car il suffit d'utiliser la méthode iterate pour construire le flot infini initial, puis la méthode skip pour ignorer les 20 premiers éléments, la méthode limit pour ne garder que le nombre de points demandé, et finalement la méthode collect pour collecter le résultat dans une liste.

public List<Point> points(long count) {
  Random rng = new Random(12);
  return Stream.iterate(new Point(0, 0),
                        p -> apply(rng.nextInt(), p))
    .skip(20)
    .limit(count)
    .collect(Collectors.toList());
}

La graine utilisée, 12, est quelconque.

Exercice 2

La seconde version de la méthode points comporte trois différences par rapport à la première :

  1. la valeur initiale passée à la méthode iterate (nommée seed ci-dessous) est une paire composée du point initial — qui n'a pas changé — et de l'état initial du générateur,
  2. la fonction de calcul de la prochaine valeur passée à la méthode iterate (nommée next ci-dessous) doit, dès lors, aussi accepter et retourner une paire ; la valeur de cette paire n'est pas difficile à calculer, mais le code Java résultant est un peu indigeste et il est important de se souvenir que le premier élément de la paire (retourné par first) est le point, le second (retourné par second) l'état du générateur,
  3. l'utilisation de la méthode map pour transformer le flot des paires (points, état du générateur) en le flot des points.
public List<Point> points(long count) {
  Pair<Point, PCG> seed =
    new Pair<>(new Point(0, 0), new PCG(12));
  UnaryOperator<Pair<Point, PCG>> next =
    s -> new Pair<>(apply(s.second().get(), s.first()),
                    s.second().next());
  return Stream.iterate(seed, next)
    .map(Pair::first)
    .skip(20)
    .limit(count)
    .collect(Collectors.toList());
}

Exercice 3

La définition du pentagone de Sierpiński ne pose pas de problème particulier et est une simple traduction en Java des fonctions données dans l'énoncé :

IFS sierpinskiPentagon = new IFS.Builder()
  .setMinX(-0.4)
  .setMinY(-0.1)
  .setWidth(1.8)
  .addFunction(p ->
               p.scaled(0.382))
  .addFunction(p ->
               p.scaled(0.382).translated(0.618, 0))
  .addFunction(p ->
               p.scaled(0.382).translated(0.809, 0.588))
  .addFunction(p ->
               p.scaled(0.382).translated(0.309, 0.951))
  .addFunction(p ->
               p.scaled(0.382).translated(-0.191, 0.588))
  .build();

Partie 2 : jokers

Le corrigé de la partie 2 vous est fourni sous la forme d'une archive Zip contenant une version modifiée et commentée des classes Lists et ListsTest.