galaxy.inc.php 26.1 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
    $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 ) ".
85
    "LEFT JOIN utilisateurs usr1 ON (p1.id_utilisateur = usr1.id_utilisateur) ".
mbriand's avatar
mbriand committed
86
    "LEFT JOIN utilisateurs usr2 ON (p2.id_utilisateur = usr2.id_utilisateur) ".
87 88
    "WHERE usr1.publique_utl != '0' ".
    "AND usr2.publique_utl != '0' ".
Feu's avatar
Feu committed
89
    "GROUP BY p1.id_utilisateur, p2.id_utilisateur");
90

Feu's avatar
Feu committed
91 92 93 94
    while ( $row = $req->get_row() )
    {
      $a = min($row['u1'],$row['u2']);
      $b = max($row['u1'],$row['u2']);
95

Feu's avatar
Feu committed
96
      $liens[$a][$b] = round($row['c']/GALAXY_SCORE_1PTPHOTO);
97 98
    }

Feu's avatar
Feu committed
99
    // b- Parrainage : n pt / relation parrain-fillot
Feu's avatar
Feu committed
100 101
    $req = new requete($this->db, "SELECT id_utilisateur as u1, id_utilisateur_fillot as u2 ".
    "FROM `parrains` ".
102
    "LEFT JOIN utilisateurs usr1 ON (parrains.id_utilisateur = usr1.id_utilisateur) ".
mbriand's avatar
mbriand committed
103
    "LEFT JOIN utilisateurs usr2 ON (id_utilisateur_fillot = usr2.id_utilisateur) ".
104 105 106
    "WHERE usr1.publique_utl != '0' ".
    "AND usr2.publique_utl != '0' ".
    "GROUP BY parrains.id_utilisateur, id_utilisateur_fillot");
Feu's avatar
Feu committed
107 108 109
    while ( $row = $req->get_row() )
    {
      $a = min($row['u1'],$row['u2']);
110 111
      $b = max($row['u1'],$row['u2']);

Feu's avatar
Feu committed
112
      if ( isset($liens[$a][$b]) )
Feu's avatar
Feu committed
113
        $liens[$a][$b] += GALAXY_SCORE_PARRAINAGE;
Feu's avatar
Feu committed
114
      else
Feu's avatar
Feu committed
115
        $liens[$a][$b] = GALAXY_SCORE_PARRAINAGE;
116 117
    }

Feu's avatar
Feu committed
118
    // c- associations et clubs : 1pt / n jours ensemble / assos
Feu's avatar
Feu committed
119 120 121 122
    $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
123 124
  (
  a.id_utilisateur < b.id_utilisateur
Feu's avatar
Feu committed
125
  AND a.id_asso = b.id_asso
Feu's avatar
Feu committed
126
  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
127
  )
128
  LEFT JOIN utilisateurs usr1 ON (a.id_utilisateur = usr1.id_utilisateur)
mbriand's avatar
mbriand committed
129
  LEFT JOIN utilisateurs usr2 ON (b.id_utilisateur = usr2.id_utilisateur)
130 131
  WHERE usr1.publique_utl != '0'
  AND usr2.publique_utl != '0'
Feu's avatar
Feu committed
132 133
  GROUP BY a.id_utilisateur,b.id_utilisateur
  ORDER BY a.id_utilisateur,b.id_utilisateur");
134

Feu's avatar
Feu committed
135 136 137
    while ( $row = $req->get_row() )
    {
      $a = min($row['u1'],$row['u2']);
138 139
      $b = max($row['u1'],$row['u2']);

Feu's avatar
Feu committed
140
      if ( isset($liens[$a][$b]) )
Feu's avatar
Feu committed
141
        $liens[$a][$b] += round($row['together']/GALAXY_SCORE_1PTJOURSASSO);
Feu's avatar
Feu committed
142
      else
Feu's avatar
Feu committed
143
        $liens[$a][$b] = round($row['together']/GALAXY_SCORE_1PTJOURSASSO);
144 145
    }

Feu's avatar
Feu committed
146 147 148 149
    // 2- On vire les liens pas significatifs
    foreach ( $liens as $a => $data )
    {
      foreach ( $data as $b => $score )
Feu's avatar
Feu committed
150
        if ( $score < GALAXY_MINSCORE )
Feu's avatar
Feu committed
151 152
          unset($liens[$a][$b]);
    }
