/*
 Samotny vypocet metody Octant
 */
package octantKlient;

//import java.util.ArrayList;
//import java.util.Collections;
//import java.util.Comparator;
import java.util.*;

/**
 *
 * @author FilipDvorak
 */
public class Vypocet {

    //funkce najdiPolohu
    public static Kruznice najdiPolohu(ArrayList<Kruznice> kruzniceNeserazene) {
        Kruznice kruzniceNalezenaPoloha = null;

        //pole je typu Kruznice a budou do ni ulozeny serazené kružnice podle velikosti jejich mezikruží 
        //čím je velikost mezikruží větší - tím je vzdálenost orientačního bodu vetší a důvěryhodnost měnší
        ArrayList<Kruznice> serazeneKruznicePodleMezikruzi = new ArrayList<Kruznice>(kruzniceNeserazene);

        //Porovnani hodnot v poli - serazeneKruznicePodleMezikruzi (typ Kruznice) 
        //Hodnoty jsou razeny od nejvetsi po nejmensi podle podminky zadane v tride - Porovnavace
        Collections.sort(serazeneKruznicePodleMezikruzi, Porovnavace.podleMezikruzi());

        //kruznice s největším mezikružím se uloží do proměnné kruzniceSnejvetsimMezikruzim a smaže se z pole 
        //serazeneKruznicePodleMezikruzi
        Kruznice kruzniceSnejvetsimMezikruzim = new Kruznice(serazeneKruznicePodleMezikruzi.get(0));
        serazeneKruznicePodleMezikruzi.remove(0);

        //vytovri se pole, do kterého se budou ukládat kruznice N (vytvorené z průniku kruznic z pole serazeneKruznicePodleMezikruzi)
        ArrayList<Kruznice> poleKruznicN = new ArrayList<Kruznice>(2);


        //cyklus for slouzi na vyhledani pruniku dvou kruznic s nejvetším mezikružím
        for (int i = 0; i < serazeneKruznicePodleMezikruzi.size(); i++) {
            Kruznice kruzniceA = kruzniceSnejvetsimMezikruzim;
            // do proměnné kruzniceB se vždy zapíše první hodnota z dynamického pole serazeneKruznicePodleMezikruzi
            //- vzdy tedy nejvetsi kruznice
            Kruznice kruzniceB = serazeneKruznicePodleMezikruzi.get(0);

            //vypočte vzdálenost dvou středů kružnic - slouží pro porovnání zda a kolik průsečíku kružnice mají 
            //(viz dále v podmínce if ...)
            Double d = vypoctiD(kruzniceA, kruzniceB);

            //pocet pruseciku 2,4,8,0
            if (d < (kruzniceA.getPolomerPozitivni() + kruzniceB.getPolomerPozitivni()) && d > (kruzniceA.getPolomerNegativni() + kruzniceB.getPolomerNegativni()) && d > (kruzniceA.getPolomerPozitivni() + kruzniceB.getPolomerNegativni()) && d > (kruzniceA.getPolomerNegativni() + kruzniceB.getPolomerPozitivni())) {
                // plati to pro 2 pruseciku a metoda najdiKruzniciNze2Pruseciku vraci kruzniciN
                Kruznice kruzniceNzPozitivnichKruznic = najdiKruzniciNze2Pruseciku(kruzniceA, kruzniceB, d);
                //výslednou kružniciN uloží do poleKružnicN
                poleKruznicN.add(kruzniceNzPozitivnichKruznic);
                break;
                
            } else if (d < (kruzniceA.getPolomerPozitivni() + kruzniceB.getPolomerPozitivni()) && d > (kruzniceA.getPolomerNegativni() + kruzniceB.getPolomerNegativni()) && (d < (kruzniceA.getPolomerPozitivni() + kruzniceB.getPolomerNegativni()) || d < (kruzniceA.getPolomerNegativni() + kruzniceB.getPolomerPozitivni()))) {
                //plati pro 4 pruseciky
                Kruznice kruzniceNze4Pruseciku = najdikruzniciNze4Pruseciku(kruzniceA, kruzniceB, d);
                poleKruznicN.add(kruzniceNze4Pruseciku);
                break;
            } else if (d < (kruzniceA.getPolomerPozitivni() + kruzniceB.getPolomerPozitivni()) && d < (kruzniceA.getPolomerNegativni() + kruzniceB.getPolomerNegativni())) {
                //plati pro 8 pruseciku
                poleKruznicN = najdiKruzniceNz8Pruseciku(kruzniceA, kruzniceB, d);
                break;
                
            } else {
                // pokud nebude žádný průsečík
                // tak se smaže prvni kružnice z pole Array<Kruznice>serazeneKruznicePodleMezikruzi
                serazeneKruznicePodleMezikruzi.remove(kruzniceB);
                //skoči zpátky na další iteraci cyklu for 
                continue;
            }
        }
        // vymaže se největsi kružnice z pole serazeneKruznice, které jsou již protnuté, ta druha kružnice je uložena v kruzniciA
        serazeneKruznicePodleMezikruzi.remove(0);

        //následující podmínka pracuje počtem kružnicN - 1 nebo 2
        //provede if jestli bude jen jedna kruzniceN
        if (poleKruznicN.size() == 1) {
            Kruznice kruzniceN = poleKruznicN.get(0);
            //když nebude žádný průsečík s kružnicíN a tou nejvetsi z pole - pozice 0 -
            //tak se smaže ta kružnice z pozice 0 a pokračuje se dál v předchozím cyklu for
            // cyklus while bude ptobíhat dokud bude v poli serazeneKruznicePodleMezikruzi nějaka hodnota 
            while (!serazeneKruznicePodleMezikruzi.isEmpty()) {
                //bude hledat průsečiky kruznceN s tou největší v poli serazenekruznicePodleMezikruzi

                Kruznice aktualniKruznice = serazeneKruznicePodleMezikruzi.get(0);
                //vypořte vzdálenost mezi středem kružnice N a aktuální (pozice 0) v poli serazeneKruznicePodleMezikruzi
                Double d = vypoctiDskruzniciN(kruzniceN, aktualniKruznice);

                //podmínky dále ošetřují jak se kružnice budou protínat
                if (d < (kruzniceN.getPolomerKruzniceN() + aktualniKruznice.getPolomerPozitivni()) && d > (kruzniceN.getPolomerKruzniceN() + aktualniKruznice.getPolomerNegativni())) {
                    // platí to pro 2 průsečíku
                    //fce najdiDalsiKruzniciNzPozitivni najde kruzniciN - protnuti kruzniceN s 
                    //tou nejvetsi z pole serazeneKruznicepoldeMezikruzi
                    kruzniceN = najdiDalsiKruzniciNzPozitivni(kruzniceN, aktualniKruznice, d);
                    serazeneKruznicePodleMezikruzi.remove(0);
                    //po smazání kružnice z pole serazeneKruznicePodleMezikruzi se přesune zase na začátek
                    continue;
                    
                } else if (d < (kruzniceN.getPolomerKruzniceN() + aktualniKruznice.getPolomerPozitivni()) && d < (kruzniceN.getPolomerKruzniceN() + aktualniKruznice.getPolomerNegativni())) {
                    //plati pro 4 pruseciky
                    kruzniceN = najdiDalsikruzniciNze4PrusecikuPozitivniInegativni(kruzniceN, aktualniKruznice, d);
                    serazeneKruznicePodleMezikruzi.remove(0);
                    continue;
                } else {
                    // pokud nebude zadny prusecik
                    // tak se smaže prvni kružnice z pole Array<Kruznice>serazeneKruznicePodleMezikruzi
                    serazeneKruznicePodleMezikruzi.remove(0);
                    //skoči zpátky na dalši iteraci cyklu for 
                    continue;
                }
                
                
                
            }
            //vrati kruznici jako pozici cílového bodu
            return kruzniceN;
        } else {
            //provede se pokud budou 2 kruznice
            //pole serazeneKruznicePodleMezikruzi2 je pouze pomocné pole
            ArrayList<Kruznice> serazeneKruznicePodleMezikruzi2 = new ArrayList<Kruznice>(serazeneKruznicePodleMezikruzi);
            Kruznice kruzniceN1 = new Kruznice(poleKruznicN.get(0));
            Kruznice kruzniceN2 = new Kruznice(poleKruznicN.get(1));

            // cyklus while pro kruzniciN1
            while (!serazeneKruznicePodleMezikruzi.isEmpty()) {
                //bude hledat průsečíky kruzniceN s tou největší v poli serazenekruznicePodleMezikruzi

                Kruznice aktualniKruznice = serazeneKruznicePodleMezikruzi.get(0);
                //fce vypocte vzdálenost středu kružnice N a té z pole serazeneKruznicePodleMezikruzi
                Double d = vypoctiDskruzniciN(kruzniceN1, aktualniKruznice);

                //podmínka porovná podle koeficientu d (vzdálenosti) počet průsečíků
                if (d < (kruzniceN1.getPolomerKruzniceN() + aktualniKruznice.getPolomerPozitivni()) && d > (kruzniceN1.getPolomerKruzniceN() + aktualniKruznice.getPolomerNegativni())) {
                    // plati pro 2 průsečíky a fce najde kruzniciN -
                    //průsečíky kruzniceN s tou největší z pole serazeneKruznicepoldeMezikruzi
                    kruzniceN1 = najdiDalsiKruzniciNzPozitivni(kruzniceN1, aktualniKruznice, d);
                    serazeneKruznicePodleMezikruzi.remove(0);
                    continue;
                    
                } else if (d < (kruzniceN1.getPolomerKruzniceN() + aktualniKruznice.getPolomerPozitivni()) && d < (kruzniceN1.getPolomerKruzniceN() + aktualniKruznice.getPolomerNegativni())) {
                    //plati pro 4 pruseciky
                    kruzniceN1 = najdiDalsikruzniciNze4PrusecikuPozitivniInegativni(kruzniceN1, aktualniKruznice, d);
                    serazeneKruznicePodleMezikruzi.remove(0);
                    continue;
                } else {
                    // pokud nebude žádný průsečík
                    // se smaže první kružnici z pole Array<Kruznice>serazeneKruznicePodleMezikruzi
                    serazeneKruznicePodleMezikruzi.remove(0);
                    kruzniceN1 = null;
                    //skočí zpátky na další iteraci cyklu for 
                    break;
                }
                
            }
            //while pro kruzniciN2 - hleda se pruseciky stejně jako předchozí cyklus while pro kruzniciN1

            while (!serazeneKruznicePodleMezikruzi2.isEmpty()) {
                //bude hledat průsečíky kruznceN s tou největší v poli serazenekruznicePodleMezikruzi

                Kruznice aktualniKruznice = serazeneKruznicePodleMezikruzi2.get(0);
                //fce vypocte vzdálenost středu kružnice N a té z pole serazeneKruznicePodleMezikruzi   
                Double d = vypoctiDskruzniciN(kruzniceN1, aktualniKruznice);
                
                
                if (d < (kruzniceN2.getPolomerKruzniceN() + aktualniKruznice.getPolomerPozitivni()) && d > (kruzniceN2.getPolomerKruzniceN() + aktualniKruznice.getPolomerNegativni())) {
                    // plati pro 2 průsečíky a fce najde kruzniciN 
                    //průsečíky kruzniceN s tou největší z pole serazeneKruznicepoldeMezikruzi
                    kruzniceN2 = najdiDalsiKruzniciNzPozitivni(kruzniceN2, aktualniKruznice, d);
                    serazeneKruznicePodleMezikruzi2.remove(0);
                    continue;
                    
                } else if (d < (kruzniceN2.getPolomerKruzniceN() + aktualniKruznice.getPolomerPozitivni()) && d < (kruzniceN2.getPolomerKruzniceN() + aktualniKruznice.getPolomerNegativni())) {
                    //plati pro 4 průsečíky
                    kruzniceN2 = najdiDalsikruzniciNze4PrusecikuPozitivniInegativni(kruzniceN2, aktualniKruznice, d);
                    serazeneKruznicePodleMezikruzi2.remove(0);
                    continue;
                } else {
                    // pokud nebude žádný průsečík
                    // tak se smaže první kružnice pole Array<Kruznice>serazeneKruznicePodleMezikruzi
                    serazeneKruznicePodleMezikruzi2.remove(0);
                    kruzniceN2 = null;
                    //skoci zpátky na dalsi iteraci cyklu for 
                    break;
                }
                
            }  //pokud bude jedna nebo nebude žádna kružnice N - cílová oblast - vypíše příslušné hodnoty 
            if (kruzniceN1 == null && kruzniceN2 == null) {
                Kruznice kruzniceN = new Kruznice(new Souradnice(0.0, 0.0), 0.0);
                return kruzniceN;
            } else if (kruzniceN1 != null && kruzniceN2 == null) {
                return kruzniceN1;
            } else if (kruzniceN1 == null && kruzniceN2 != null) {
                return kruzniceN2;
            } else {
                //vybere kruznici
                return kruzniceN1;
            }
            
            
        }


//        return kruzniceNalezenaPoloha;
    }
    
