11-02-2010, 11:39 PM
Salut, je te propose un calcul avec moins de conditions (pas de repérage de "coin"). Si tu veux des explications, n'hésite pas (à copier-coller dans un fichier pour le test).
Code PHP :
<?php
function getNeighbours($n, $c) {
$return = array();
if($n == 0) { // Si le centre
for($i = 0; $i < 4; $i++) {
$return[] = array(1, $i);
}
} else {
if($c%$n == 0) { // Si sur un axe
$return[] = validIndex($n + 1, $c + floor($c / $n) - 1);
} else {
$return[] = validIndex($n - 1, $c - floor($c / $n) - 1 );
}
$return[] = validIndex($n - 1, $c - floor($c / $n));
$return[] = validIndex($n, $c - 1);
$return[] = validIndex($n, $c + 1);
$return[] = validIndex($n + 1, $c - floor($c / $n));
$return[] = validIndex($n + 1, $c - floor($c / $n) + 1);
}
usort($return, '_sort1');
return $return;
}
// Première fonction de tri (du plus petit cercle au plus grand)
function _sort1($a,$b) {
if ($a[0] == $b[0])
return _sort2($a,$b);
return ($a[0] < $b[0]) ? -1 : 1;
}
// Deuxième fonction de tri (si égalité, du plus petit index au plus grand)
function _sort2($a,$b) {
if ($a[1] == $b[1])
return 0;
return ($a[1] < $b[1]) ? -1 : 1;
}
// Vérifie que l'index calculé ne soit pas trop grand ou trop petit
function validIndex($n, $c) {
if($c < 0) $c = $n * 4 - 1;
if($c >= $n * 4) $c = 0;
return array($n, $c);
}
//On définit le maillage de sphères
$spheres = array();
$spheres[] = array(0,0);
for($i = 1; $i < 4; $i++) {
for($j = 0; $j < 4 * $i; $j++) {
$spheres[] = array($i, $j);
}
}
//On affiche les résultats
foreach($spheres as $sphere) {
$neighbours = getNeighbours($sphere[0],$sphere[1]);
echo "Sphère ", $sphere[0], "-", $sphere[1], " : ";
foreach($neighbours as $elem) {
echo "", $elem[0], "-", $elem[1], " | ";
}
echo "<br />";
}
?>
Par contre, il faut juste limiter les voisins pour le dernier cercle : je n'ai pas mis de limites au maillage.
@+