Feu's avatar
fix  
Feu committed
153 154 155

    return $liens;
  }
156 157


Feu's avatar
fix  
Feu committed
158 159 160 161 162
  /**
   * Initialise une nouvelle galaxy, le "big bang" en quelque sorte
   */
  function init ( )
  {
163 164
    new requete($this->dbrw,"TRUNCATE `galaxy_link`");
    new requete($this->dbrw,"TRUNCATE `galaxy_star`");
165

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

Feu's avatar
Feu committed
168 169 170 171 172 173
    // 3- On crée les peronnes requises
    $stars = array();
    foreach ( $liens as $a => $data )
    {
      if ( !isset($stars[$a]) )
        $stars[$a] = $a;
174

Feu's avatar
Feu committed
175 176 177 178
      foreach ( $data as $b => $score )
        if ( !isset($stars[$b]) )
          $stars[$b] = $b;
    }
179

Feu's avatar
Feu committed
180 181
    $gx=0;
    $gy=0;
182

Feu's avatar
Feu committed
183
    $width = floor(sqrt(count($stars)));
184

Feu's avatar
Feu committed
185 186 187 188 189 190 191 192 193
    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++;
      }
194 195
    }

Feu's avatar
Feu committed
196 197 198 199
    // 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 ));
200

Feu's avatar
Feu committed
201 202 203 204
    //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
205
    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 )");
206

Feu's avatar
test  
Feu committed
207
    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
208
    new requete($this->dbrw, "DELETE FROM galaxy_star WHERE nblinks_star = 0");
209

Feu's avatar
fix  
Feu committed
210
  }
211

Feu's avatar
fix  
Feu committed
212 213 214
  function update()
  {
    $liens = $this->scores();
215

Feu's avatar
fix  
Feu committed
216 217 218 219 220
    $stars = array();
    foreach ( $liens as $a => $data )
    {
      if ( !isset($stars[$a]) )
        $stars[$a] = $a;
221

Feu's avatar
fix  
Feu committed
222 223 224 225
      foreach ( $data as $b => $score )
        if ( !isset($stars[$b]) )
          $stars[$b] = $b;
    }
226

Feu's avatar
fix  
Feu committed
227 228
    $prev_stars = array();
    $prev_liens = array();
229

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

Feu's avatar
fix  
Feu committed
232 233
    while ( list($id) = $req->get_row() )
      $prev_stars[$id] = $id;
234

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

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

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

Feu's avatar
fix  
Feu committed
245 246 247 248 249
    // 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));
250

251 252 253 254 255 256 257 258 259 260 261
    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);
    }
262

Feu's avatar
fix  
Feu committed
263 264 265 266 267 268
    // 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 ));
269 270 271
      }

    // ajoute les nouveaux liens
Feu's avatar
fix  
Feu committed
272 273 274 275
    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 ));
276

Feu's avatar
fix  
Feu committed
277 278 279 280 281
    // 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));
282 283

    // met à jour les champs calculés
Feu's avatar
fix  
Feu committed
284 285 286 287
    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 )");
288

Feu's avatar
fix  
Feu committed
289 290
    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");
291

Feu's avatar
Feu committed
292
  }
293 294 295



Feu's avatar
test  
Feu committed
296 297 298 299 300 301 302 303 304 305 306
  /**
   * 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;
  }
307

Feu's avatar
test  
Feu committed
308 309 310 311 312 313
  /**
   * 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
314 315
  function cycle ( $detectcollision=false )
  {
Feu's avatar
test  
Feu committed
316 317
    if ( !$this->done_pre_cycle )
      $this->pre_cycle();
318

Feu's avatar
test  
Feu committed
319 320 321 322 323 324 325 326
    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");
327

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

Feu's avatar
test  
Feu committed
330
    $reducer=1000;
331

Feu's avatar
test  
Feu committed
332 333
    if ( $req->lines > 0 )
    {
Feu's avatar
test  
Feu committed
334
      list($max,$avg) = $req->get_row();
Feu's avatar
test  
Feu committed
335 336 337 338 339
      if ( $max > 1000 )
      {
        echo "failed due to expension";
        exit();
      }
Feu's avatar
test  
Feu committed
340
      if ( !is_null($max) && $max > 0 )
341
        $reducer = max(25,round($max)*3);
Feu's avatar
Feu committed
342
      //echo $max." ".$avg." (".$reducer.") - ";
343 344
    }

Feu's avatar
test  
Feu committed
345
    new requete($this->dbrw,"UPDATE galaxy_link, galaxy_star AS a, galaxy_star AS b SET  ".
Feu's avatar
test  
Feu committed
346 347 348
    "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");
349

Feu's avatar
Feu committed
350 351 352 353 354 355 356 357 358 359 360
    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");
361 362


Feu's avatar
test  
Feu committed
363
  }
364

Feu's avatar
test  
Feu committed
365 366 367
  /**
   * Provoque un deplacement aleatoir de tous les éléments (+/- 5 sur x et y)
   */
