|
|
Alexander Calder, The Star, 1960 |
Le cours aborde deux sujets, les agents autonome et le Perlin noise. A la fin, nous proposons un programme qui combine ce deux techniques. Il est basé sur un code dans le livre "Generative Gestaltung" de Hartmut Bohnacker, Benedikt Groß, Julia Laub, Claudius Lazzeroni.
PerlinNoise
Agent autonom
La synthèse de texture est nommée d'après son inventeur Ken Perlin, qui l'a développé en 1980 pour le Tron film, qui lui a valu un Academy Award en 1997. Ses travaux dans le domaine sont précurseurs de bon nombre de techniques couramment utilisées aujourd'hui dans le monde de l'image de synthèse. Le Perlin noise (bruit) est souvent utilisé dans la synthèse de l'image, afin de simuler des phénomènes naturels tels que les nuages, le paysage, ou de l'eau.
Si on compare le Perlin noise avec la fonction random, on constate que le random genère des chiffres d'une manière pseudo-aléatoire. La fonction de Perlin par contre prend toujours la valeur précédente en compte pour calculer la prochaine. Il en résulte des courbes plus 'naturel'. La valeur de retour de la fonction est normalisée, elle donne en retour une valeur entre 0 et 1. Il faut donc l'adapter à une variance donnée (dans le code, c'est le noiseScale). La douceur de la courbe résultant dépend ensuite de la distance entre les valeurs (noiseDist) dans la fonction de noise. Les valeurs plus petites donnent des 'reliefs' plus doux. Dans notre cas, il faut augmenter la valeur de noiseDist pour adoucir la courbe, car il s'agit d'un dénominateur.
et voici le code:
float noiseScale; float noiseDist = 40; // pour stocker les positions précédents: float x_buff, y_noise_buff, y_random_buff; void setup() { size(500, 100); background(255); float noiseScale = height; for (float x=0; x < width; x++) { float y_noise = noise (x/noiseDist)*noiseScale; float y_random = random(height); stroke(123); line(x_buff, y_random_buff, x, y_random); stroke(#FF0000); line(x_buff, y_noise_buff, x, y_noise); x_buff= x; y_noise_buff = y_noise; y_random_buff = y_random; } }
Dans l'exemple précédent, la valeur y_noise a été calculée par rapport à la valeur de x. La fonction perlin noise permet aussi de calculer son valeur en prenons en compte plusieurs dimensions (2 ou 3 en ce qui concerne la fonction implémenté dans Processing).
random 2D | noise 2D |
le code avec random
void setup() { size(255, 255); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { float gris = random(255); color c = color (gris); set(x, y, c); } } }
le code avec perlinNoise
float noiseScale; float noiseDist = 0.005;// la granularité du noise float x_step; void setup() { size(255, 255); noiseScale = 255;// il s'agit d'un valeur de gris for (int x = 0; x < width; x++) { x_step += noiseDist; float y_step = 0.0; // pour chaque boucle y recommence a 0 for (int y = 0; y < height; y++) { y_step += noiseDist; float gris = noise(x_step, y_step)*noiseScale; color c = color(gris); set(x, y, c); } } }
Pour paramétrer plus précisément la fonction, il y a la méthode noiseDetail, qui prend deux arguments, l'octave et le falloff. Dans la référence de Processing ou sur le site de Paul Bourke il y a des explications plus détaillé. Pour explorer la fonction, essayer l'applet sur le blog de Prossel Software.
La fonction de noiseSeed ressemble à la fonction de randomSeed, elle choisit un 'set de valeur' parmit 10 000. Si cette valeur est déterminée, le courbe du noise donne à chaque relance le même résultat.
Un système d'agent autonome est un système composé d'un ensemble d'agents, situés dans un environnement ou chaque agent à un comportement d'une certaine autonomie. Ce peut-être un processus, un robot, un être humain, etc.
Objet de longue date de recherches en intelligence artificielle distribuée, les systèmes des agents forment un type intéressant de modélisation de sociétés, et ont à ce titre des champs d'application larges, allant jusqu'aux sciences humaines.
Les agents ressemblent en grand parti des particules des cours précédents. Ici, leurs comportement ne résulte pas des forces extérieures, comme la gravité, du vent, mais ils ont une comportement propre. Dans l'exemple suivant, qui a été emprunté du livre "Generative Gestaltung", le comportement de l'agent est généré par la fonction de noise. Elle calcule à chaque cycle l'angle d'avancement avec la fonction est dessine ensuite un trait de l'ancienne position à la nouvelle. Le reste du code ressemble +/- de celui du particule.
class Agent { PVector p, pOld; float stepSize, angle; boolean isOutside = false; Agent() { p = new PVector(random(width), random(height)); pOld = new PVector(p.x, p.y); stepSize = random(1, 5); } void update1() { angle = noise(p.x/noiseStep, p.y/noiseStep) * noiseScale; p.x += cos(angle) * stepSize; p.y += sin(angle) * stepSize; if (p.x<-10) isOutside = true; else if (p.x>width+10) isOutside = true; else if (p.y<-10) isOutside = true; else if (p.y>height+10) isOutside = true; if (isOutside) { p.x = random(width); p.y = random(height); pOld.set(p); } strokeWeight(strokeWidth*stepSize); line(pOld.x, pOld.y, p.x, p.y); pOld.set(p); isOutside = false; } }
Le code a implémenté une interface pour pouvoir manipulé le nombre des agents et ces différents paramètres, tel que le stepSize, le NoiseScale, l'alpha etc.
Voici le code complet
Ce qu'il faut connaître: |