    private static Double vypoctiD(Kruznice kruzniceA, Kruznice kruzniceB) {
        Double xa = kruzniceA.getOrientacnibod().getSouradnice().getSouradniceX();
        Double ya = kruzniceA.getOrientacnibod().getSouradnice().getSouradniceY();
        Double xb = kruzniceB.getOrientacnibod().getSouradnice().getSouradniceX();
        Double yb = kruzniceB.getOrientacnibod().getSouradnice().getSouradniceY();
        
        Double d = Math.sqrt(Math.pow((xa - xb), 2.0) + Math.pow((ya - yb), 2.0));
        
        return d;
    }
    
    private static ArrayList<Prusecik> najdiOsmPruseciku(Kruznice kruzniceA, Kruznice kruzniceB, Double d) {
        ArrayList<Prusecik> osmPruseciku = null;
        
        Double m1 = vypoctiM(kruzniceA.getPolomerNegativni(), kruzniceB.getPolomerNegativni(), d);
        Double v1 = vypoctiV(kruzniceA.getPolomerNegativni(), m1);
        Double sx1 = vypoctiSx(kruzniceA.getOrientacnibod().getSouradnice().getSouradniceX(), m1, d, kruzniceB.getOrientacnibod().getSouradnice().getSouradniceX());
        Double sy1 = vypoctiSy(kruzniceA.getOrientacnibod().getSouradnice().getSouradniceY(), m1, d, kruzniceB.getOrientacnibod().getSouradnice().getSouradniceY());
        Double cx1 = vypocticx(sx1, v1, d, kruzniceA.getOrientacnibod().getSouradnice().getSouradniceY(), kruzniceB.getOrientacnibod().getSouradnice().getSouradniceY());
        Double cy1 = vypocticy(sy1, v1, d, kruzniceA.getOrientacnibod().getSouradnice().getSouradniceX(), kruzniceB.getOrientacnibod().getSouradnice().getSouradniceX());
        
        Double m2 = vypoctiM(kruzniceA.getPolomerPozitivni(), kruzniceB.getPolomerPozitivni(), d);
        Double v2 = vypoctiV(kruzniceA.getPolomerPozitivni(), m2);
        Double sx2 = vypoctiSx(kruzniceA.getOrientacnibod().getSouradnice().getSouradniceX(), m2, d, kruzniceB.getOrientacnibod().getSouradnice().getSouradniceX());
        Double sy2 = vypoctiSy(kruzniceA.getOrientacnibod().getSouradnice().getSouradniceY(), m2, d, kruzniceB.getOrientacnibod().getSouradnice().getSouradniceY());
        Double cx2 = vypocticx(sx2, v2, d, kruzniceA.getOrientacnibod().getSouradnice().getSouradniceY(), kruzniceB.getOrientacnibod().getSouradnice().getSouradniceY());
        Double cy2 = vypocticy(sy2, v2, d, kruzniceA.getOrientacnibod().getSouradnice().getSouradniceX(), kruzniceB.getOrientacnibod().getSouradnice().getSouradniceX());
        
        Double m3 = vypoctiM(kruzniceA.getPolomerPozitivni(), kruzniceB.getPolomerNegativni(), d);
        Double v3 = vypoctiV(kruzniceA.getPolomerPozitivni(), m3);
        Double sx3 = vypoctiSx(kruzniceA.getOrientacnibod().getSouradnice().getSouradniceX(), m3, d, kruzniceB.getOrientacnibod().getSouradnice().getSouradniceX());
        Double sy3 = vypoctiSy(kruzniceA.getOrientacnibod().getSouradnice().getSouradniceY(), m3, d, kruzniceB.getOrientacnibod().getSouradnice().getSouradniceY());
        Double cx3 = vypocticx(sx3, v3, d, kruzniceA.getOrientacnibod().getSouradnice().getSouradniceY(), kruzniceB.getOrientacnibod().getSouradnice().getSouradniceY());
        Double cy3 = vypocticy(sy3, v3, d, kruzniceA.getOrientacnibod().getSouradnice().getSouradniceX(), kruzniceB.getOrientacnibod().getSouradnice().getSouradniceX());
        
        Double m4 = vypoctiM(kruzniceA.getPolomerNegativni(), kruzniceB.getPolomerPozitivni(), d);
        Double v4 = vypoctiV(kruzniceA.getPolomerNegativni(), m4);
        Double sx4 = vypoctiSx(kruzniceA.getOrientacnibod().getSouradnice().getSouradniceX(), m4, d, kruzniceB.getOrientacnibod().getSouradnice().getSouradniceX());
        Double sy4 = vypoctiSy(kruzniceA.getOrientacnibod().getSouradnice().getSouradniceY(), m4, d, kruzniceB.getOrientacnibod().getSouradnice().getSouradniceY());
        Double cx4 = vypocticx(sx4, v4, d, kruzniceA.getOrientacnibod().getSouradnice().getSouradniceY(), kruzniceB.getOrientacnibod().getSouradnice().getSouradniceY());
        Double cy4 = vypocticy(sy4, v4, d, kruzniceA.getOrientacnibod().getSouradnice().getSouradniceX(), kruzniceB.getOrientacnibod().getSouradnice().getSouradniceX());
        
        return osmPruseciku;
    }
    
