web-dev-qa-db-fra.com

Montrer l'intersection de deux courbes

Si j'ai deux parcelles définies par deux équations différentes:

x = 0:0.01:30;
y1 = x .^2 + 2;
y2 = x .^3 ;

et je les trace comme 

plot(x, y1, x, y2);

Comment obtenir un petit anneau autour du point d'intersection par programmation (comme dans le graphique suivant)?

enter image description here

8
user2329401

Vous devrez trouver le point d'intersection (px, py) manuellement:

idx = find(y1 - y2 < eps, 1); %// Index of coordinate in array
px = x(idx);
py = y1(idx);

Rappelez-vous que nous comparons deux nombres dans une représentation en virgule flottante, donc, au lieu de y1 == y2, nous devons définir une tolérance. Je l'ai choisi comme eps, mais c'est à vous de décider.

Pour tracer un cercle autour de ce point, vous pouvez calculer ses points, puis les représenter, mais une meilleure approche consisterait à tracer un point avec un marqueur de cercle agrandi (crédit de Jonas pour cette suggestion):

plot(px, py, 'ro', 'MarkerSize', 18)

De cette façon, les dimensions du cercle ne sont pas affectées par les axes et le rapport de format du tracé.

Exemple

x = 0:0.01:30;
y1 = x .^ 2 + 2;
y2 = x .^ 3;

%// Find point of intersection
idx = find(y1 - y2 < eps, 1);
px = x(idx);
py = y1(idx);

figure
plot(x, y1, x, y2, px, py, 'ro', 'MarkerSize', 18)
axis([0 10 0 10])

Cela devrait produire l'intrigue suivante: result

11
Eitan T

Dans votre exemple, lorsque vous avez x, y1 et y2 Ce que vous pouvez faire est

idx = find(abs(y1 - y2) == min(abs(y1 - y2)));
xInter = x(idx)
yInter = y1(idx) % or y2(idx)

Si vous avez x1, y1 et x2, y2, où x1 ~ = x2vous pouvez d’abord effectuer une interpolation 1D en utilisant

yy2 = interp1(x2, y2, x1);

puis appliquer

idx = find(abs(y1 - yy2) == min(abs(y1 - yy2)));
xInter = x1(idx)
yInter = y1(idx) % or yy2(idx)
2
nkukarl

Excellent article de @EitanT, mais j'aimerais compléter ceci par une autre façon (automatisée) de trouver l'intersection (en supposant qu'il en existe un et que les graphiques se comportent bien).

Voici notre point de départ:

x = 0:0.01:30;
y1 = x .^2 + 2;
y2 = x .^3 ;

Tout d'abord, nous vérifions si ces valeurs sont exactement égales. Pour des situations non discrètes à virgule flottante, cela devrait être suffisant:

idx = find(y1==y2)

Si elles ne sont jamais enregistrées comme étant exactement égales, une intersection se produit si l’une surpasse l’autre, nous examinons donc la différence:

if isempty(idx)
  d = y1-y2;
  % At the moment of crossing, the sign will change:
  s = diff(sign(d));
  % Now just find the point where it changes
  f = find(s,1);
end

Pour résumer cela sous forme compacte sans variables supplémentaires, je vous recommande d'utiliser:

idx = find(y1==y2)
if isempty(idx)
idx = find(diff(sign(y1-y2)),1)
end
1
Dennis Jaheruddin

En particulier lorsque vous connaissez les fonctions, vous pouvez utiliser la boîte à outils mathématiques symboliques.

y1 = x .^2 + 2;
y2 = x .^3 ;
syms x real
intersection=simplify(solve(y1==y2))

Utilisez vpa(intersection) pour le convertir en nombre ou double(intersection) pour le convertir en valeur à virgule flottante.

1
Daniel

Dernier point mais non le moindre, le moyen le plus propre de procéder est la commande polyxpoly :

[xi,yi] = polyxpoly(x,y1,x,y2)

xi = 1.69560153754948
yi = 4.87508921229275

Bonne chance!

0
Oliver Amundsen