Intersection dans le plan entre un cercle et un segment
Sommaire |
[modifier] Langage mathématique
[modifier] Hypothèses
Soit deux points
et
deux points du segment
.
Soit un cercle de centre
, et de rayon ρ.
[modifier] Solution
Posons :
Si Δ < 0, le segment ne coupe pas le cercle.
Dans le cas contraire, c'est-à-dire
, il faut faire un second test :
le segment coupe le cercle.
[modifier] Implémentation informatique
[modifier] Pseudo-code
![]()
![]()
SI
ALORS
SI
ET
ALORS RETOURNE Intersection SINON RETOURNE Pas d'intersection FIN SI SINON RETOURNE Pas d'intersection FIN SI
[modifier] Implémentation en C
((C_x - A_x)*(B_x - A_x) + (C_y - A_y)*(B_y - A_y))/((B_x - A_x)*(B_x - A_x) + (B_y - A_y)*(B_y - A_y))
// La fonction renvoie une valeur non nulle en cas d'intersection
int IntersectionPlanCercleSegmentfloat A[2], float B[2], float C[2], float Rayon)
{
float Alpha, Beta, Gamma, Delta;
Alpha = (B[0] - A[0]) * (B[0] - A[0]) + (B[1] - A[1]) * (B[1] - A[1]);
Beta = 2 * ((B[0] - A[0]) * (A[0] - C[0]) + (B[1] - A[1]) * (A[1] - C[1]));
Gamma = A[0] * A[0] + A[1] * A[1] + C[0] * C[0] + C[1] * C[1] - 2 * (A[0] * C[0] + A[1] * C[1]) - Rayon * Rayon;
if((Beta * Beta - 4 * Alpha * Gamma) >= 0)
{
float u;
u = ((C[0] - A[0]) * (B[0] - A[0]) + (C[1] - A[1]) * (B[1] - A[1])) / ((B[0] - A[0]) * (B[0] - A[0]) + (B[1] - A[1]) * (B[1] - A[1]))
return 0.0f <= u && u <= 1.0f;
} else {
return 0;
}
}
[modifier] Démonstration
Le problème est très proche de celui de l'intersection dans le plan entre un cercle et une droite. En effet, si la droite n'a pas de point d'intersection avec le cercle, le segment non plus. C'est donc notre premier test : est-ce que la droite
appartient au cercle ?
Si c'est le cas, ne crions pas tout de suite CQFD : il reste à savoir si le segment
a un point d'intersection avec le cercle. Pour ce faire, il est possible de revenir à la fin de la démonstration de l'intersection dans le plan entre un cercle et une droite, afin de calculer u et de vérifier que
. Cependant, l'utilisation de la racine carré dans la résolution de u peut rapidement nuir aux performances de votre application ! Cherchons donc une autre solution, même si moins évidente, certes ...
La solution est le produit scalaire. Suivez bien : si nous appelons le point
le point le plus proche du cercle, il vérifie donc
. Faisons maintenant l'hypothèse que
a un point de concours avec le cercle, dans ce cas
a un point d'intersection avec le cercle.
Donc trouvons un point M qui vérifie l'équation
. Si on pose
, cela revient à trouver u tel que
.
On écrit le produit scalaire sous forme algébrique, et on isole u, pour trouver
. Et, comme dit précédemment,
Le segment a un point d'intersection au cercle.
Maintenant on peut crier CQFD :).
SI
ALORS
SI
ET
ALORS
RETOURNE Intersection
SINON
RETOURNE Pas d'intersection
FIN SI
SINON
RETOURNE Pas d'intersection
FIN SI