    private static Double vypoctiM(Double r1A, Double r1B, Double d) {
        Double m = (r1A * r1A - r1B * r1B) / (2 * d) + d / 2;
        return m;
    }
    
    private static Double vypoctiV(Double r, Double m) {
        Double v = Math.sqrt(r * r - m * m);
        return v;
    }
    
    private static Double vypoctiSx(Double Ax, Double m, Double d, Double Bx) {
        Double sx = Ax + (m / d) * (Bx - Ax);
        return sx;
    }
    
    private static Double vypoctiSy(Double Ay, Double m, Double d, Double By) {
        Double sy = Ay + (m / d) * (By - Ay);
        return sy;
    }
    
    private static Double vypocticx(Double sx, Double v, Double d, Double Ay, Double By) {
        Double cx = sx - (v / d) * (Ay - By);
        return cx;
    }
    
    private static Double vypocticy(Double sy, Double v, Double d, Double Ax, Double Bx) {
        Double cy = sy + (v / d) * (Ax - Bx);
        return cy;
    }

    // tato funkce se zavolá, když budeme mít 8 průsečíků -
    //pocitaji se jen středy mezikruží
    private static ArrayList<Kruznice> najdiKruzniceNz8Pruseciku(Kruznice kruzniceA, Kruznice kruzniceB, Double d) {
        //platí pro 8 průsečíků
        //získáme polomšry ve sředu mezikruží
        Double polomerStredniA = kruzniceA.getPolomerNegativni() + (kruzniceA.getPolomerPozitivni() - kruzniceA.getPolomerNegativni()) / 2;
        Double polomerStredniB = kruzniceB.getPolomerNegativni() + (kruzniceB.getPolomerPozitivni() - kruzniceB.getPolomerNegativni()) / 2;
        
        ArrayList<Kruznice> dveKruzniceN = new ArrayList<Kruznice>(2);
        
        Kruznice stredniKruzniceA = new Kruznice(kruzniceA.getOrientacnibod(), polomerStredniA);
        Kruznice stredniKruzniceB = new Kruznice(kruzniceB.getOrientacnibod(), polomerStredniB);

        //vypočet průsečíků
        Double m = vypoctiM(stredniKruzniceA.getPolomerStredni(), stredniKruzniceB.getPolomerStredni(), d);
        Double v = vypoctiV(stredniKruzniceA.getPolomerStredni(), m);
        Double sx = vypoctiSx(stredniKruzniceA.getOrientacnibod().getSouradnice().getSouradniceX(), m, d, stredniKruzniceB.getOrientacnibod().getSouradnice().getSouradniceX());
        Double sy = vypoctiSy(stredniKruzniceA.getOrientacnibod().getSouradnice().getSouradniceY(), m, d, stredniKruzniceB.getOrientacnibod().getSouradnice().getSouradniceY());
        Double cx1 = vypocticx(sx, v, d, stredniKruzniceA.getOrientacnibod().getSouradnice().getSouradniceY(), stredniKruzniceB.getOrientacnibod().getSouradnice().getSouradniceY());
        Double cy1 = vypocticy(sy, v, d, stredniKruzniceA.getOrientacnibod().getSouradnice().getSouradniceX(), stredniKruzniceB.getOrientacnibod().getSouradnice().getSouradniceX());
        Double cx2 = vypocticx2(sx, v, d, stredniKruzniceA.getOrientacnibod().getSouradnice().getSouradniceY(), stredniKruzniceB.getOrientacnibod().getSouradnice().getSouradniceY());
        Double cy2 = vypocticy2(sy, v, d, stredniKruzniceA.getOrientacnibod().getSouradnice().getSouradniceX(), stredniKruzniceB.getOrientacnibod().getSouradnice().getSouradniceX());

        //polměr kružnice N je rozdíl pozitivního a negativního poloměru
        Double delkaMezikruziA = (kruzniceA.getPolomerPozitivni() - kruzniceA.getPolomerNegativni());
        
        dveKruzniceN.add(new Kruznice(new Souradnice(cx1, cy1), delkaMezikruziA / 2));
        dveKruzniceN.add(new Kruznice(new Souradnice(cx2, cy2), delkaMezikruziA / 2));
        
        return dveKruzniceN;
    }
    
    private static Double vypocticx2(Double sx, Double v, Double d, Double Ay, Double By) {
        Double cx = sx + (v / d) * (Ay - By);
        return cx;
    }
    
    private static Double vypocticy2(Double sy, Double v, Double d, Double Ax, Double Bx) {
        Double cy = sy - (v / d) * (Ax - Bx);
        return cy;
    }
    
    private static Double najdiVzdalenostBodu(Souradnice bod1zPozitivnihoPolomeru, Souradnice bod3zPozitivnihoPolomeru) {
        Double vzdalenost = 0.0;
        Double xa = bod1zPozitivnihoPolomeru.getSouradniceX();
        Double xb = bod3zPozitivnihoPolomeru.getSouradniceX();
        Double ya = bod1zPozitivnihoPolomeru.getSouradniceY();
        Double yb = bod3zPozitivnihoPolomeru.getSouradniceY();
        
        vzdalenost = Math.sqrt(Math.pow((xa - xb), 2.0) + Math.pow((ya - yb), 2.0));
        
        
        return vzdalenost;
    }

