2010-03-14 4 views
3

question simple ici. Disons que j'ai deux points:PHP Find Coordonnées entre deux points

point 1 

x = 0 
y = 0 


point 2 

x = 10 
y = 10 

Comment puis-je trouver toutes les coordonnées inbetween que par programmation, en supposant qu'il existe une ligne droite entre deux points ... donc l'exemple ci-dessus renverrait:

0,0 
1,1 
2,2 
3,3 
... 
8,8 
9,9 
10,10 
Merci :)

+0

Pour ne pas pinailler mais il y a un nombre infini de points entre deux points sur un plan.Si vous voulez dire des points intégraux, c'est différent, mais votre pas minimum dictera combien de points maximum il y a. – GrayWizardx

+0

Je vous suggère d'utiliser un meilleur exemple, car cela rend l'équation de ligne y = x ce qui n'est pas le cas habituel. –

Répondre

3

merci pour toute votre aide, mais non des réponses postées travaillé comment je le voulais. Par exemple, disons que mes points étaient:

0, 0

0, 10

Il n'y aurait qu'un début et une finition de coordonnées ... elle ne tenait pas à trouver les inbetween.

Peut-être que je l'ai fait quelque chose de mal: S, mais je suis venu avec ma propre solution:

// Points 
$p1 = array(
    'x' => 50, 
    'y' => 50 
); 

$p2 = array(
    'x' => 234, 
    'y' => 177 
); 

// Work out distances 
$pxd = $p2['x'] - $p1['x']; 
$pyd = $p2['y'] - $p1['y']; 

// Find out steps 
$steps = max($p1['x'], $p1['y'], $p2['x'], $p2['y']); 

$coords = array(); 

for ($i = 0; $i < $steps; ++ $i) { 
    $coords[] = array(
     'x' => round($p1['x'] += $pxd/$steps), 
     'y' => round($p1['y'] += $pyd/$steps) 
    ); 
} 

print_r($coords); 
+0

Vous avez trouvé l'une des deux exceptions où la solution y = a + bx ne fonctionne pas. La raison en est que la pente b serait infinie (car la division par 0 n'est pas définie et x1 - x2 est 0). Votre solution présente toutefois des inconvénients: vous calculez uniquement des valeurs discrètes pour le quadrant supérieur droit (positif x et y). Et les pas sont arbitrairement définis par la plus grande coordonnée: take (20,0) et (21,1): il y aura 21 pas, tandis que (0,5) et (1,3) ne donneront que 3 pas. Essayez d'utiliser $ steps = max ($ pdx, $ pdy) à la place. –

+0

La modification de $ steps fonctionne de manière incohérente. Branchez 3,3 et 0,5 et le code renvoie seulement deux points: 2,4 et 0,5. Il manque un point intervenant le long de x = 1 avec soit y = 4 ou y = 5, ce qui serait acceptable j'imagine. –

2

Vous devez trouver la pente de la première ligne:

m = (y1 - y2)/(x1 - x2) 

Ensuite, vous devez trouver l'équation de la ligne:

y = mx + b 

Dans votre exemple, vous nous obtenons:

y = 1x + b 
0 = 1(0) + b 

ou

y = x 

Pour obtenir toutes les coordonnées dont vous avez besoin tout simplement Brancher toutes les valeurs x1 -> x2. En PHP toute cette chose ressemble à:

// These are in the form array(x_cord, y_cord) 
$pt1 = array(0, 0); 
$pt2 = array(10, 10); 
$m = ($pt1[1] - $pt2[1])/($pt1[0] - $pt2[0]); 
$b = $pt1[1] - $m * $pt1[0]; 

for ($i = $pt1[0]; $i <= $pt2[0]; $i++) 
    $points[] = array($i, $m * $i + $b); 

Ce sera bien sûr vous donner les coordonnées de tous les points qui tombent sur des valeurs entières de X, et non pas « toutes les coordonnées » entre les deux points.

+1

+1, Votre code semble faire exactement ce que je voulais faire mon code à l'origine, c'est plus propre et ressemble plus à une solution solide. –

+0

vous m'avez battu. de toute façon je laisse mon algo pour ceux qui le veulent. –

+0

Le test d'une ligne verticale est laissé comme un exercice pour l'utilisateur. – jasonbar

1
  1. utiliser l'équation de la ligne, y = mx + c
  2. Put (0,0) et et (10,10) pour obtenir deux équations et résoudre pour obtenir les valeurs de m et c. (vous serez en mesure de trouver les équations directes pour obtenir m et c quelque part).
  3. Ensuite, créez une boucle à partir de x = x1 (0) jusqu'à x = x2 (10)
  4. aide y = mx + c, obtenir la valeur de y (maintenant que vous connaissez m et c)
0

pour générer tous les points de réseau (points de coordonnées intégrales) sur le segment entre (x1, y1) et (x2, y2), où x1, x2, y1 et y2 sont des nombres entiers:

function gcd($a,$b) { 
    // implement the Euclidean algorithm for finding the greatest common divisor of two integers, always returning a non-negative value 
    $a = abs($a); 
    $b = abs($b); 
    if ($a == 0) { 
     return $b; 
    } else if ($b == 0) { 
     return $a; 
    } else { 
     return gcd(min($a,$b),max($a,$b) % min($a,$b)); 
    } 
} 

function lattice_points($x1, $y1, $x2, $y2) { 
    $delta_x = $x2 - $x1; 
    $delta_y = $y2 - $y1; 
    $steps = gcd($delta_x, $delta_y); 
    $points = array(); 
    for ($i = 0; $i <= $steps; $i++) { 
     $x = $x1 + $i * $delta_x/$steps; 
     $y = $y1 + $i * $delta_y/$steps; 
     $points[] = "({$x},{$y})"; 
    } 
    return $points; 
} 
+0

Ne semble pas fonctionner de manière cohérente. Donné (3,3,0,5) il ne renvoie que 3,3 et 0,5 mais aucun des points intermédiaires. Fonctionne correctement avec (3,3,0,6) qui est une parfaite "ligne de 45 degrés" mais ne fonctionne pas bien le long d'autres pentes. –

+0

@DonJones: Il n'y a pas de points de réseau - c'est-à-dire des points pour lesquels les deux coordonnées sont des entiers - sur le segment de droite entre (3,3) et (0,5). – Isaac

1

serait, trouver le milieu en faisant la moyenne des coordonnées, répéter jusqu'à ce que vous avez terminé un algorithme plus simple. Je voulais juste souligner parce que personne ne l'a fait.

Questions connexes