👤
Krina89
a fost răspuns

Se dau două segmente în plan, specificate prin coordonatele capetelor. Să se verifice dacă au cel puțin un punct comun.
Date de intrare

Fișierul de intrare intersectiesegmente.in conține pe prima linie 8 numere naturale separate prin spații, respectiv: X1, Y1, X2, Y2, X3, Y3, X4, Y4. Primul segment are capetele (X1, Y1) și (X2, Y2).
Date de ieșire

Fișierul de ieșire intersectiesegmente.out va conține pe prima linie DA (când segmentele se intersectează) sau NU (în caz contrar).
Restricții și precizări

Numerele din fișierul de intrare sunt întregi cuprinse între -1001 și 1001.
Ambele segmente au lungimea nenulă.


Exemplu

intersectiesegmente.in

-1 -1 1 1 -1 1 1 -1

intersectiesegmente.out

DA


Nu prea imi iesa pb de geometrie,pe foaie e mai usor decat pe calculator:)


Răspuns :

Ai o grămadă de modalități :))
Trebuie doar să creezi o formulă matematică pe care apoi să o transcrii în limbaj.

O idee de calcul:

Pentru ca 2 drepte să nu se intersecteze, ele trebuie să fie paralele, adică să aibă aceeași pantă, dar să nu coincidă.
Prima etapă de verificare e simplă, aplici formula de calcul a pantei și afli cele 2 pante:
m1 = (Y2-Y1)/(X2-X1);
m2 = (Y4-Y3)/(X4-X3);

Ca să fie paralele, trebuie să fie diferite. Deci prima e pur și simplu if(m1!=m2).

Ok, acum avem a 2-a parte: de verificat ca nu cumva, chiar dacă au aceeași pantă, să nu fie chiar aceeași dreaptă, că astfel ar avea toate punctele intersectate.
De ce este necesară această verificare? Pentru că, dacă de exemplu am avea 2 puncte de la d1: (1, 1), (2, 2) și alte 2 de la d2: (3, 3) și (4, 4), ele ar avea panta egală și ar fi paralele, doar că dacă le-am desena pe un grafic, cele 2 drepte ar coincide, și astfel, chiar dacă formula anterioară ar răspunde negativ la intersecție, ele ar putea coincide și s-ar intersecta într-un infinit de puncte.

Acum să încercăm să găsim o modalitate:
Aici am putea, de exemplu să folosim formula determinantului și să vedem dacă P1(X1, Y1), P2 și P3 sunt coliniare && dacă P1, P2 și P4 sunt coliniare. Dacă sunt, dreapta coincide, dacă nu sunt coliniare, atunci sigur nu coincid dreptele.
O altă cale, mai simplă de a verifica această a 2-a parte, ar fi folosind următoarele ipoteze:

a) O dreaptă este, de fapt, graficul unei funcții simple (f(x) = ax+b), deci ecuația diferența dintre ecuația unei drepte și o funcție este că funcția doar are f(x) în loc de y și îl are pus în stânga, și restul tot în dreapta

b) Într-o astfel de funcție simplă, f(x) = ax+b
  * a-ul este panta (cea pe care am folosit-o mai înainte). Panta/Direcția graficului unei funcții este definită doar de acest a. Poți încerca să faci niște funcții și o să vezi că oricât ar fi b, unghiul/panta/direcția este aceeași dacă a este același la funcțiile pe care încerci să le desenezi.
  * b-ul este distanța pe Oy de la O până la grafic. Practic: cât e de la centru (O), mergând în sus/jos pe Oy, până la graficul funcției. Deci practic, dacă a-ul definea unghiul, b-ul definește depărtarea de Ox.

Ok, și funcția este definită de acești 2 parametri. Dacă coincid, și graficele coincid, dacă sunt diferite și dreptele celor 2 funcții sunt diferite.

Bun, noi la prima parte am verificat dacă panta este aceeași, adică dacă a-ul este același la cele 2 funcții. Iar ca să verificăm și a doua parte, trebuie să vedem dacă b-ul coincide. :)) Cum aflăm b-ul? Asta e simplu:
Avem formula dreptei, pentru panta m și A(x0, y0):
(y-y0) = m*(x-x0)
y - y0 = mx - mx0
y = m * x - m * x0
      |        \______/ -- ăsta e b-ul
      ^ -- ăsta e a-ul
deci b-ul este m*x0.

În cazul nostru, pentru prima dreaptă:
b1 = m1 * X1 (sau X2, nu contează care din puncte, pentru că folosim panta)
b2 = m2 * X3 (sau X4, dat tot aia e)

și aici avem
if(b1 == b2) și condiția de la prima parte este falsă (sunt paralele)
  atunci coincid
altfel
  nu coincid, sunt paralele, nu se intersectează..


Deci, într-un final, programul ar fi astfel:

cin>>x1>>y1>>x2>>y2>>x3>>y3>>x4>>y4;

m1 = (y2-y1)/(x2-x1);
m2 = (y4-y3)/(x4-x3);

b1 = m1 * x1
b2 = m2 * x3

if(m1 == m2 && b1 != b2){
    // dacă pantele sunt egale(sunt paralele), și dreptele nu coincid
    // înseamnă că nu se intersectează niciodată
    cout<<"NU";
}else{
     // dacă nu sunt paralele, (sau eventual, dacă sunt paralele, dar coincid)
     // înseamnă că se intersectează
     cout<<"DA";
}