    //zde se najde stred 4 průsečíků, zalezi na poradi parametrů! 
    // pozitivni to sice je ale muze to byt i s negativniho - body 3,4 jsou z negativniho polomeru
    private static Souradnice najdiStred4Bodu(Souradnice bod1zPozitivnihoPolomeru, Souradnice bod3zPozitivnihoPolomeru, Souradnice bod2zPozitivnihoPolomeru, Souradnice bod4zPozitivnihoPolomeru) {

        //body na tech primkách - alias ty průsečíky
        Double x1 = bod1zPozitivnihoPolomeru.getSouradniceX();
        Double x2 = bod3zPozitivnihoPolomeru.getSouradniceX();
        Double x3 = bod2zPozitivnihoPolomeru.getSouradniceX();
        Double x4 = bod4zPozitivnihoPolomeru.getSouradniceX();
        
        Double y1 = bod1zPozitivnihoPolomeru.getSouradniceY();
        Double y2 = bod3zPozitivnihoPolomeru.getSouradniceY();
        Double y3 = bod2zPozitivnihoPolomeru.getSouradniceY();
        Double y4 = bod4zPozitivnihoPolomeru.getSouradniceY();

        //konstanty
        Double a = (y1 - y2);
        Double b = (x2 - x1);
        Double c = (y3 - y4);
        Double d = (x4 - x3);
        //vyjádření dvou parametrických rovnic přímky a určení x,y
        Double y = (0 - a * c * x3 - a * d * y3 + c * a * x1 + c * b * y1) / (c * b - a * d);
        Double x = (d * y3 - d * y + c * x3) / c;

        //uložení středu jako proměnné typu Souřadnice
        Souradnice stred4Bodu = new Souradnice(x, y);
        return stred4Bodu;
    }
    
    private static Double najdiPolomer4Bodu(Souradnice stred4Bodu, Souradnice bod1zPozitivnihoPolomeru, Souradnice bod2zPozitivnihoPolomeru, Souradnice bod3zPozitivnihoPolomeru, Souradnice bod4zPozitivnihoPolomeru) {
        // fce najde polomer kružnice N - největší vzdálenost mezi průsečíky a střede kružniceN
        Double vzdalenost1 = najdiVzdalenostBodu(stred4Bodu, bod1zPozitivnihoPolomeru);
        Double vzdalenost2 = najdiVzdalenostBodu(stred4Bodu, bod2zPozitivnihoPolomeru);
        Double vzdalenost3 = najdiVzdalenostBodu(stred4Bodu, bod3zPozitivnihoPolomeru);
        Double vzdalenost4 = najdiVzdalenostBodu(stred4Bodu, bod4zPozitivnihoPolomeru);
        Double nejvetsiVzdalenost = 0.0;
        
        
        ArrayList<Double> velikostVzdalenosti = new ArrayList<Double>();
        velikostVzdalenosti.add(vzdalenost1);
        velikostVzdalenosti.add(vzdalenost2);
        velikostVzdalenosti.add(vzdalenost3);
        velikostVzdalenosti.add(vzdalenost4);
        
        for (Double aktualniVzdalenost : velikostVzdalenosti) {
            if (nejvetsiVzdalenost < aktualniVzdalenost) {
                nejvetsiVzdalenost = aktualniVzdalenost;
                
            }
            
        }
        
        
        return nejvetsiVzdalenost;
    }

    // fce zavolana pri poctu průsečiků - 2
    private static Kruznice najdiKruzniciNze2Pruseciku(Kruznice kruzniceA, Kruznice kruzniceB, Double d) {
        
        Double souradniceX;
        Double souradniceY;
        // proměnné m,v,sx,sy slouží pro získání průsečíku - body cx1,cy1 a cx2,cy2
        // funkce vypoci* slouzi pro výpočet stejnojmenných proměnných
        Double m = vypoctiM(kruzniceA.getPolomerPozitivni(), kruzniceB.getPolomerPozitivni(), d);
        Double v = vypoctiV(kruzniceA.getPolomerPozitivni(), m);
        
        Double sx = vypoctiSx(kruzniceA.getOrientacnibod().getSouradnice().getSouradniceX(), m, d, kruzniceB.getOrientacnibod().getSouradnice().getSouradniceX());
        Double sy = vypoctiSy(kruzniceA.getOrientacnibod().getSouradnice().getSouradniceY(), m, d, kruzniceB.getOrientacnibod().getSouradnice().getSouradniceY());
        Double cx1 = vypocticx(sx, v, d, kruzniceA.getOrientacnibod().getSouradnice().getSouradniceY(), kruzniceB.getOrientacnibod().getSouradnice().getSouradniceY());
        Double cy1 = vypocticy(sy, v, d, kruzniceA.getOrientacnibod().getSouradnice().getSouradniceX(), kruzniceB.getOrientacnibod().getSouradnice().getSouradniceX());
        Double cx2 = vypocticx2(sx, v, d, kruzniceA.getOrientacnibod().getSouradnice().getSouradniceY(), kruzniceB.getOrientacnibod().getSouradnice().getSouradniceY());
        Double cy2 = vypocticy2(sy, v, d, kruzniceA.getOrientacnibod().getSouradnice().getSouradniceX(), kruzniceB.getOrientacnibod().getSouradnice().getSouradniceX());

        //najde stred pomyslné úsečky spojující 2 pruseciku a vrati souradnice stredu, kde vytvorime kruzniciN
        // nejprve pro souradnice x 
        if (cx1 > cx2) {
            souradniceX = (cx1 - cx2) / 2 + cx2;
        } else {
            souradniceX = (cx2 - cx1) / 2 + cx1;
        }
        // poté pro souradnice y
        if (cy1 > cy2) {
            souradniceY = (cy1 - cy2) / 2 + cy2;
        } else {
            souradniceY = (cy2 - cy1) / 2 + cy1;
        }

        //souradnice jsou ulozeny do proměnných
        Souradnice souradnice1 = new Souradnice(cx1, cy1);
        Souradnice souradnice2 = new Souradnice(cx2, cy2);

        //najde vzdálenost průsečíků a pak podělí dvěma - získáme tím poloměr kružniceN
        Double polomerKruzniceN = najdiVzdalenostBodu(souradnice1, souradnice2) / 2;

        //výsledné hodnoty uloží do proměnné kružniceN
        Souradnice souradniceStreduKruzniceN = new Souradnice(souradniceX, souradniceY);
        Kruznice kruzniceN = new Kruznice(souradniceStreduKruzniceN, polomerKruzniceN);
        //vrati kruzniciN ze dvou pruseciku2 dvou pozitivnich kruznic
        return kruzniceN;
    }
    