Feu's avatar
test  
Feu committed
368 369
  function rand()
  {
370
    new requete($this->dbrw, "UPDATE `galaxy_star` SET x_star = x_star+5-( RAND( ) *10 ), y_star = y_star+5-( RAND( ) *10) WHERE fixe_star != 1");
Feu's avatar
Feu committed
371
  }
372

Feu's avatar
test  
Feu committed
373 374 375 376 377
  /**
   * Optimise le placement de certains éléments en les renvoyant dans des zones peu denses
   */
  function optimize()
  {
378

Feu's avatar
test  
Feu committed
379
    $req = new requete($this->db,
380
    "SELECT a.id_star, b.x_star, b.y_star, l.ideal_length_link
Feu's avatar
test  
Feu committed
381 382 383 384 385 386 387 388 389 390
     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");
391

Feu's avatar
test  
Feu committed
392 393
    while ( list($id,$cx,$cy,$l) = $req->get_row() )
    {
394
      list($nx,$ny) = $this->find_low_density_point($cx-$l,$cy-$l,$l*2,$id);
Feu's avatar
test  
Feu committed
395 396 397
      $nx = sprintf("%.f",$nx);
      $ny = sprintf("%.f",$ny);
      //echo "MOVE $id to ($nx, $ny)<br/>\n";
398
      new requete ( $this->dbrw, "UPDATE galaxy_star set x_star=$nx, y_star=$ny WHERE id_star=$id AND fixe_star != 1");
Feu's avatar
test  
Feu committed
399
    }
400

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

Feu's avatar
test  
Feu committed
404
    $req = new requete($this->db,
405
    "SELECT a.id_star, b.id_star, b.x_star, b.y_star
Feu's avatar
test  
Feu committed
406 407 408 409
     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");
410

Feu's avatar
test  
Feu committed
411 412 413 414 415
    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 )
      {
416
        list($nx,$ny) = $this->find_low_density_point($x1,$y1,$cw,"$ida,$idb");
Feu's avatar
test  
Feu committed
417
        //echo "MOVE $ida,$idb to ($nx, $ny)<br/>\n";
418
        new requete ( $this->dbrw, "UPDATE galaxy_star set x_star=$nx, y_star=$ny WHERE id_star=$ida OR id_star=$idb fixe_star != 1");
Feu's avatar
test  
Feu committed
419 420
      }
    }
421

Feu's avatar
test  
Feu committed
422
  }
423

Feu's avatar
Feu committed
424 425 426 427
  function star_color ( $img, $i )
  {
    if ( $i > 800 )
      return imagecolorallocate($img, 255, 255, 255);
428

Feu's avatar
Feu committed
429
    if ( $i > 700 )
430 431
      return imagecolorallocate($img, (($i-700)*255/100), (($i-700)*255/100), 255);

Feu's avatar
Feu committed
432 433
    if ( $i > 400 )
      return imagecolorallocate($img, 255 -(($i-400)*255/300), 255 -(($i-400)*255/300), ($i-400)*255/300);
434

Feu's avatar
Feu committed
435
    if ( $i > 35 )
436 437 438
      return imagecolorallocate($img, 255, ($i-35)*255/365, 0);

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

Feu's avatar
test  
Feu committed
441 442 443
  /**
   * Préalable au rendu: fixe les coordonnées en pixels de tous les éléments
   */
Feu's avatar
Feu committed
444 445 446 447
  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();
448

Feu's avatar
Feu committed
449 450 451 452
    $top_x = floor($top_x);
    $top_y = floor($top_y);
    $bottom_x = ceil($bottom_x);
    $bottom_y = ceil($bottom_y);
453

Feu's avatar
Feu committed
454 455
    $this->width = ($bottom_x-$top_x)*$tx;
    $this->height = ($bottom_y-$top_y)*$tx;
456 457

    $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
458
  }
