galaxy.inc.php 24.9 KB
Newer Older
Feu's avatar
Feu committed
1 2
<?php

Feu's avatar
test  
Feu committed
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
/* Copyright 2007
 *
 * - Julien Etelain < julien at pmad dot net >
 *
 * "AE Recherche & Developpement" : Galaxy
 *
 * Ce fichier fait partie du site de l'Association des étudiants
 * de l'UTBM, http://ae.utbm.fr.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA.
 */
27

Feu's avatar
Feu committed
28 29 30 31
define("GALAXY_SCORE_1PTPHOTO",1);
define("GALAXY_SCORE_PARRAINAGE",15);
define("GALAXY_SCORE_1PTJOURSASSO",75);
define("GALAXY_MINSCORE",10);
Feu's avatar
Feu committed
32

33 34 35 36 37 38 39 40 41 42 43
/**
 * @defgroup useless Les trucs inutiles
 */

/**
 * Gestionnaire de Galaxy
 *
 *
 * @ingroup useless
 * @author Julien Etelain
 */
Feu's avatar
Feu committed
44 45 46 47
class galaxy
{
  var $db;
  var $dbrw;
48

Feu's avatar
Feu committed
49 50
  var $width;
  var $height;
51

Feu's avatar
test  
Feu committed
52
  var $done_pre_cycle;
53

Feu's avatar
Feu committed
54 55 56 57
  function galaxy ( &$db, &$dbrw )
  {
    $this->db = $db;
    $this->dbrw = $dbrw;
Feu's avatar
test  
Feu committed
58
    $this->done_pre_cycle=false;
59 60
  }

Feu's avatar
test  
Feu committed
61 62 63 64
  /**
   * Vérifie que des données puevent être montrés aux utilisateurs.
   * Pour cela vérifie qu'il existe des éléments avec des coordonnées en pixels.
   */
Feu's avatar
Feu committed
65 66 67 68 69 70 71
  function is_ready_public()
  {
    $req = new requete($this->db,"SELECT * FROM galaxy_star WHERE rx_star IS NOT NULL AND ry_star IS NOT NULL LIMIT 1");
    if ( $req->lines != 1 )
      return false;
    return true;
  }
Feu's avatar
fix  
Feu committed
72

73

Feu's avatar
fix  
Feu committed
74
  function scores ()
Feu's avatar
Feu committed
75 76
  {
    $liens = array();
77

Feu's avatar
Feu committed
78
    // 1- Cacul du score
79

Feu's avatar
Feu committed
80
    // a- Les photos : 1pt / n photo ensemble
Feu's avatar
Feu committed
81 82 83 84 85
    $req = new requete($this->db, "SELECT COUNT( * ) as c, p1.id_utilisateur as u1, p2.id_utilisateur as u2 ".
    "FROM `sas_personnes_photos` AS `p1` ".
    "JOIN `sas_personnes_photos` AS `p2` ON ( p1.id_photo = p2.id_photo ".
    "AND p1.id_utilisateur != p2.id_utilisateur ) ".
    "GROUP BY p1.id_utilisateur, p2.id_utilisateur");
86

Feu's avatar
Feu committed
87 88 89 90
    while ( $row = $req->get_row() )
    {
      $a = min($row['u1'],$row['u2']);
      $b = max($row['u1'],$row['u2']);
91

Feu's avatar
Feu committed
92
      $liens[$a][$b] = round($row['c']/GALAXY_SCORE_1PTPHOTO);
93 94
    }

Feu's avatar
Feu committed
95
    // b- Parrainage : n pt / relation parrain-fillot
Feu's avatar
Feu committed
96 97 98 99 100 101
    $req = new requete($this->db, "SELECT id_utilisateur as u1, id_utilisateur_fillot as u2 ".
    "FROM `parrains` ".
    "GROUP BY id_utilisateur, id_utilisateur_fillot");
    while ( $row = $req->get_row() )
    {
      $a = min($row['u1'],$row['u2']);
102 103
      $b = max($row['u1'],$row['u2']);

Feu's avatar
Feu committed
104
      if ( isset($liens[$a][$b]) )
Feu's avatar
Feu committed
105
        $liens[$a][$b] += GALAXY_SCORE_PARRAINAGE;
Feu's avatar
Feu committed
106
      else
Feu's avatar
Feu committed
107
        $liens[$a][$b] = GALAXY_SCORE_PARRAINAGE;
108 109
    }

Feu's avatar
Feu committed
110
    // c- associations et clubs : 1pt / n jours ensemble / assos
Feu's avatar
Feu committed
111 112 113 114
    $req = new requete($this->db,"SELECT a.id_utilisateur as u1,b.id_utilisateur as u2,
  SUM(DATEDIFF(LEAST(COALESCE(a.date_fin,NOW()),COALESCE(b.date_fin,NOW())),GREATEST(a.date_debut,b.date_debut))) AS together
  FROM asso_membre AS a
  JOIN asso_membre AS b ON
115 116
  (
  a.id_utilisateur < b.id_utilisateur
Feu's avatar
Feu committed
117
  AND a.id_asso = b.id_asso
Feu's avatar
Feu committed
118
  AND DATEDIFF(LEAST(COALESCE(a.date_fin,NOW()),COALESCE(b.date_fin,NOW())),GREATEST(a.date_debut,b.date_debut)) >= ".GALAXY_SCORE_1PTJOURSASSO."
Feu's avatar
Feu committed
119 120 121
  )
  GROUP BY a.id_utilisateur,b.id_utilisateur
  ORDER BY a.id_utilisateur,b.id_utilisateur");
122

Feu's avatar
Feu committed
123 124 125
    while ( $row = $req->get_row() )
    {
      $a = min($row['u1'],$row['u2']);
126 127
      $b = max($row['u1'],$row['u2']);

Feu's avatar
Feu committed
128
      if ( isset($liens[$a][$b]) )
Feu's avatar
Feu committed
129
        $liens[$a][$b] += round($row['together']/GALAXY_SCORE_1PTJOURSASSO);
Feu's avatar
Feu committed
130
      else
Feu's avatar
Feu committed
131
        $liens[$a][$b] = round($row['together']/GALAXY_SCORE_1PTJOURSASSO);
132 133
    }

Feu's avatar
Feu committed
134 135 136 137
    // 2- On vire les liens pas significatifs
    foreach ( $liens as $a => $data )
    {
      foreach ( $data as $b => $score )
Feu's avatar
Feu committed
138
        if ( $score < GALAXY_MINSCORE )
Feu's avatar
Feu committed
139 140
          unset($liens[$a][$b]);
    }
Feu's avatar
fix  
Feu committed
141 142 143

    return $liens;
  }
144 145


Feu's avatar
fix  
Feu committed
146 147 148 149 150 151
  /**
   * Initialise une nouvelle galaxy, le "big bang" en quelque sorte
   */
  function init ( )
  {
    new requete($this->dbrw,"TRUNCATE `galaxy_link`");
    new requete($this->dbrw,"TRUNCATE `galaxy_star`");
152

Feu's avatar
fix  
Feu committed
153
    $liens = $this->scores();
154

Feu's avatar
Feu committed
155 156 157 158 159 160
    // 3- On crée les peronnes requises
    $stars = array();
    foreach ( $liens as $a => $data )
    {
      if ( !isset($stars[$a]) )
        $stars[$a] = $a;
161

Feu's avatar
Feu committed
162 163 164 165
      foreach ( $data as $b => $score )
        if ( !isset($stars[$b]) )
          $stars[$b] = $b;
    }
166

Feu's avatar
Feu committed
167 168
    $gx=0;
    $gy=0;
169

Feu's avatar
Feu committed
170
    $width = floor(sqrt(count($stars)));
171

Feu's avatar
Feu committed
172 173 174 175 176 177 178 179 180
    foreach ( $stars as $id )
    {
      new insert($this->dbrw,"galaxy_star",array( "id_star"=>$id, "x_star" => $gx, "y_star" => $gy ));
      $gx++;
      if ( $gx > $width )
      {
        $gx=0;
        $gy++;
      }
181 182
    }

Feu's avatar
Feu committed
183 184 185 186
    // 4- On crée les liens
    foreach ( $liens as $a => $data )
      foreach ( $data as $b => $score )
        new insert($this->dbrw,"galaxy_link",array( "id_star_a"=>$a, "id_star_b"=>$b, "tense_link" => $score ));
187

Feu's avatar
Feu committed
188 189 190 191
    //fixe_star
    new requete($this->dbrw, "UPDATE galaxy_star SET max_tense_star = ( SELECT MAX(tense_link) FROM galaxy_link WHERE id_star_a=id_star OR id_star_b=id_star )");
    new requete($this->dbrw, "UPDATE galaxy_star SET sum_tense_star = ( SELECT SUM(tense_link) FROM galaxy_link WHERE id_star_a=id_star OR id_star_b=id_star )");
    new requete($this->dbrw, "UPDATE galaxy_star SET nblinks_star = ( SELECT COUNT(*) FROM galaxy_link WHERE id_star_a=id_star OR id_star_b=id_star )");
Feu's avatar
test  
Feu committed
192
    new requete($this->dbrw, "UPDATE galaxy_link SET max_tense_stars_link=( SELECT AVG(max_tense_star) FROM galaxy_star WHERE id_star=id_star_a OR id_star=id_star_b )");
193

Feu's avatar
test  
Feu committed
194
    new requete($this->dbrw, "UPDATE galaxy_link SET ideal_length_link=0.25+((1-(tense_link/max_tense_stars_link))*30)");
Feu's avatar
Feu committed
195
    new requete($this->dbrw, "DELETE FROM galaxy_star WHERE nblinks_star = 0");
196

Feu's avatar
fix  
Feu committed
197
  }
198

Feu's avatar
fix  
Feu committed
199 200 201
  function update()
  {
    $liens = $this->scores();
202

Feu's avatar
fix  
Feu committed
203 204 205 206 207
    $stars = array();
    foreach ( $liens as $a => $data )
    {
      if ( !isset($stars[$a]) )
        $stars[$a] = $a;
208

Feu's avatar
fix  
Feu committed
209 210 211 212
      foreach ( $data as $b => $score )
        if ( !isset($stars[$b]) )
          $stars[$b] = $b;
    }
213

Feu's avatar
fix  
Feu committed
214 215
    $prev_stars = array();
    $prev_liens = array();
216

Feu's avatar
fix  
Feu committed
217
    $req = new requete($this->dbrw, "SELECT id_star FROM galaxy_star");
218

Feu's avatar
fix  
Feu committed
219 220
    while ( list($id) = $req->get_row() )
      $prev_stars[$id] = $id;
221

Feu's avatar
fix  
Feu committed
222
    $req = new requete($this->dbrw, "SELECT id_star_a, id_star_b, tense_link FROM galaxy_link");
223

Feu's avatar
fix  
Feu committed
224 225
    while ( list($a,$b,$c) = $req->get_row() )
      $prev_liens[$a][$b] = $c;
226

Feu's avatar
fix  
Feu committed
227 228 229 230
    // enlève les anciennes étoiles
    foreach ( $prev_stars as $id )
      if ( !isset($stars[$id]) )
        new delete($this->dbrw,"galaxy_star",array( "id_star"=>$id) );
231

Feu's avatar
fix  
Feu committed
232 233 234 235 236
    // enlève les anciens liens
    foreach ( $prev_liens as $a => $data )
      foreach ( $data as $b => $score )
        if (!isset($liens[$a][$b]) )
          new delete($this->dbrw,"galaxy_link",array( "id_star_a"=>$a, "id_star_b"=>$b));
237

238 239 240 241 242 243 244 245 246 247 248
    if ( count($prev_stars) == 0 )
    {
      $x1=0;
      $y1=0;
      $cw=10;
    }
    else
    {
      list($x1,$y1,$x2,$y2) = $this->limits();
      $cw = max($x2-$x1,$y2-$y1);
    }
249

Feu's avatar
fix  
Feu committed
250 251 252 253 254 255
    // ajoute les nouvelles étoiles
    foreach ( $stars as $id )
      if ( !isset($prev_stars[$id]) )
      {
        list($nx,$ny) = $this->find_low_density_point($x1,$y1,$cw);
        new insert($this->dbrw,"galaxy_star",array( "id_star"=>$id, "x_star" => $nx, "y_star" => $ny ));
256 257 258
      }

    // ajoute les nouveaux liens
Feu's avatar
fix  
Feu committed
259 260 261 262
    foreach ( $liens as $a => $data )
      foreach ( $data as $b => $score )
        if (!isset($prev_liens[$a][$b]) )
          new insert($this->dbrw,"galaxy_link",array( "id_star_a"=>$a, "id_star_b"=>$b, "tense_link" => $score ));
263

Feu's avatar
fix  
Feu committed
264 265 266 267 268
    // met à jour les anciens liens
    foreach ( $liens as $a => $data )
      foreach ( $data as $b => $score )
        if ( isset($prev_liens[$a][$b]) && $prev_liens[$a][$b] != $score )
          new update($this->dbrw,"galaxy_link",array("tense_link"=>$score),array("id_star_a"=>$a,"id_star_b"=>$b));
269 270

    // met à jour les champs calculés
Feu's avatar
fix  
Feu committed
271 272 273 274
    new requete($this->dbrw, "UPDATE galaxy_star SET max_tense_star = ( SELECT MAX(tense_link) FROM galaxy_link WHERE id_star_a=id_star OR id_star_b=id_star )");
    new requete($this->dbrw, "UPDATE galaxy_star SET sum_tense_star = ( SELECT SUM(tense_link) FROM galaxy_link WHERE id_star_a=id_star OR id_star_b=id_star )");
    new requete($this->dbrw, "UPDATE galaxy_star SET nblinks_star = ( SELECT COUNT(*) FROM galaxy_link WHERE id_star_a=id_star OR id_star_b=id_star )");
    new requete($this->dbrw, "UPDATE galaxy_link SET max_tense_stars_link=( SELECT AVG(max_tense_star) FROM galaxy_star WHERE id_star=id_star_a OR id_star=id_star_b )");
275

Feu's avatar
fix  
Feu committed
276 277
    new requete($this->dbrw, "UPDATE galaxy_link SET ideal_length_link=0.25+((1-(tense_link/max_tense_stars_link))*30)");
    new requete($this->dbrw, "DELETE FROM galaxy_star WHERE nblinks_star = 0");
278

Feu's avatar
Feu committed
279
  }
280 281 282



Feu's avatar
test  
Feu committed
283 284 285 286 287 288 289 290 291 292 293
  /**
   * Préalable à une série de cycles.
   * Efface les coordonnées en pixels de tous les éléments.
   */
  function pre_cycle ()
  {
    // s'assure que is_ready_public() renverra false pendant les calculs
    // se débloquera après un appel à pre_render() (causé par render() ou mini_render())
    new requete($this->dbrw,"UPDATE `galaxy_star` SET rx_star = NULL, ry_star = NULL");
    $this->done_pre_cycle=true;
  }
294

Feu's avatar
test  
Feu committed
295 296 297 298 299 300
  /**
   * Cycle.
   * Produit les mouvements des objets par le calculs des contraintes aux quels ils sont soumis.
   * Attention: Il n'y a pas de notion d'accélération ou d'intertie.
   * Provoque un appel de pre_cycle() s'il n'a pas eu lieu.
   */
Feu's avatar
Feu committed
301 302
  function cycle ( $detectcollision=false )
  {
Feu's avatar
test  
Feu committed
303 304
    if ( !$this->done_pre_cycle )
      $this->pre_cycle();
305

Feu's avatar
test  
Feu committed
306 307 308 309 310 311 312 313
    new requete($this->dbrw,"UPDATE galaxy_link, galaxy_star AS a, galaxy_star AS b SET ".
    "vx_link = b.x_star-a.x_star, ".
    "vy_link = b.y_star-a.y_star  ".
    "WHERE a.id_star = galaxy_link.id_star_a AND b.id_star = galaxy_link.id_star_b");
    new requete($this->dbrw,"UPDATE galaxy_link SET length_link = SQRT(POW(vx_link,2)+POW(vy_link,2))");
    new requete($this->dbrw,"UPDATE galaxy_link SET dx_link=vx_link/length_link, dy_link=vy_link/length_link WHERE length_link != 0");
    new requete($this->dbrw,"UPDATE galaxy_link SET dx_link=0, dy_link=0 WHERE length_link = ideal_length_link");
    new requete($this->dbrw,"UPDATE galaxy_link SET dx_link=RAND(), dy_link=RAND() WHERE length_link != ideal_length_link AND dx_link=0 AND dy_link=0");
314

Feu's avatar
test  
Feu committed
315
    $req = new requete($this->db,"SELECT MAX(length_link/ideal_length_link),AVG(length_link/ideal_length_link) FROM galaxy_link");
316

Feu's avatar
test  
Feu committed
317
    $reducer=1000;
318

Feu's avatar
test  
Feu committed
319 320
    if ( $req->lines > 0 )
    {
Feu's avatar
test  
Feu committed
321
      list($max,$avg) = $req->get_row();
Feu's avatar
test  
Feu committed
322 323 324 325 326
      if ( $max > 1000 )
      {
        echo "failed due to expension";
        exit();
      }
Feu's avatar
test  
Feu committed
327
      if ( !is_null($max) && $max > 0 )
328
        $reducer = max(25,round($max)*3);
Feu's avatar
Feu committed
329
      //echo $max." ".$avg." (".$reducer.") - ";
330 331
    }

Feu's avatar
test  
Feu committed
332
    new requete($this->dbrw,"UPDATE galaxy_link, galaxy_star AS a, galaxy_star AS b SET  ".
Feu's avatar
test  
Feu committed
333 334 335
    "delta_link_a=(length_link-ideal_length_link)/ideal_length_link/$reducer, ".
    "delta_link_b=(length_link-ideal_length_link)/ideal_length_link/$reducer*-1 ".
    "WHERE a.id_star = galaxy_link.id_star_a AND b.id_star = galaxy_link.id_star_b");
336

Feu's avatar
Feu committed
337 338 339 340 341 342 343 344 345 346 347
    new requete($this->dbrw,"UPDATE galaxy_star SET ".
    "dx_star = COALESCE(( SELECT SUM( delta_link_a * dx_link ) FROM galaxy_link WHERE id_star_a = id_star ),0) + ".
      "COALESCE((SELECT SUM( delta_link_b * dx_link ) FROM galaxy_link WHERE id_star_b = id_star ),0), ".
    "dy_star = COALESCE(( SELECT SUM( delta_link_a * dy_link ) FROM galaxy_link WHERE id_star_a = id_star ),0) + ".
      "COALESCE((SELECT SUM( delta_link_b * dy_link ) FROM galaxy_link WHERE id_star_b = id_star ),0) WHERE fixe_star != 1");
    if ( $detectcollision )
    {
      new requete($this->dbrw,"UPDATE galaxy_star AS a, galaxy_star AS b SET a.dx_star=0, a.dy_star=0, b.dx_star=0, b.dy_star=0 WHERE a.id_star != b.id_star AND POW(a.x_star+a.dx_star-b.x_star-b.dx_star,2)+POW(a.y_star+a.dy_star-b.y_star-b.dy_star,2) < 0.05");
      new requete($this->dbrw,"UPDATE galaxy_star AS a, galaxy_star AS b SET a.dx_star=0, a.dy_star=0, b.dx_star=0, b.dy_star=0 WHERE a.id_star != b.id_star AND POW(a.x_star+a.dx_star-b.x_star-b.dx_star,2)+POW(a.y_star+a.dy_star-b.y_star-b.dy_star,2) < 0.05");
    }
    new requete($this->dbrw,"UPDATE galaxy_star SET x_star = x_star + dx_star, y_star = y_star + dy_star WHERE dx_star != 0 OR dy_star != 0 AND fixe_star != 1");
348 349


Feu's avatar
test  
Feu committed
350
  }
351

Feu's avatar
test  
Feu committed
352 353 354
  /**
   * Provoque un deplacement aleatoir de tous les éléments (+/- 5 sur x et y)
   */
Feu's avatar
test  
Feu committed
355 356 357
  function rand()
  {
    new requete($this->dbrw, "UPDATE `galaxy_star` SET x_star = x_star+5-( RAND( ) *10 ), y_star = y_star+5-( RAND( ) *10)");
Feu's avatar
Feu committed
358
  }
359

Feu's avatar
test  
Feu committed
360 361 362 363 364
  /**
   * Optimise le placement de certains éléments en les renvoyant dans des zones peu denses
   */
  function optimize()
  {
365

Feu's avatar
test  
Feu committed
366
    $req = new requete($this->db,
367
    "SELECT a.id_star, b.x_star, b.y_star, l.ideal_length_link
Feu's avatar
test  
Feu committed
368 369 370 371 372 373 374 375 376 377
     FROM galaxy_star AS a
     INNER JOIN galaxy_link AS l ON ( l.id_star_a = a.id_star )
     INNER JOIN galaxy_star AS b ON ( l.id_star_b = b.id_star )
     WHERE a.nblinks_star=1 AND b.nblinks_star > 1
     UNION
     SELECT b.id_star, a.x_star, a.y_star, l.ideal_length_link
     FROM galaxy_star AS b
     INNER JOIN galaxy_link AS l ON ( l.id_star_b = b.id_star )
     INNER JOIN galaxy_star AS a ON ( l.id_star_a = a.id_star )
     WHERE b.nblinks_star=1 AND a.nblinks_star > 1");
378

Feu's avatar
test  
Feu committed
379 380
    while ( list($id,$cx,$cy,$l) = $req->get_row() )
    {
381
      list($nx,$ny) = $this->find_low_density_point($cx-$l,$cy-$l,$l*2,$id);
Feu's avatar
test  
Feu committed
382 383 384 385 386
      $nx = sprintf("%.f",$nx);
      $ny = sprintf("%.f",$ny);
      //echo "MOVE $id to ($nx, $ny)<br/>\n";
      new requete ( $this->dbrw, "UPDATE galaxy_star set x_star=$nx, y_star=$ny WHERE id_star=$id");
    }
387

Feu's avatar
test  
Feu committed
388
    list($x1,$y1,$x2,$y2) = $this->limits();
Feu's avatar
fix  
Feu committed
389
    $cw = max($x2-$x1,$y2-$y1);
390

Feu's avatar
test  
Feu committed
391
    $req = new requete($this->db,
392
    "SELECT a.id_star, b.id_star, b.x_star, b.y_star
Feu's avatar
test  
Feu committed
393 394 395 396
     FROM galaxy_star AS a
     INNER JOIN galaxy_link AS l ON ( l.id_star_a = a.id_star )
     INNER JOIN galaxy_star AS b ON ( l.id_star_b = b.id_star )
     WHERE a.nblinks_star=1 AND b.nblinks_star=1");
397

Feu's avatar
test  
Feu committed
398 399 400 401 402
    while ( list($ida,$idb,$x,$y) = $req->get_row() )
    {
      $d = $this->get_density ( $x-1, $y-1, $x+1, $y+1, "$ida,$idb" );
      if ( $d > 5 )
      {
403
        list($nx,$ny) = $this->find_low_density_point($x1,$y1,$cw,"$ida,$idb");
Feu's avatar
test  
Feu committed
404 405 406 407
        //echo "MOVE $ida,$idb to ($nx, $ny)<br/>\n";
        new requete ( $this->dbrw, "UPDATE galaxy_star set x_star=$nx, y_star=$ny WHERE id_star=$ida OR id_star=$idb");
      }
    }
408

Feu's avatar
test  
Feu committed
409
  }
410

Feu's avatar
Feu committed
411 412 413 414
  function star_color ( $img, $i )
  {
    if ( $i > 800 )
      return imagecolorallocate($img, 255, 255, 255);
415

Feu's avatar
Feu committed
416
    if ( $i > 700 )
417 418
      return imagecolorallocate($img, (($i-700)*255/100), (($i-700)*255/100), 255);

Feu's avatar
Feu committed
419 420
    if ( $i > 400 )
      return imagecolorallocate($img, 255 -(($i-400)*255/300), 255 -(($i-400)*255/300), ($i-400)*255/300);
421

Feu's avatar
Feu committed
422
    if ( $i > 35 )
423 424 425
      return imagecolorallocate($img, 255, ($i-35)*255/365, 0);

    return imagecolorallocate($img, $i*255/36, 0, 0);
Feu's avatar
Feu committed
426
  }
427

Feu's avatar
test  
Feu committed
428 429 430
  /**
   * Préalable au rendu: fixe les coordonnées en pixels de tous les éléments
   */
Feu's avatar
Feu committed
431 432 433 434
  function pre_render ($tx=100)
  {
    $req = new requete($this->db, "SELECT MIN(x_star), MIN(y_star), MAX(x_star), MAX(y_star) FROM  galaxy_star");
    list($top_x,$top_y,$bottom_x,$bottom_y) = $req->get_row();
435

Feu's avatar
Feu committed
436 437 438 439
    $top_x = floor($top_x);
    $top_y = floor($top_y);
    $bottom_x = ceil($bottom_x);
    $bottom_y = ceil($bottom_y);
440

Feu's avatar
Feu committed
441 442
    $this->width = ($bottom_x-$top_x)*$tx;
    $this->height = ($bottom_y-$top_y)*$tx;
443 444

    $req=new requete($this->dbrw,"UPDATE galaxy_star SET rx_star = (x_star-$top_x) * $tx, ry_star = (y_star-$top_y) * $tx");
Feu's avatar
Feu committed
445
  }
446

Feu's avatar
test  
Feu committed
447 448
  /**
   * Fait le rendu de la mignature de galaxy
Feu's avatar
Feu committed
449
   */
Feu's avatar
wip  
Feu committed
450 451 452 453
  function mini_render ( $mini_target="mini_galaxy_temp.png")
  {
    if ( empty($this->width) || empty($this->height) )
      $this->pre_render();
454

Feu's avatar
test  
Feu committed
455
    $img = imagecreatetruecolor($this->width/50,$this->height/50);
Feu's avatar
wip  
Feu committed
456 457
    $bg = imagecolorallocate($img, 0, 0, 0);
    imagefill($img, 0, 0, $bg);
Feu's avatar
test  
Feu committed
458
    $req = new requete($this->db, "SELECT FLOOR(rx_star/50),FLOOR(ry_star/50),SUM(sum_tense_star) FROM  galaxy_star GROUP BY FLOOR(rx_star/50),FLOOR(ry_star/50)");
459

Feu's avatar
wip  
Feu committed
460
    while ( list($x,$y,$d) = $req->get_row() )
Feu's avatar
wip  
Feu committed
461
      imagesetpixel($img,$x,$y,$this->star_color($img,$d));
462

Feu's avatar
test  
Feu committed
463 464
    $img2 = imagecreatetruecolor($this->width/100,$this->height/100);
    imagecopyresampled($img2,$img,0,0,0,0,$this->width/100,$this->height/100,$this->width/50,$this->height/50);
BenC's avatar
BenC committed
465
    if(is_writable("/var/www/ae/www/ae2/var/"))
BenC's avatar
BenC committed
466
      imagepng($img2,$mini_target);
467 468
    imagedestroy($img2);
    imagedestroy($img);
Feu's avatar
wip  
Feu committed
469
  }
470

Feu's avatar
test  
Feu committed
471 472 473
  /**
   * Fait le rendu de l'image globale de galaxy
   */
474
  function render ($target="galaxy_temp.png")
Feu's avatar
Feu committed
475 476 477
  {
    if ( empty($this->width) || empty($this->height) )
      $this->pre_render();
478

Feu's avatar
Feu committed
479
    $img = imagecreatetruecolor($this->width,$this->height);
480

Feu's avatar
Feu committed
481 482 483 484 485
    if ( $img === false )
    {
      echo "failed imagecreatetruecolor($width,$height);";
      exit();
    }
486

Feu's avatar
Feu committed
487 488
    $bg = imagecolorallocate($img, 0, 0, 0);
    $textcolor = imagecolorallocate($img, 255, 255, 255);
Feu's avatar
test  
Feu committed
489
    $wirecolor = imagecolorallocate($img, 32, 32, 32);
490

Feu's avatar
Feu committed
491
    imagefill($img, 0, 0, $bg);
492

Feu's avatar
Feu committed
493
    imagestring($img, 1, 0, 0, "AE R&D - GALAXY", $textcolor);
494

Feu's avatar
Feu committed
495 496 497
    for($i=0;$i<820;$i++)
    {
      imageline($img,$i,10,$i,20,$this->star_color($img,$i));
498

Feu's avatar
Feu committed
499 500 501
      if ( $i %100 == 0)
        imagestring($img, 1, $i, 22, $i, $textcolor);
    }
502

Feu's avatar
Feu committed
503 504 505 506 507
    $req = new requete($this->db, "SELECT ABS(length_link-ideal_length_link) as ex, ".
    "a.rx_star as x1, a.ry_star as y1, b.rx_star as x2, b.ry_star as y2 ".
    "FROM  galaxy_link ".
    "INNER JOIN galaxy_star AS a ON (a.id_star=galaxy_link.id_star_a) ".
    "INNER JOIN galaxy_star AS b ON (b.id_star=galaxy_link.id_star_b)");
508

Feu's avatar
Feu committed
509 510
    while ( $row = $req->get_row() )
    {
511 512 513
      imageline ($img, $row['x1'], $row['y1'], $row['x2'], $row['y2'], $wirecolor );
    }

Feu's avatar
Feu committed
514 515 516
    $req = new requete($this->db, "SELECT ".
    "rx_star, ry_star, sum_tense_star  ".
    "FROM  galaxy_star");
517

Feu's avatar
Feu committed
518 519
    while ( $row = $req->get_row() )
    {
520
      imagefilledellipse ($img, $row['rx_star'], $row['ry_star'], 5, 5, $this->star_color($img,$row['sum_tense_star']) );
Feu's avatar
Feu committed
521
    }
522

Feu's avatar
Feu committed
523 524 525
    $req = new requete($this->db, "SELECT ".
    "rx_star, ry_star, COALESCE(alias_utl,CONCAT(prenom_utl,' ',nom_utl)) AS nom ".
    "FROM  galaxy_star ".
526 527
    "INNER JOIN utilisateurs ON (utilisateurs.id_utilisateur=galaxy_star.id_star)");

Feu's avatar
Feu committed
528 529 530 531
    while ( $row = $req->get_row() )
    {
      imagestring($img, 1, $row['rx_star']+5, $row['ry_star']-3,  utf8_decode($row['nom']), $textcolor);
    }
532

Feu's avatar
Feu committed
533 534 535 536
    if ( is_null($target) )
      imagepng($img);
    else
      imagepng($img,$target);
Feu's avatar
wip  
Feu committed
537

Feu's avatar
Feu committed
538
    imagedestroy($img);
539

Feu's avatar
Feu committed
540
  }
541

Feu's avatar
test  
Feu committed
542 543 544
  /**
   * Fait le rendu d'une zone de galaxy
   */
Feu's avatar
Feu committed
545
  function render_area ( $tx, $ty, $w, $h, $target=null, $highlight=null )
Feu's avatar
Feu committed
546
  {
Feu's avatar
Feu committed
547
    $x1 = $tx-100; // Pour les textes
Feu's avatar
Feu committed
548 549 550
    $y1 = $ty-3;
    $x2 = $tx+$w+3;
    $y2 = $ty+$h+3;
551

Feu's avatar
Feu committed
552
    $img = imagecreatetruecolor($w,$h);
553

Feu's avatar
Feu committed
554 555 556
    $bg = imagecolorallocate($img, 0, 0, 0);
    $textcolor = imagecolorallocate($img, 255, 255, 255);
    $wirecolor = imagecolorallocate($img, 32, 32, 32);
557 558 559

    imagefill($img, 0, 0, $bg);

Feu's avatar
Feu committed
560 561 562 563 564
    $req = new requete($this->db, "SELECT ABS(length_link-ideal_length_link) as ex, ".
    "a.rx_star as x1, a.ry_star as y1, b.rx_star as x2, b.ry_star as y2 ".
    "FROM  galaxy_link ".
    "INNER JOIN galaxy_star AS a ON (a.id_star=galaxy_link.id_star_a) ".
    "INNER JOIN galaxy_star AS b ON (b.id_star=galaxy_link.id_star_b)");
565

Feu's avatar
Feu committed
566 567
    while ( $row = $req->get_row() )
    {
568 569 570
      imageline ($img, $row['x1']-$tx, $row['y1']-$ty, $row['x2']-$tx, $row['y2']-$ty, $wirecolor );
    }

Feu's avatar
Feu committed
571
    if ( is_null($highlight ) ) // Normal render
Feu's avatar
Feu committed
572
    {
Feu's avatar
Feu committed
573 574 575 576
      $req = new requete($this->db, "SELECT ".
      "rx_star, ry_star, sum_tense_star  ".
      "FROM  galaxy_star ".
      "WHERE rx_star >= $x1 AND rx_star <= $x2 AND ry_star >= $y1 AND ry_star <= $y2");
577

Feu's avatar
Feu committed
578
      while ( $row = $req->get_row() )
579 580
        imagefilledellipse ($img, $row['rx_star']-$tx, $row['ry_star']-$ty, 5, 5, $this->star_color($img,$row['sum_tense_star']) );

Feu's avatar
Feu committed
581 582 583 584
      $req = new requete($this->db, "SELECT ".
      "rx_star, ry_star, COALESCE(alias_utl,CONCAT(prenom_utl,' ',nom_utl)) AS nom ".
      "FROM  galaxy_star ".
      "INNER JOIN utilisateurs ON (utilisateurs.id_utilisateur=galaxy_star.id_star) ".
585 586
      "WHERE rx_star >= $x1 AND rx_star <= $x2 AND ry_star >= $y1 AND ry_star <= $y2" );

Feu's avatar
Feu committed
587 588
      while ( $row = $req->get_row() )
        imagestring($img, 1, $row['rx_star']+5-$tx, $row['ry_star']-3-$ty,  utf8_decode($row['nom']), $textcolor);
589

Feu's avatar
Feu committed
590
    }
Feu's avatar
Feu committed
591
    else
Feu's avatar
Feu committed
592
    {
Feu's avatar
Feu committed
593
      $ids = implode(",",$highlight);
594

Feu's avatar
test  
Feu committed
595
      $wirecolor = imagecolorallocate($img, 64, 64, 64);
Feu's avatar
Feu committed
596 597 598 599 600 601

      $req = new requete($this->db, "SELECT ABS(length_link-ideal_length_link) as ex, ".
      "a.rx_star as x1, a.ry_star as y1, b.rx_star as x2, b.ry_star as y2 ".
      "FROM  galaxy_link ".
      "INNER JOIN galaxy_star AS a ON (a.id_star=galaxy_link.id_star_a) ".
      "INNER JOIN galaxy_star AS b ON (b.id_star=galaxy_link.id_star_b) ".
Feu's avatar
test  
Feu committed
602
      "WHERE a.id_star = ".$highlight[0]." OR b.id_star = ".$highlight[0]."");
603

Feu's avatar
Feu committed
604
      while ( $row = $req->get_row() )
605 606
        imageline ($img, $row['x1']-$tx, $row['y1']-$ty, $row['x2']-$tx, $row['y2']-$ty, $wirecolor );

Feu's avatar
Feu committed
607
      $textcolor = imagecolorallocate($img, 128, 128, 128);
608

Feu's avatar
Feu committed
609 610 611 612
       $req = new requete($this->db, "SELECT ".
      "rx_star, ry_star, sum_tense_star  ".
      "FROM  galaxy_star ".
      "WHERE id_star NOT IN ($ids) AND rx_star >= $x1 AND rx_star <= $x2 AND ry_star >= $y1 AND ry_star <= $y2");
613

Feu's avatar
Feu committed
614
      while ( $row = $req->get_row() )
615 616
        imagefilledellipse ($img, $row['rx_star']-$tx, $row['ry_star']-$ty, 5, 5, $this->star_color($img,$row['sum_tense_star']) );

Feu's avatar
Feu committed
617 618 619 620
      $req = new requete($this->db, "SELECT ".
      "rx_star, ry_star, COALESCE(alias_utl,CONCAT(prenom_utl,' ',nom_utl)) AS nom ".
      "FROM  galaxy_star ".
      "INNER JOIN utilisateurs ON (utilisateurs.id_utilisateur=galaxy_star.id_star) ".
621 622
      "WHERE id_star NOT IN ($ids) AND rx_star >= $x1 AND rx_star <= $x2 AND ry_star >= $y1 AND ry_star <= $y2" );

Feu's avatar
Feu committed
623 624
      while ( $row = $req->get_row() )
        imagestring($img, 1, $row['rx_star']+5-$tx, $row['ry_star']-3-$ty,  utf8_decode($row['nom']), $textcolor);
625

Feu's avatar
Feu committed
626
      $textcolor = imagecolorallocate($img, 255, 255, 255);
627

Feu's avatar
Feu committed
628 629 630 631
       $req = new requete($this->db, "SELECT ".
      "rx_star, ry_star, sum_tense_star  ".
      "FROM  galaxy_star ".
      "WHERE id_star IN ($ids) AND rx_star >= $x1 AND rx_star <= $x2 AND ry_star >= $y1 AND ry_star <= $y2");
632

Feu's avatar
Feu committed
633
      while ( $row = $req->get_row() )
634 635
        imagefilledellipse ($img, $row['rx_star']-$tx, $row['ry_star']-$ty, 5, 5, $this->star_color($img,$row['sum_tense_star']) );

Feu's avatar
Feu committed
636 637 638 639
      $req = new requete($this->db, "SELECT ".
      "rx_star, ry_star, COALESCE(alias_utl,CONCAT(prenom_utl,' ',nom_utl)) AS nom ".
      "FROM  galaxy_star ".
      "INNER JOIN utilisateurs ON (utilisateurs.id_utilisateur=galaxy_star.id_star) ".
640 641
      "WHERE id_star IN ($ids) AND rx_star >= $x1 AND rx_star <= $x2 AND ry_star >= $y1 AND ry_star <= $y2" );

Feu's avatar
Feu committed
642 643
      while ( $row = $req->get_row() )
        imagestring($img, 1, $row['rx_star']+5-$tx, $row['ry_star']-3-$ty,  utf8_decode($row['nom']), $textcolor);
644

Feu's avatar
Feu committed
645
    }
Feu's avatar
Feu committed
646

Feu's avatar
Feu committed
647 648 649 650
    if ( is_null($target) )
      imagepng($img);
    else
      imagepng($img,$target);
651 652 653

    imagedestroy($img);

Feu's avatar
Feu committed
654 655
  }

Feu's avatar
test  
Feu committed
656 657 658
  /**
   * Calcule le nombre d'objet dans la zone donnée.
   */
Feu's avatar
Feu committed
659 660
  function get_density ( $x1, $y1, $x2, $y2, $except=null )
  {
Feu's avatar
Feu committed
661 662 663 664
    $x1 = str_replace(",",".",sprintf("%.f",$x1));
    $y1 = str_replace(",",".",sprintf("%.f",$y1));
    $x2 = str_replace(",",".",sprintf("%.f",$x2));
    $y2 = str_replace(",",".",sprintf("%.f",$y2));
665

Feu's avatar
test  
Feu committed
666
    //echo "get_density($x1,$y1,$x2,$y2) = ";
667

Feu's avatar
Feu committed
668 669 670 671 672 673 674 675 676
    if (is_null($except) )
      $req = new requete($this->db, "SELECT ".
        "COUNT(*)  ".
        "FROM  galaxy_star ".
        "WHERE x_star >= $x1 AND x_star < $x2 AND y_star >= $y1 AND y_star < $y2");
    else
      $req = new requete($this->db, "SELECT ".
        "COUNT(*)  ".
        "FROM  galaxy_star ".
Feu's avatar
Feu committed
677
        "WHERE id_star NOT IN (".$except.") AND x_star >= $x1 AND x_star < $x2 AND y_star >= $y1 AND y_star < $y2");
678

Feu's avatar
Feu committed
679
    list($count) = $req->get_row();
680

Feu's avatar
test  
Feu committed
681
    //echo $count."<br/>\n";
682

Feu's avatar
Feu committed
683 684
    return $count;
  }
685

Feu's avatar
test  
Feu committed
686 687 688
  /**
   * Cherche un point où la densité est faible dans la zone donnée.
   */
Feu's avatar
Feu committed
689 690 691 692 693
  function find_low_density_point ( $x, $y, $s, $except=null )
  {
    $ld = null;
    $lx = null;
    $ly = null;
694

Feu's avatar
Feu committed
695 696
    $cx = $x;
    $cy = $y;
697

Feu's avatar
Feu committed
698 699 700 701
    for($cx=$x;$cx<$x+$s;$cx+=$s/3)
    {
      for($cy=$y;$cy<$y+$s;$cy+=$s/3)
      {
Feu's avatar
Feu committed
702
        $d = $this->get_density($cx,$cy,$cx+($s/3),$cy+($s/3), $except);
Feu's avatar
Feu committed
703
        if ( $d == 0 )
704 705
          return array($cx+($s/6),$cy+($s/6));

Feu's avatar
Feu committed
706 707
        if ( is_null($ld) || $ld > $d )
        {
708
          $lx = $cx;
Feu's avatar
Feu committed
709 710 711 712 713
          $ly = $cy;
          $ld = $d;
        }
      }
    }
714

Feu's avatar
Feu committed
715
    if ( $s < 0.001 )
716 717
      return array($lx+($s/6),$ly+($s/6));

Feu's avatar
Feu committed
718 719
    return $this->find_low_density_point($lx,$ly,$s/3, $except);
  }
720

Feu's avatar
Feu committed
721 722 723 724 725
  function limits()
  {
    $req = new requete($this->db, "SELECT MIN(x_star), MIN(y_star), MAX(x_star), MAX(y_star) FROM  galaxy_star");
    return $req->get_row();
  }
726

Feu's avatar
Feu committed
727 728 729 730 731
}




BenC's avatar
BenC committed
732
?>