    private static Kruznice najdikruzniciNze4Pruseciku(Kruznice kruzniceA, Kruznice kruzniceB, Double d) {
        //fce najde pruseciky - cili 4 body  
        //kruznice vlevo je B, vpravo A, kde A protina obe kruznice B
        Kruznice kruzniceNze4bodu = null;
        //podmínka která rozliší která kružnice protína tu druhou celým mezikružím
        if (d < kruzniceA.getPolomerPozitivni() + kruzniceB.getPolomerNegativni()) {
            ArrayList<Souradnice> prusecikyZe4bodu = najdiPrusecikyZe4bodu(kruzniceA, kruzniceB, d);
            //fce získá stred tech 4 průsečíků
            Souradnice stred4bodu = najdiStred4Bodu(prusecikyZe4bodu.get(0), prusecikyZe4bodu.get(1), prusecikyZe4bodu.get(2), prusecikyZe4bodu.get(3));
            //fce najdiPolomer4Bodu získá největší vzdálenost mezi středem a těmi průsečíky a uloží ji jako poloměr kružniceN
            kruzniceNze4bodu = new Kruznice(stred4bodu, najdiPolomer4Bodu(stred4bodu, prusecikyZe4bodu.get(0), prusecikyZe4bodu.get(1), prusecikyZe4bodu.get(2), prusecikyZe4bodu.get(3)));
        } else {
            ArrayList<Souradnice> prusecikyZe4bodu = najdiPrusecikyZe4bodu(kruzniceB, kruzniceA, d);
            Souradnice stred4bodu = najdiStred4Bodu(prusecikyZe4bodu.get(0), prusecikyZe4bodu.get(1), prusecikyZe4bodu.get(2), prusecikyZe4bodu.get(3));
            kruzniceNze4bodu = new Kruznice(stred4bodu, najdiPolomer4Bodu(stred4bodu, prusecikyZe4bodu.get(0), prusecikyZe4bodu.get(1), prusecikyZe4bodu.get(2), prusecikyZe4bodu.get(3)));
        }
        return kruzniceNze4bodu;
        // ArrayList<Souradnice> prusecikyZe4bodu = najdiPrusecikyZe4bodu (kruzniceA,kruzniceB, d);

    }
    
    private static ArrayList<Souradnice> najdiPrusecikyZe4bodu(Kruznice kruzniceA, Kruznice kruzniceB, Double d) {
        //vypocet nejdriv pro pozitivni poloemry kruznic A,B
        // pro body 1,2 na pozitivnich polomerech
        Double m1 = vypoctiM(kruzniceA.getPolomerPozitivni(), kruzniceB.getPolomerPozitivni(), d);
        Double v1 = vypoctiV(kruzniceA.getPolomerPozitivni(), m1);
        Double sx1 = vypoctiSx(kruzniceA.getOrientacnibod().getSouradnice().getSouradniceX(), m1, d, kruzniceB.getOrientacnibod().getSouradnice().getSouradniceX());
        Double sy1 = vypoctiSy(kruzniceA.getOrientacnibod().getSouradnice().getSouradniceY(), m1, d, kruzniceB.getOrientacnibod().getSouradnice().getSouradniceY());
        Double cx1 = vypocticx(sx1, v1, d, kruzniceA.getOrientacnibod().getSouradnice().getSouradniceY(), kruzniceB.getOrientacnibod().getSouradnice().getSouradniceY());
        Double cy1 = vypocticy(sy1, v1, d, kruzniceA.getOrientacnibod().getSouradnice().getSouradniceX(), kruzniceB.getOrientacnibod().getSouradnice().getSouradniceX());
        Double cx2 = vypocticx2(sx1, v1, d, kruzniceA.getOrientacnibod().getSouradnice().getSouradniceY(), kruzniceB.getOrientacnibod().getSouradnice().getSouradniceY());
        Double cy2 = vypocticy2(sy1, v1, d, kruzniceA.getOrientacnibod().getSouradnice().getSouradniceX(), kruzniceB.getOrientacnibod().getSouradnice().getSouradniceX());

        //vypocet vlevo pozitivni -A a vpravo negatovni polomer -B
        Double m2 = vypoctiM(kruzniceA.getPolomerPozitivni(), kruzniceB.getPolomerNegativni(), d);
        Double v2 = vypoctiV(kruzniceA.getPolomerPozitivni(), m2);
        Double sx2 = vypoctiSx(kruzniceA.getOrientacnibod().getSouradnice().getSouradniceX(), m2, d, kruzniceB.getOrientacnibod().getSouradnice().getSouradniceX());
        Double sy2 = vypoctiSy(kruzniceA.getOrientacnibod().getSouradnice().getSouradniceY(), m2, d, kruzniceB.getOrientacnibod().getSouradnice().getSouradniceY());
        Double cx3 = vypocticx(sx2, v2, d, kruzniceA.getOrientacnibod().getSouradnice().getSouradniceY(), kruzniceB.getOrientacnibod().getSouradnice().getSouradniceY());
        Double cy3 = vypocticy(sy2, v2, d, kruzniceA.getOrientacnibod().getSouradnice().getSouradniceX(), kruzniceB.getOrientacnibod().getSouradnice().getSouradniceX());
        Double cx4 = vypocticx2(sx2, v2, d, kruzniceA.getOrientacnibod().getSouradnice().getSouradniceY(), kruzniceB.getOrientacnibod().getSouradnice().getSouradniceY());
        Double cy4 = vypocticy2(sy2, v2, d, kruzniceA.getOrientacnibod().getSouradnice().getSouradniceX(), kruzniceB.getOrientacnibod().getSouradnice().getSouradniceX());

        //do pole umistim 4 pruseciky, nejprve horno P-P a potom spodni, pak N-P horni a pak spodni
        ArrayList<Souradnice> serazene4Pruseciky = new ArrayList<Souradnice>(4);
        Souradnice souradnice1 = new Souradnice(cx1, cy1);
        Souradnice souradnice2 = new Souradnice(cx2, cy2);
        Souradnice souradnice3 = new Souradnice(cx3, cy3);
        Souradnice souradnice4 = new Souradnice(cx4, cy4);
        
        serazene4Pruseciky.add(souradnice1);
        serazene4Pruseciky.add(souradnice2);
        serazene4Pruseciky.add(souradnice3);
        serazene4Pruseciky.add(souradnice4);
        
        return serazene4Pruseciky;
    }
    
    private static Kruznice najdiDalsiKruzniciNzPozitivni(Kruznice kruzniceN, Kruznice aktualniKruznice, Double d) {
        //fce platí pro 2 průsečíky
        //má odlišné parametry než najdiKruzniciNze2Pruseciku!
        Double souradniceX;
        Double souradniceY;
        
        Double m = vypoctiM(kruzniceN.getPolomerKruzniceN(), aktualniKruznice.getPolomerPozitivni(), d);
        Double v = vypoctiV(kruzniceN.getPolomerKruzniceN(), m);
        
        Double sx = vypoctiSx(kruzniceN.getStredKruzniceN().getSouradniceX(), m, d, aktualniKruznice.getOrientacnibod().getSouradnice().getSouradniceX());
        Double sy = vypoctiSy(kruzniceN.getStredKruzniceN().getSouradniceY(), m, d, aktualniKruznice.getOrientacnibod().getSouradnice().getSouradniceY());
        Double cx1 = vypocticx(sx, v, d, kruzniceN.getStredKruzniceN().getSouradniceY(), aktualniKruznice.getOrientacnibod().getSouradnice().getSouradniceY());
        Double cy1 = vypocticy(sy, v, d, kruzniceN.getStredKruzniceN().getSouradniceX(), aktualniKruznice.getOrientacnibod().getSouradnice().getSouradniceX());
        Double cx2 = vypocticx2(sx, v, d, kruzniceN.getStredKruzniceN().getSouradniceY(), aktualniKruznice.getOrientacnibod().getSouradnice().getSouradniceY());
        Double cy2 = vypocticy2(sy, v, d, kruzniceN.getStredKruzniceN().getSouradniceX(), aktualniKruznice.getOrientacnibod().getSouradnice().getSouradniceX());

        //najde stred tech 2 pruseciku a vrati souradnice stredu, kde vytvorime kruzniceN 
        if (cx1 > cx2) {
            souradniceX = (cx1 - cx2) / 2 + cx2;
        } else {
            souradniceX = (cx2 - cx1) / 2 + cx1;
        }
        
        if (cy1 > cy2) {
            souradniceY = (cy1 - cy2) / 2 + cy2;
        } else {
            souradniceY = (cy2 - cy1) / 2 + cy1;
        }
        
        Souradnice souradnice1 = new Souradnice(cx1, cy1);
        Souradnice souradnice2 = new Souradnice(cx2, cy2);
        
        Double polomerKruzniceN = najdiVzdalenostBodu(souradnice1, souradnice2) / 2;
        
        Souradnice souradniceStreduKruzniceN = new Souradnice(souradniceX, souradniceY);
        kruzniceN = new Kruznice(souradniceStreduKruzniceN, polomerKruzniceN);
        //vrati kruzniciN ze dvou pruseciku2 dvou pozitivnich kruznic
        return kruzniceN;
    }
    