459

Feu's avatar
test  
Feu committed
460 461
  /**
   * Fait le rendu de la mignature de galaxy
Feu's avatar
Feu committed
462
   */
Feu's avatar
wip  
Feu committed
463 464 465 466
  function mini_render ( $mini_target="mini_galaxy_temp.png")
  {
    if ( empty($this->width) || empty($this->height) )
      $this->pre_render();
467

Feu's avatar
test  
Feu committed
468
    $img = imagecreatetruecolor($this->width/50,$this->height/50);
Feu's avatar
wip  
Feu committed
469 470
    $bg = imagecolorallocate($img, 0, 0, 0);
    imagefill($img, 0, 0, $bg);
Feu's avatar
test  
Feu committed
471
    $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)");
472

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

Feu's avatar
test  
Feu committed
476 477
    $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);
Antoine Tenart's avatar
kwain  
Antoine Tenart committed
478
    if(is_writable("/var/www/ae2/data/img/"))
BenC's avatar
BenC committed
479
      imagepng($img2,$mini_target);
480 481
    imagedestroy($img2);
    imagedestroy($img);
Feu's avatar
wip  
Feu committed
482
  }
483

Feu's avatar
test  
Feu committed
484 485 486
  /**
   * Fait le rendu de l'image globale de galaxy
   */
487
  function render ($target="galaxy_temp.png")
Feu's avatar
Feu committed
488 489 490
  {
    if ( empty($this->width) || empty($this->height) )
      $this->pre_render();
491

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

Feu's avatar
Feu committed
494 495 496 497 498
    if ( $img === false )
    {
      echo "failed imagecreatetruecolor($width,$height);";
      exit();
    }
499

Feu's avatar
Feu committed
500 501
    $bg = imagecolorallocate($img, 0, 0, 0);
    $textcolor = imagecolorallocate($img, 255, 255, 255);
Feu's avatar
test  
Feu committed
502
    $wirecolor = imagecolorallocate($img, 32, 32, 32);
503

Feu's avatar
Feu committed
504
    imagefill($img, 0, 0, $bg);
505

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

Feu's avatar
Feu committed
508 509 510
    for($i=0;$i<820;$i++)
    {
      imageline($img,$i,10,$i,20,$this->star_color($img,$i));
511

Feu's avatar
Feu committed
512 513 514
      if ( $i %100 == 0)
        imagestring($img, 1, $i, 22, $i, $textcolor);
    }
515

Feu's avatar
Feu committed
516 517 518 519 520
    $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)");
521

Feu's avatar
Feu committed
522 523
    while ( $row = $req->get_row() )
    {
524 525 526
      imageline ($img, $row['x1'], $row['y1'], $row['x2'], $row['y2'], $wirecolor );
    }

Feu's avatar
Feu committed
527 528 529
    $req = new requete($this->db, "SELECT ".
    "rx_star, ry_star, sum_tense_star  ".
    "FROM  galaxy_star");
530

Feu's avatar
Feu committed
531 532
    while ( $row = $req->get_row() )
    {
533
      imagefilledellipse ($img, $row['rx_star'], $row['ry_star'], 5, 5, $this->star_color($img,$row['sum_tense_star']) );
Feu's avatar
Feu committed
534
    }
535

Feu's avatar
Feu committed
536
    $req = new requete($this->db, "SELECT ".
mbriand's avatar
mbriand committed
537
    "rx_star, ry_star, COALESCE(surnom_utbm, CONCAT(prenom_utl,' ',nom_utl), alias_utl) AS nom ".
Feu's avatar
Feu committed
538
    "FROM  galaxy_star ".
539 540
    "INNER JOIN utilisateurs ON (utilisateurs.id_utilisateur=galaxy_star.id_star)".
    "INNER JOIN `utl_etu_utbm` ON (`utl_etu_utbm`.`id_utilisateur` = `utilisateurs`.`id_utilisateur`)");
541

Feu's avatar
Feu committed
542 543 544 545
    while ( $row = $req->get_row() )
    {
      imagestring($img, 1, $row['rx_star']+5, $row['ry_star']-3,  utf8_decode($row['nom']), $textcolor);
    }
