//---------------------------------------------------------------------------
/* Program przecpros.cpp - przeciecie prostych
Dane: P1(x1,y1), P2(x2,y2); P3(x3,y3), P4(x4,y4);
Obliczyc wspolrzedne punktu przeciecia P(xp, yp);
Obliczenia wykonuje program 2-ma metodami:
z rozwi¹zania uk³adu 2  rownañ
w postaci kierunkowej: y=m1*x+b1; y=m2*x+b2;
oraz w postaci ogólnej: A1*x+B1*y+C1=0; A2*x+B2*y+C2=0;
*/
// Biblioteki
#include <iostream>
#include <stdio.h>
#include <cstdlib>
#include <string>
// Definicja 
#define MIN 0.00000001

using namespace std;

// Funckje - deklaracje
double mm(double x1, double y1, double x2, double y2); // wspolczynnik m rown. kierunk.
double b(double x, double y, double m); // wspolczynnik b rownania kierunkowego
// przeciecie prostych w postaci kierunkowej
void przec1(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double &xp, double &yp);
// przeciecie prostych w postaci ogolnej
void przec2(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double &xpp, double &ypp);

/* == Funkcja g³ówna =================================== */
int main(int argc, char **argv)
{
    long n1, n2, n3, n4, np; // numery punktów
    double x1, y1, x2, y2; // wspolrz. prostej P1-P2
    double x3, y3, x4, y4; // wspolrz. prostej P3-P4
    double  xp, yp;  // wspolrz. punktu wyznaczanego P z rownan kierunkowych
    double m1, m2, dm; // wsplolczynniki m i mianownik do obliczen
    double b1, b2; // wsplolczynniki  b
    double A1, A2, B1, B2, C1, C2; // wspolcz. rownania ogolnego
    double xpp, ypp; // wspolrz. punktu wyznaczanego P z rownan ogolnych
     
    // naglowek  
    cout << "Program przecpros.cpp " << endl;
    cout << "\nPrzeciecie 2 prostych " << endl;
    cout << "z których kazda wyznaczona jest przez 2 punkty\n" << endl;
    cout << "               o P1(x1,y1)" << endl;
    cout << "               | " << endl;
    cout << " P3(x3,y3) o---* P --------o P4(x4,y4)" << endl;
    cout << "               |" << endl;
    cout << "               o P2(x2,y2)" << endl << endl;
    cout << "Przeciecie obliczane 2 metodami: \n";
    cout << "Przeciecie prostych w postaci kierunkowej: y=m*x+b\n";
    cout << "Przeciecie prostych w postaci ogolnej: A*x+B*y+C=0\n" << endl;
    
    // wprowadzenie danych
    cout << "\nWprowadz kolejne dane oddzielone spacja: Nr (calkowity) X  Y " << endl;
    cout << "\nProsta P1-P2" << endl;
    cout << "1) Wprowadz: Nr punktu P1   X1   Y1:  ";
    cin >> n1 >>  x1 >> y1; // dane punktu P1 
    cout << "2) Wprowadz: Nr punktu P2   X2   Y2:  ";
    cin >> n2 >>  x2 >> y2; // dane punktu P1 
    
	cout << "\nProsta P3-P4" <<endl;
    
	cout << "3) Wprowadz Nr punktu P3 (0 - koniec) =>  ";
    cin >> n3; // numer punktu P3
    
	while (n3 != 0) // dopoki nrP3  rozny od zera
    { // poczatek petli while
           cout << "\nWprowadz: X3  Y3:  ";
           cin >>  x3 >> y3;
           cout << "4) Wprowadz  Nr punktu P4  X4   Y4:  ";
           cin >> n4 >>  x4 >> y4;
           cout << "\nWprowadz Nr punktu przeciecia P: ";
           cin >> np;
           cout << endl;
           // przeciecie prostych w postaci kierunkowej
           przec1(x1, y1, x2, y2, x3, y3, x4, y4, xp, yp);
           // przeciecie prostych w postaci ogolnej
           przec2(x1, y1, x2, y2, x3, y3, x4, y4, xpp, ypp);

           cout << "\nPrzeciecie prostych " << n1 << "-" << n2 << "  i  ";
           cout << n3 << "-" << n4 << endl;
           cout << "Punkt przeciecia " << np << endl;
           cout << "xp  = " << xp  <<  "  yp  = " << yp << endl;
           cout << "xpp = " << xpp <<  "  ypp = " << ypp << endl;
           cout << "\nProsta P3-P4" <<endl;
           cout << "Wprowadz Nr punktu P3 (0 - koniec) =>  ";
           cin >> n3;
    } // koniec petli while 

 cin.get(); // czka na klawisz Enter
 return 0;
} // koniec main()
/* ==  Koniec funkcji g³ównej =================================== */


//---------------------------------------------------------------------------

// Definicje funkcji 

// wspolczynnik m
double mm(double x1, double y1, double x2, double y2)
{
  double dx;
  dx=x2-x1;
  if (dx==0) dx=MIN;
  return (y2-y1)/dx;
}


// wspolczynnik b
double b(double x, double y, double m)
{
return -m*x+y;

}


// przeciecie prostych w postaci kierunkowej - obl. xp, yp przez referencje
void przec1(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double &xp, double &yp)
{
    double m1, m2, b1, b2, dm;
    m1=mm(x1, y1, x2, y2);
    m2=mm(x3, y3, x4, y4);
   // cout << "\n======Funkcja przec1 ==== " << endl;
   // cout << "\nm1=" << m1 << "  m2=" << m2 << endl;
    m1=(y2-y1)/(x2-x1);
    m2=(y4-y3)/(x4-x3);
   // cout << "\nm1=" << m1 << "  m2=" << m2 << endl;
    b1=b(x1, y1, m1);
    b2=b(x3, y3, m2);
    dm = m2-m1;
    cout << "m2-m1=" << dm << endl;
    if (dm == 0) dm=MIN;
   // cout << "m2-m1=" << dm << endl;
    xp = (b1-b2)/dm;
    yp=(b1*m2-b2*m1)/dm;
   // cout << "Funkcja przec1: ";
   // cout << "  xp="<<xp << "  yp=" <<yp << endl;
}

// przeciecie prostych w postaci ogolnej -obl. xpp, ypp  przez referencje
void przec2(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double &xpp, double &ypp)
{
    double A1, B1, A2, B2, C1, C2, mian;
    A1=-(y2-y1);
    B1= x2-x1;
    A2=-(y4-y3);
    B2= x4-x3;
    C1 = -A1*x1-B1*y1;
    C2 = -A2*x3-B2*y3;
     mian = A1*B2-A2*B1;
    if (mian==0) mian=MIN;
    xpp=(B1*C2-B2*C1)/mian;
    ypp=(A2*C1-A1*C2)/mian;
}