    private static Kruznice najdiDalsikruzniciNze4PrusecikuPozitivniInegativni(Kruznice kruzniceN, Kruznice aktualniKruznice, Double d) {
        //pocitány jsou průsečíky jak pro pozitivní poloměr tak pro negativní poloměr kružnice z pole serazeneKruznicePodleMezikruzi
        // a kružnicí N
        Double m = vypoctiM(kruzniceN.getPolomerKruzniceN(), aktualniKruznice.getPolomerPozitivni(), d);
        Double v = vypoctiV(kruzniceN.getPolomerKruzniceN(), m);
        
        Double sx = vypoctiSx(kruzniceN.getStredKruzniceN().getSouradniceX(), m, d, aktualniKruznice.getOrientacnibod().getSouradnice().getSouradniceX());
        Double sy = vypoctiSy(kruzniceN.getStredKruzniceN().getSouradniceY(), m, d, aktualniKruznice.getOrientacnibod().getSouradnice().getSouradniceY());
        Double cx1 = vypocticx(sx, v, d, kruzniceN.getStredKruzniceN().getSouradniceY(), aktualniKruznice.getOrientacnibod().getSouradnice().getSouradniceY());
        Double cy1 = vypocticy(sy, v, d, kruzniceN.getStredKruzniceN().getSouradniceX(), aktualniKruznice.getOrientacnibod().getSouradnice().getSouradniceX());
        Double cx2 = vypocticx2(sx, v, d, kruzniceN.getStredKruzniceN().getSouradniceY(), aktualniKruznice.getOrientacnibod().getSouradnice().getSouradniceY());
        Double cy2 = vypocticy2(sy, v, d, kruzniceN.getStredKruzniceN().getSouradniceX(), aktualniKruznice.getOrientacnibod().getSouradnice().getSouradniceX());
        
        Double m2 = vypoctiM(kruzniceN.getPolomerKruzniceN(), aktualniKruznice.getPolomerNegativni(), d);
        Double v2 = vypoctiV(kruzniceN.getPolomerKruzniceN(), m2);
        
        Double sx2 = vypoctiSx(kruzniceN.getStredKruzniceN().getSouradniceX(), m2, d, aktualniKruznice.getOrientacnibod().getSouradnice().getSouradniceX());
        Double sy2 = vypoctiSy(kruzniceN.getStredKruzniceN().getSouradniceY(), m2, d, aktualniKruznice.getOrientacnibod().getSouradnice().getSouradniceY());
        Double cx3 = vypocticx(sx2, v2, d, kruzniceN.getStredKruzniceN().getSouradniceY(), aktualniKruznice.getOrientacnibod().getSouradnice().getSouradniceY());
        Double cy3 = vypocticy(sy2, v2, d, kruzniceN.getStredKruzniceN().getSouradniceX(), aktualniKruznice.getOrientacnibod().getSouradnice().getSouradniceX());
        Double cx4 = vypocticx2(sx2, v2, d, kruzniceN.getStredKruzniceN().getSouradniceY(), aktualniKruznice.getOrientacnibod().getSouradnice().getSouradniceY());
        Double cy4 = vypocticy2(sy2, v2, d, kruzniceN.getStredKruzniceN().getSouradniceX(), aktualniKruznice.getOrientacnibod().getSouradnice().getSouradniceX());

        //souřadncie jsou uloženy do proměnných
        Souradnice souradnice1 = new Souradnice(cx1, cy1);
        Souradnice souradnice2 = new Souradnice(cx2, cy2);
        Souradnice souradnice3 = new Souradnice(cx3, cy3);
        Souradnice souradnice4 = new Souradnice(cx4, cy4);

        //fce najdiStred4Bodu nalezne střed protínajících se přímek spojujících vypočítané průsečíky 
        Souradnice stred4bodu = najdiStred4Bodu(souradnice1, souradnice3, souradnice2, souradnice4);

        //fce najde poloměr kružnice N - největší vzdálenost mezi průsečíky a střede kružniceN
        Double polomerKruzniceN = najdiPolomer4Bodu(stred4bodu, souradnice1, souradnice2, souradnice3, souradnice4);
        
        kruzniceN = new Kruznice(stred4bodu, polomerKruzniceN);
        //vrati kruzniciN ze 4 pruseciku - kruzniceSnejvetsimMezikruzim a kruzniceN
        return kruzniceN;
    }
    
    private static Double vypoctiDskruzniciN(Kruznice kruzniceN1, Kruznice aktualniKruznice) {
        
        Double xa = kruzniceN1.getStredKruzniceN().getSouradniceX();
        Double ya = kruzniceN1.getStredKruzniceN().getSouradniceY();
        Double xb = aktualniKruznice.getOrientacnibod().getSouradnice().getSouradniceX();
        Double yb = aktualniKruznice.getOrientacnibod().getSouradnice().getSouradniceY();
        
        Double d = Math.sqrt(Math.pow((xa - xb), 2.0) + Math.pow((ya - yb), 2.0));
        
        return d;
    }