546

Feu's avatar
Feu committed
547 548 549 550
    if ( is_null($target) )
      imagepng($img);
    else
      imagepng($img,$target);
Feu's avatar
wip  
Feu committed
551

Feu's avatar
Feu committed
552
    imagedestroy($img);
553

Feu's avatar
Feu committed
554
  }
555

Feu's avatar
test  
Feu committed
556 557 558
  /**
   * Fait le rendu d'une zone de galaxy
   */
Feu's avatar
Feu committed
559
  function render_area ( $tx, $ty, $w, $h, $target=null, $highlight=null )
Feu's avatar
Feu committed
560
  {
Feu's avatar
Feu committed
561
    $x1 = $tx-100; // Pour les textes
Feu's avatar
Feu committed
562 563 564
    $y1 = $ty-3;
    $x2 = $tx+$w+3;
    $y2 = $ty+$h+3;
565

Feu's avatar
Feu committed
566
    $img = imagecreatetruecolor($w,$h);
567

Feu's avatar
Feu committed
568 569 570
    $bg = imagecolorallocate($img, 0, 0, 0);
    $textcolor = imagecolorallocate($img, 255, 255, 255);
    $wirecolor = imagecolorallocate($img, 32, 32, 32);
571 572 573

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

Feu's avatar
Feu committed
574 575 576 577 578
    $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)");
579

Feu's avatar
Feu committed
580 581
    while ( $row = $req->get_row() )
    {
582 583 584
      imageline ($img, $row['x1']-$tx, $row['y1']-$ty, $row['x2']-$tx, $row['y2']-$ty, $wirecolor );
    }

Feu's avatar
Feu committed
585
    if ( is_null($highlight ) ) // Normal render
Feu's avatar
Feu committed
586
    {
Feu's avatar
Feu committed
587 588 589 590
      $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");
591

Feu's avatar
Feu committed
592
      while ( $row = $req->get_row() )
593 594
        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
595
      $req = new requete($this->db, "SELECT ".
mbriand's avatar
mbriand committed
596
      "rx_star, ry_star, COALESCE(surnom_utbm, CONCAT(prenom_utl,' ',nom_utl), alias_utl) AS nom ".
Feu's avatar
Feu committed
597 598
      "FROM  galaxy_star ".
      "INNER JOIN utilisateurs ON (utilisateurs.id_utilisateur=galaxy_star.id_star) ".
mbriand's avatar
mbriand committed
599
      "LEFT JOIN `utl_etu_utbm` ON (`utl_etu_utbm`.`id_utilisateur` = `utilisateurs`.`id_utilisateur`)".
600 601
      "WHERE rx_star >= $x1 AND rx_star <= $x2 AND ry_star >= $y1 AND ry_star <= $y2" );

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

Feu's avatar
Feu committed
605
    }
Feu's avatar
Feu committed
606
    else
Feu's avatar
Feu committed
607
    {
Feu's avatar
Feu committed
608
      $ids = implode(",",$highlight);
609

Feu's avatar
test  
Feu committed
610
      $wirecolor = imagecolorallocate($img, 64, 64, 64);
Feu's avatar
Feu committed
611 612 613 614 615 616

      $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
617
      "WHERE a.id_star = ".$highlight[0]." OR b.id_star = ".$highlight[0]."");
618

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

Feu's avatar
Feu committed
622
      $textcolor = imagecolorallocate($img, 128, 128, 128);
623

Feu's avatar
Feu committed
624 625 626 627
       $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");
628

Feu's avatar
Feu committed
629
      while ( $row = $req->get_row() )
630 631
        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
