Images genetiques

Contenu du snippet

salut

je m'ennuyais cette nuit et j'avais envie de faire une pause sur mes autres projets alors j'ai fait ca :

un algorithme genetique de generation d'images aleatoires

Source / Exemple :


<?php
session_start();

// unset($_SESSION['db']);

class Point{
	public function random(){
		$this->x = ( self::$ox + mt_rand(- self::x_max ,self::x_max) / 5 ) % self::x_max;
		$this->y = ( self::$oy + mt_rand(- self::y_max,self::y_max) / 5 ) % self::y_max;

		self::$ox = $this->x;
		self::$oy = $this->x;
	}
	public function mute(){
		$this->x += mt_rand(-5, 5);
		$this->y += mt_rand(-5, 5);
	}
	const x_max = 200;
	const y_max = 200;
	public $x, $y;
	private static $ox = 0, $oy = 0;
}

class polygone{
	public function __construct(){

	}
	public function getImg($img, $black){
		$c = count($this->array) - 1;
		$fp = null;
		$op = null;
		foreach ($this->array as $p){
			if ($fp === null) {
				$fp = $p;
			}else{
			      imageLine($img, $op->x, $op->y, $p->x, $p->y, $black);
			}
			$op = $p;
		}
		imageLine($img, $fp->x, $fp->y, $op->x, $op->y, $black);
	}
	public function random(){
		$this->array = array();
		$number = mt_rand(3,15);
		for ($i = 0; $i<$number ; $i++){
			$this->array[$i] = new Point();
			$this->array[$i]->random();
		}
	}
	public function mute(){
		if (count($this->array) > 3 && mt_rand(0, 10) < 4 ){
			unset($this->array[mt_rand(0, count($this->array) - 1)]);
		}else{
			$p = $array[] = new Point();
			$p->random();
		}
		foreach ($this->array as $p){
			$p->mute();
		}
	}
	private $array;
}

function cmpimgs(Img $a, Img $b){
	return $a->getNote() - $b->getNote();
}

class Img{
	public function __construct(){
		$this->note = 0;
	}
	public function getHtml(){
		return '<a href="imgs.php?checked='.$this->id.'"><img src="imgs.php?id='.$this->id.'" /> ('.$this->note.') </a>';
	}
	public function getImg(){
		$img = imageCreate(200, 200);
		$white = imageColorAllocate($img, 255, 255, 255);
		$black = imageColorAllocate($img, 0, 0, 0);
		foreach ($this->array as $p){
			$p->getImg($img, $black);
		}
		return $img;
	}
	public function random(){
		$this->array = array();
		$number = mt_rand(2,16);
		for ($i = 0; $i<$number ; $i++){
			$this->array[$i] = new polygone();
			$this->array[$i]->random();
		}
	}
	public function setId($id){
		$this->id = $id;
	}
	public function clicked(ImgDatabase $db, $nbr){
		$imgs = $db->getimgs($nbr);
		usort($imgs, 'cmpimgs');
		$this->note += $nbr;
		foreach ($imgs as $img){
			$img->note --;
		}
		if (mt_rand(0, 10) < 4){
			$db->rem($nbr - 1);
		}else {
			$imgs[$nbr - 1]->accoupler($this);
			if (mt_rand(0, 10) < 4){
				$me = clone $this;
				$me->mute();
				$db->store($me);
			}
			if (mt_rand(0, 10) < 4){
				$m = new Img();
				$m->random();
				$db->store($m);
			}
		}
	}
	private function accoupler(Img $i){
		$this->array = array_merge($this->getRPart(), $i->getRPart());
		$this->note = 0;
	}
	private function mute(){
		unset($this->array[mt_rand(0, count($this->array) - 1)]);
		foreach ($this->array as $p){
			if (mt_rand(0, 10) < 4){
				$p->mute();
			}
		}
	}
	private function getRPart(){
		$c = count($this->array);
		$l = mt_rand(5, $c);
		$f = mt_rand(0, $c - $l);
		return array_slice($this->array, $f, $l);
	}
	public function getNote(){
		return $this->note;
	}
	private $array, $id, $note;
}

class ImgDatabase{
	public function __construct(){
		if (!isset($_SESSION['db'])){
			$_SESSION['db'] = array();
		}
		$this->db = $_SESSION['db'];
	}
	public function __destruct(){
		$_SESSION['db'] = $this->db;
	}
	public function getimgs($n){
		return array_slice($this->db, 0, $n);
	}
	public function store($img){
		$this->db[] = $img;
	}
	public function rem($n){
		unset($this->db[$n]);
		$this->db = array_values($this->db);
	}
	public function get($n){
		$out = array();
		$l = count($this->db);
		for ($i=0;$i<$n && $i < $l;$i++){
			$j = mt_rand($i, $l-1);
			$out[$i] = $this->db[$j];
			$this->db[$j] = $this->db[$i];
			$this->db[$i] = $out[$i];
			$this->db[$i]->setId($i);
			$this->db[$j]->setId($j);
		}
		for ($i=$l;$i<$n;$i++){
			$out[$i] = $this->db[$i] = new Img();
			$out[$i]->random();
			$out[$i]->setId($i);
		}
		return $out;
	}
	public function getById($id){
		return $this->db[$id];
	}
	public function getNbrPic(){
		return count($this->db);
	}
	private $db;
}

$db = new ImgDatabase();
$nbr = 8;

function echopage($db, $nbr){
	$imgs = $db->get($nbr);
	?>
	<table>
	<tr>
	<td><?php echo $imgs[0]->getHTML(); ?></td>
	<td><?php echo $imgs[1]->getHTML(); ?></td>
	<td><?php echo $imgs[2]->getHTML(); ?></td>
	</tr>
	<tr>
	<td><?php echo $imgs[3]->getHTML(); ?></td>
	<td><?php echo $imgs[4]->getHTML(); ?></td>
	<td><?php echo $imgs[5]->getHTML(); ?></td>
	</tr>
	<tr>
	<td><?php echo $imgs[6]->getHTML(); ?></td>
	<td><?php echo $imgs[7]->getHTML(); ?></td>
	<td><p><?php echo $db->getNbrPic(); ?></p></td>
	</tr>
	</table>
	<?php
}

if (isset($_GET['checked'])){
	$img = $db->getById((int) $_GET['checked']);
	$img->clicked($db, $nbr);
	echopage($db, $nbr);
}else if (!isset($_GET['id'])){
	echopage($db, $nbr);
}else{
	$img = $db->getById((int) $_GET['id']);
	$a = $img->getImg();
	imagejpeg($a);
}
?>

Conclusion :


les reproductions ne sont pas hyper clean, on pourrait ajouter des options genre :

decaler un groupe de polygones

ne pas ajouter les points qu'on ajoute aux polygones seulement a la fin de ces polygones

ne pas faire bouger de +- 5 tout les points de chaque polygones mutant.

ne pas faire muter tout les polygones

on pourrait aussi ajouter a la selection naturelle : une selection du joyeux mutant (ca reviendrait a generer 5 mutants et enfants, et a demander a l'utilisateur lequel on garde)

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.