    //funkce pro vypocet kruznic, ktere rozdeli mezikruzi a vytvori nove kruznice s polomerem vnitrni plus cast mezikruzi
    public static ArrayList<Kruznice> najdiStredniPolomeryKruznic(ArrayList<Kruznice> kruzniceSeStredyVorientacnichBodech) {
        
        ArrayList<Kruznice> poleKruznicSeStrednimPolomerem = new ArrayList<Kruznice>();
        
        for (Kruznice aktualniKruznice : kruzniceSeStredyVorientacnichBodech) {
            Double polomerStredniA = aktualniKruznice.getPolomerNegativni() + (aktualniKruznice.getPolomerPozitivni() - aktualniKruznice.getPolomerNegativni()) / 1.5;
            
            poleKruznicSeStrednimPolomerem.add(new Kruznice(aktualniKruznice.getOrientacnibod(), polomerStredniA));
            
            
        }
        return poleKruznicSeStrednimPolomerem;
    }
    
    
    public static ArrayList<Prusecik> najdiPrusecikyKruznicSeStrednimPolomerem(ArrayList<Kruznice> kruzniceSeStrednimPolomerem) {
        ArrayList<Prusecik> polePruseciku = new ArrayList<Prusecik>();

        for (Kruznice aktualniKruzniceA : kruzniceSeStrednimPolomerem) {
            for (Kruznice aktualniKruzniceB : kruzniceSeStrednimPolomerem) {
                Double d = vypoctiD(aktualniKruzniceA, aktualniKruzniceB);

                //prusecik mezi kruznicemi neni
                if (d > (aktualniKruzniceA.getPolomerStredni() + aktualniKruzniceB.getPolomerStredni()) || (d + aktualniKruzniceA.getPolomerStredni() < aktualniKruzniceB.getPolomerStredni()) || (d + aktualniKruzniceB.getPolomerStredni() < aktualniKruzniceA.getPolomerStredni())) {
                    //continue preskoci na dalsi cyklus
                    continue;
                }
                //nasledujic fce pocitaji pruseciky      
                Double m = vypoctiM(aktualniKruzniceA.getPolomerStredni(), aktualniKruzniceB.getPolomerStredni(), d);
                Double v = vypoctiV(aktualniKruzniceA.getPolomerStredni(), m);
                Double sx = vypoctiSx(aktualniKruzniceA.getOrientacnibod().getSouradnice().getSouradniceX(), m, d, aktualniKruzniceB.getOrientacnibod().getSouradnice().getSouradniceX());
                Double sy = vypoctiSy(aktualniKruzniceA.getOrientacnibod().getSouradnice().getSouradniceY(), m, d, aktualniKruzniceB.getOrientacnibod().getSouradnice().getSouradniceY());

                //bude 1 prusecik
                if (d == (aktualniKruzniceA.getPolomerStredni() + aktualniKruzniceB.getPolomerStredni()) || (d + aktualniKruzniceA.getPolomerStredni() == aktualniKruzniceB.getPolomerStredni()) || (d + aktualniKruzniceB.getPolomerStredni() == aktualniKruzniceA.getPolomerStredni())) {
                    polePruseciku.add(new Prusecik(new Souradnice(sx, sy), aktualniKruzniceA, aktualniKruzniceB));
                } //2 pruseciky existuji mezi kruznicemi
                else {
                    Double cx1 = vypocticx(sx, v, d, aktualniKruzniceA.getOrientacnibod().getSouradnice().getSouradniceY(), aktualniKruzniceB.getOrientacnibod().getSouradnice().getSouradniceY());
                    Double cx2 = vypocticx2(sx, v, d, aktualniKruzniceA.getOrientacnibod().getSouradnice().getSouradniceY(), aktualniKruzniceB.getOrientacnibod().getSouradnice().getSouradniceY());
                    Double cy1 = vypocticy(sy, v, d, aktualniKruzniceA.getOrientacnibod().getSouradnice().getSouradniceX(), aktualniKruzniceB.getOrientacnibod().getSouradnice().getSouradniceX());
                    Double cy2 = vypocticy2(sy, v, d, aktualniKruzniceA.getOrientacnibod().getSouradnice().getSouradniceX(), aktualniKruzniceB.getOrientacnibod().getSouradnice().getSouradniceX());
                    
                    polePruseciku.add(new Prusecik(new Souradnice(cx1, cy1), aktualniKruzniceA, aktualniKruzniceB));
                    polePruseciku.add(new Prusecik(new Souradnice(cx2, cy2), aktualniKruzniceA, aktualniKruzniceB));
                    
                }
            }
        }
        
        //kontrola duplicity pruseciku - pruseciky se stejnymi souradnicemi jsou vyrazeny
        ArrayList<Prusecik> polePrusecikuBezDuplicit = new ArrayList<Prusecik>();
        polePrusecikuBezDuplicit.add(polePruseciku.get(0));
        polePruseciku.remove(0);
        
        for (Prusecik aktualniprusecik : polePruseciku) {
            int pocitadloRuznychPruseciku = 0;
            for (Prusecik aktualniprusecikNovy : polePrusecikuBezDuplicit) {
                int ax = aktualniprusecik.getSouradnice().getSouradniceX().intValue();
                int ay = aktualniprusecik.getSouradnice().getSouradniceY().intValue();
                
                int bx = aktualniprusecikNovy.getSouradnice().getSouradniceX().intValue();
                int by = aktualniprusecikNovy.getSouradnice().getSouradniceY().intValue();
                
                if (ax == bx && ay == by) {
                    break;
                } else {
                    pocitadloRuznychPruseciku++;
                }
                
            }
            if (pocitadloRuznychPruseciku == polePrusecikuBezDuplicit.size()) {
                polePrusecikuBezDuplicit.add(aktualniprusecik);
            }
        }
        
        
        //vykresleni pruseciku
        Vykresleni.vykresliPrusecikyBezDuplicit(polePrusecikuBezDuplicit);
       
        //ukonci program kdyz nejsou zadne pruseciky
        if (polePrusecikuBezDuplicit == null){
            return null;
        }
        
        
        return polePrusecikuBezDuplicit;
    }
    
    public static ArrayList<Prusecik> najdiPrusecikyLeziciVeVSechKruznicich(ArrayList<Prusecik> prusecikyDvouKruznic, ArrayList<Kruznice> kruzniceSeStredyVorientacnichBodech) {
        ArrayList<Prusecik> pruseciky = new ArrayList<Prusecik>();
        
        for (Prusecik aktualniPrusecik : prusecikyDvouKruznic) {
            //pocitadlo pocita kruznice ve kterych je umisten prusecik
            int pocitadloObkopujichKruznic = 0;
            for (Kruznice aktualniKruznice : kruzniceSeStredyVorientacnichBodech) {
                //podminka overujich zda prusecik lezi v mezikruzi
                Double px = aktualniPrusecik.getSouradnice().getSouradniceX();
                Double stredX = aktualniKruznice.getOrientacnibod().getSouradnice().getSouradniceX();
                Double py = aktualniPrusecik.getSouradnice().getSouradniceY();
                Double stredY = aktualniKruznice.getOrientacnibod().getSouradnice().getSouradniceY();
                Double polomerPozitivni = aktualniKruznice.getPolomerPozitivni();
                Double polomerNegativni = aktualniKruznice.getPolomerNegativni();

                //podminka overujich zda ten prusecik lezi v mezikruzi
                if (((px - stredX) * (px - stredX) + (py - stredY) * (py - stredY)) <= (polomerPozitivni * polomerPozitivni)) {
                    if (((px - stredX) * (px - stredX) + (py - stredY) * (py - stredY)) >= (polomerNegativni * polomerNegativni)) {
                        pocitadloObkopujichKruznic++;
                        continue;
                    }
                }
            }
            
            if (pocitadloObkopujichKruznic >= kruzniceSeStredyVorientacnichBodech.size() * (0.75)) {
                pruseciky.add(aktualniPrusecik);
            }

            System.out.println("Pocet pruseciku novych kruznic je: " + prusecikyDvouKruznic.size() + " " + "pocet obklopenych pruseciku nachazejicich se v meziruzi: " + pruseciky.size() + " " + "pocet obklopujicich kruznic je " + pocitadloObkopujichKruznic);
            Log.zapisDoLogu("Pocet pruseciku novych kruznic je: " + prusecikyDvouKruznic.size() + " " + "pocet obklopenych pruseciku nachazejicich se v meziruzi: " + pruseciky.size() + " " + "pocet obklopujicich kruznic je " + pocitadloObkopujichKruznic);
           
        }
        Vykresleni.vykresliPrusecikyBezDuplicit(pruseciky);
        return pruseciky;
    }
    
    public static Prusecik vypoctiCilovyPrusecik(ArrayList<Prusecik> prusecikyVeVsechkruznicich) {
        Prusecik cilovyPrusecik = null;
        System.out.println("Zacinam pocitat cilpovy prisecik");
        Log.zapisDoLogu("Zacinam pocitat cilovy prusecik");
        //vypocet obsahu oblasti kde lezi cilovy prusecik
        Double obsahOblasti = spoctiObsahOblasti(prusecikyVeVsechkruznicich);
        //  System.out.println("Vypis obsah oblasti " + obsahOblasti);
        
        //fce vypocita x souradnice ciloveho pruseciku
        Double souradniceXCilovehoPruseciku = vypoctiSouradniceXCilovehoPruseciku(obsahOblasti, prusecikyVeVsechkruznicich);
       
        // System.out.println("Cilovy prusecik - sour. X" + souradniceXCilovehoPruseciku);
         
        //fce vypocita y souradnici ciloveho pruseciku
        Double souradniceYCilovehoPruseciku = vypoctiSouradniceYCilovehoPruseciku(obsahOblasti, prusecikyVeVsechkruznicich);
        
        cilovyPrusecik = new Prusecik(new Souradnice(souradniceXCilovehoPruseciku, souradniceYCilovehoPruseciku),obsahOblasti);
        System.out.println("Cilovy prusecik - sour. x " + souradniceXCilovehoPruseciku + "sour. y " + souradniceYCilovehoPruseciku);
        Log.zapisDoLogu("Cilovy prusecik - sour. x " + souradniceXCilovehoPruseciku + "sour. y " + souradniceYCilovehoPruseciku);
        
        return cilovyPrusecik;
    }
    