632
      $req = new requete($this->db, "SELECT ".
mbriand's avatar
mbriand committed
633
      "rx_star, ry_star, COALESCE(surnom_utbm, CONCAT(prenom_utl,' ',nom_utl), alias_utl) AS nom ".
Feu's avatar
Feu committed
634 635
      "FROM  galaxy_star ".
      "INNER JOIN utilisateurs ON (utilisateurs.id_utilisateur=galaxy_star.id_star) ".
mbriand's avatar
mbriand committed
636
      "LEFT JOIN `utl_etu_utbm` ON (`utl_etu_utbm`.`id_utilisateur` = `utilisateurs`.`id_utilisateur`)".
637 638
      "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
639 640
      while ( $row = $req->get_row() )
        imagestring($img, 1, $row['rx_star']+5-$tx, $row['ry_star']-3-$ty,  utf8_decode($row['nom']), $textcolor);
641

Feu's avatar
Feu committed
642
      $textcolor = imagecolorallocate($img, 255, 255, 255);
643

Feu's avatar
Feu committed
644 645 646 647
       $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");
648

Feu's avatar
Feu committed
649
      while ( $row = $req->get_row() )
650 651
        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
652
      $req = new requete($this->db, "SELECT ".
mbriand's avatar
mbriand committed
653
      "rx_star, ry_star, COALESCE(surnom_utbm, CONCAT(prenom_utl,' ',nom_utl), alias_utl) AS nom ".
Feu's avatar
Feu committed
654 655
      "FROM  galaxy_star ".
      "INNER JOIN utilisateurs ON (utilisateurs.id_utilisateur=galaxy_star.id_star) ".
mbriand's avatar
mbriand committed
656
      "LEFT JOIN `utl_etu_utbm` ON (`utl_etu_utbm`.`id_utilisateur` = `utilisateurs`.`id_utilisateur`)".
657 658
      "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
659 660
      while ( $row = $req->get_row() )
        imagestring($img, 1, $row['rx_star']+5-$tx, $row['ry_star']-3-$ty,  utf8_decode($row['nom']), $textcolor);
661

Feu's avatar
Feu committed
662
    }
Feu's avatar
Feu committed
663

Feu's avatar
Feu committed
664 665 666 667
    if ( is_null($target) )
      imagepng($img);
    else
      imagepng($img,$target);
668 669 670

    imagedestroy($img);

Feu's avatar
Feu committed
671 672
  }

Feu's avatar
test  
Feu committed
673 674 675
  /**
   * Calcule le nombre d'objet dans la zone donnée.
   */
Feu's avatar
Feu committed
676 677
  function get_density ( $x1, $y1, $x2, $y2, $except=null )
  {
Feu's avatar
Feu committed
678 679 680 681
    $x1 = str_replace(",",".",sprintf("%.f",$x1));
    $y1 = str_replace(",",".",sprintf("%.f",$y1));
    $x2 = str_replace(",",".",sprintf("%.f",$x2));
    $y2 = str_replace(",",".",sprintf("%.f",$y2));
682

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

Feu's avatar
Feu committed
685 686 687 688 689 690 691 692 693
    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
694
        "WHERE id_star NOT IN (".$except.") AND x_star >= $x1 AND x_star < $x2 AND y_star >= $y1 AND y_star < $y2");
695

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

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

Feu's avatar
Feu committed
700 701
    return $count;
  }
702

Feu's avatar
test  
Feu committed
703 704 705
  /**
   * Cherche un point où la densité est faible dans la zone donnée.
   */
Feu's avatar
Feu committed
706 707 708 709 710
  function find_low_density_point ( $x, $y, $s, $except=null )
  {
    $ld = null;
    $lx = null;
    $ly = null;
711

Feu's avatar
Feu committed
712 713
    $cx = $x;
    $cy = $y;
714

Feu's avatar
Feu committed
715 716 717 718
    for($cx=$x;$cx<$x+$s;$cx+=$s/3)
    {
      for($cy=$y;$cy<$y+$s;$cy+=$s/3)
      {
Feu's avatar
Feu committed
719
        $d = $this->get_density($cx,$cy,$cx+($s/3),$cy+($s/3), $except);
Feu's avatar
Feu committed
720
        if ( $d == 0 )
721 722
          return array($cx+($s/6),$cy+($s/6));

Feu's avatar
Feu committed
723 724
        if ( is_null($ld) || $ld > $d )
        {
725
          $lx = $cx;
Feu's avatar
Feu committed
726 727 728 729 730
          $ly = $cy;
          $ld = $d;
        }
      }
    }
731

Feu's avatar
Feu committed
732
    if ( $s < 0.001 )
733 734
      return array($lx+($s/6),$ly+($s/6));

Feu's avatar
Feu committed
735 736
    return $this->find_low_density_point($lx,$ly,$s/3, $except);
  }
737

Feu's avatar
Feu committed
738 739 740 741 742
  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();
  }
743

Feu's avatar
Feu committed
744 745 746 747 748
}




BenC's avatar
BenC committed
749
?>