    private static Double spoctiObsahOblasti(ArrayList<Prusecik> prusecikyVeVsechkruznicich) {
        Double suma = 0.0;
        Double obsah = 0.0;
        //vzorcve pro vypocet obsahu polygonu jsou uvedeny v diplomove praci
        for (int i = 0; i < prusecikyVeVsechkruznicich.size() - 1; i++) {
            Double aktualniPrusecikX = prusecikyVeVsechkruznicich.get(i).getSouradnice().getSouradniceX();
            Double nasledujiciPrusecikX = prusecikyVeVsechkruznicich.get(i + 1).getSouradnice().getSouradniceX();
            
            Double aktualniPrusecikY = prusecikyVeVsechkruznicich.get(i).getSouradnice().getSouradniceY();
            Double nasledujiciPrusecikY = prusecikyVeVsechkruznicich.get(i + 1).getSouradnice().getSouradniceY();
            
            suma = suma + (aktualniPrusecikX * nasledujiciPrusecikY - nasledujiciPrusecikX * aktualniPrusecikY);
            
        }
        
        Double posledniPrusecikX = prusecikyVeVsechkruznicich.get(prusecikyVeVsechkruznicich.size() - 1).getSouradnice().getSouradniceX();
        Double prvniPrusecikX = prusecikyVeVsechkruznicich.get(0).getSouradnice().getSouradniceX();
        
        Double posledniPrusecikY = prusecikyVeVsechkruznicich.get(prusecikyVeVsechkruznicich.size() - 1).getSouradnice().getSouradniceY();
        Double prvniPrusecikY = prusecikyVeVsechkruznicich.get(0).getSouradnice().getSouradniceY();
        
        suma = suma + (posledniPrusecikX * prvniPrusecikY - prvniPrusecikX * posledniPrusecikY);
        
        obsah = suma / 2;
        return obsah;
    }
    
    private static Double vypoctiSouradniceXCilovehoPruseciku(Double obsahOblasti, ArrayList<Prusecik> prusecikyVeVsechkruznicich) {
        Double souradniceX = 0.0;
        Double suma = 0.0;
        
        for (int i = 0; i < prusecikyVeVsechkruznicich.size() - 1; i++) {
            Double aktualniPrusecikX = prusecikyVeVsechkruznicich.get(i).getSouradnice().getSouradniceX();
            Double nasledujiciPrusecikX = prusecikyVeVsechkruznicich.get(i + 1).getSouradnice().getSouradniceX();
            
            Double aktualniPrusecikY = prusecikyVeVsechkruznicich.get(i).getSouradnice().getSouradniceY();
            Double nasledujiciPrusecikY = prusecikyVeVsechkruznicich.get(i + 1).getSouradnice().getSouradniceY();
            
            suma = suma + ((aktualniPrusecikX + nasledujiciPrusecikX) * (aktualniPrusecikX * nasledujiciPrusecikY - nasledujiciPrusecikX * aktualniPrusecikY));
            
        }
        
        Double posledniPrusecikX = prusecikyVeVsechkruznicich.get(prusecikyVeVsechkruznicich.size() - 1).getSouradnice().getSouradniceX();
        Double prvniPrusecikX = prusecikyVeVsechkruznicich.get(0).getSouradnice().getSouradniceX();
        
        Double posledniPrusecikY = prusecikyVeVsechkruznicich.get(prusecikyVeVsechkruznicich.size() - 1).getSouradnice().getSouradniceY();
        Double prvniPrusecikY = prusecikyVeVsechkruznicich.get(0).getSouradnice().getSouradniceY();
        
        suma = suma + ((posledniPrusecikX + prvniPrusecikX) * (posledniPrusecikX * prvniPrusecikY - prvniPrusecikX * posledniPrusecikY));
        
        souradniceX = suma / (6 * obsahOblasti);
        return souradniceX;
    }
    
    private static Double vypoctiSouradniceYCilovehoPruseciku(Double obsahOblasti, ArrayList<Prusecik> prusecikyVeVsechkruznicich) {
        Double souradniceY = 0.0;
        Double suma = 0.0;
        
        for (int i = 0; i < prusecikyVeVsechkruznicich.size() - 1; i++) {
            Double aktualniPrusecikX = prusecikyVeVsechkruznicich.get(i).getSouradnice().getSouradniceX();
            Double nasledujiciPrusecikX = prusecikyVeVsechkruznicich.get(i + 1).getSouradnice().getSouradniceX();
            
            Double aktualniPrusecikY = prusecikyVeVsechkruznicich.get(i).getSouradnice().getSouradniceY();
            Double nasledujiciPrusecikY = prusecikyVeVsechkruznicich.get(i + 1).getSouradnice().getSouradniceY();
            
            suma = suma + ((aktualniPrusecikY + nasledujiciPrusecikY) * (aktualniPrusecikX * nasledujiciPrusecikY - nasledujiciPrusecikX * aktualniPrusecikY));
            
        }
        
        Double posledniPrusecikX = prusecikyVeVsechkruznicich.get(prusecikyVeVsechkruznicich.size() - 1).getSouradnice().getSouradniceX();
        Double prvniPrusecikX = prusecikyVeVsechkruznicich.get(0).getSouradnice().getSouradniceX();
        
        Double posledniPrusecikY = prusecikyVeVsechkruznicich.get(prusecikyVeVsechkruznicich.size() - 1).getSouradnice().getSouradniceY();
        Double prvniPrusecikY = prusecikyVeVsechkruznicich.get(0).getSouradnice().getSouradniceY();
        
        suma = suma + ((posledniPrusecikY + prvniPrusecikY) * (posledniPrusecikX * prvniPrusecikY - prvniPrusecikX * posledniPrusecikY));
        
        souradniceY = suma / (6 * obsahOblasti);
        return souradniceY;
    }
    

    public static Prusecik vypoctiCilovyPrusekZeDvouPruseciku(ArrayList<Prusecik> prusecikyVeVsechkruznicich) {
    Double ax = prusecikyVeVsechkruznicich.get(0).getSouradnice().getSouradniceX();
    Double ay = prusecikyVeVsechkruznicich.get(0).getSouradnice().getSouradniceY();

    Double bx = prusecikyVeVsechkruznicich.get(1).getSouradnice().getSouradniceX();
    Double by = prusecikyVeVsechkruznicich.get(1).getSouradnice().getSouradniceY();    
    
    Double x = (ax + bx)/2; 
    Double y = (ay + by)/2;
    Prusecik cilovyPrusecik = new Prusecik(new Souradnice(x, y));
    
    return cilovyPrusecik;
    }
    
    private static class Porovnavace {
        
        public static class podleMezikruziClass implements Comparator<Kruznice> {
            
            @Override
            //metoda compare s parametry typu Kruznice
            // vrati porovnane pole kruznic - serazeneKruznicePodleMezikruzi
            public int compare(Kruznice k1, Kruznice k2) {
                
                Double delkaMezikruziA;
                Double delkaMezikruziB;
                Double rozdil;
                
                delkaMezikruziA = (k1.getPolomerPozitivni() - k1.getPolomerNegativni());
                delkaMezikruziB = (k2.getPolomerPozitivni() - k2.getPolomerNegativni());
                
                rozdil = delkaMezikruziB - delkaMezikruziA;

                //porovnani hodnot - ktera je vetsi kdyz je B vetsi nez A ---- 1
                if (rozdil > 0.0) {
                    return 1;
                } else if (rozdil < 0.0) {
                    return -1;
                } else {
                    return 0;
                }
                
            }
        }
        
        public static Comparator<Kruznice> podleMezikruzi() {
            return new podleMezikruziClass();
        }
        
        public Porovnavace() {
        }
    }
}
