private static unsafe ProstokątNaObrazie ZnajdźSkrajnePunktuObrazu2(bool *Obraz, int x, int y, HashSet <ObiektNaMapie> tr)
        {
            ProstokątNaObrazie zwr = new ProstokątNaObrazie();

            {
                ObiektNaMapie PomocniczyObiekt = new ObiektNaMapie();
                foreach (var item in tr)
                {
                    SprawdźSkrajne(new Point(item.MinX, item.MinY), ref PomocniczyObiekt);
                    SprawdźSkrajne(new Point(item.MaxX, item.MaxY), ref PomocniczyObiekt);
                }
                zwr.Początek = new Point(PomocniczyObiekt.MinX, PomocniczyObiekt.MinY);
                zwr.Koniec   = new Point(PomocniczyObiekt.MaxX, PomocniczyObiekt.MaxY);
                List <Point> ListaOdległośi = new List <Point>();
                Point        Sierodek       = zwr.Początek.Dodaj(zwr.Koniec).Razy(0.5f);
                ListaOdległośi.Add(Sierodek);
                ListaOdległośi.Add(ZnajdźNajdalszyPunkt(zwr, Obraz, x, y, ListaOdległośi));
                ListaOdległośi.Add(ZnajdźNajdalszyPunkt(zwr, Obraz, x, y, ListaOdległośi));
                ListaOdległośi.Add(ZnajdźNajdalszyPunkt(zwr, Obraz, x, y, ListaOdległośi));
                ListaOdległośi.Add(ZnajdźNajdalszyPunkt(zwr, Obraz, x, y, ListaOdległośi));
                zwr.XNYN = ListaOdległośi[1];
                ListaOdległośi.RemoveRange(0, 2);
                int L = ZnajdźNajdalszyKąt(ListaOdległośi, zwr.XNYN, Sierodek);
                zwr.XPYP = ListaOdległośi[L];
                ListaOdległośi.RemoveAt(L);
                zwr.XNYP = ListaOdległośi[0];
                zwr.XPYN = ListaOdległośi[1];
            }
            zwr.Ustaw(new Size(x, y));
            return(zwr);
        }
        private static unsafe Point ZnajdźNajdalszyPunkt(ProstokątNaObrazie ob, bool *Obraz, int x, int y, IList <Point> Punkty)
        {
            float Odległość          = 0;
            Point NajdalejPostawiony = new Point(0, 0);

            Obraz += x * ob.Początek.Y;
            for (int i = ob.Początek.Y; i < ob.Koniec.Y; i++)
            {
                Obraz += ob.Początek.X;
                for (int j = ob.Początek.X; j < ob.Koniec.X; j++, Obraz++)
                {
                    if (*Obraz)
                    {
                        Point p             = new Point(j, i);
                        float OdległośćTego = int.MaxValue;
                        foreach (var item in Punkty)
                        {
                            float Dys = item.Odległość(p);
                            if (Dys < OdległośćTego)
                            {
                                OdległośćTego = Dys;
                            }
                        }
                        if (OdległośćTego > Odległość)
                        {
                            Odległość          = OdległośćTego;
                            NajdalejPostawiony = p;
                        }
                    }
                }
                Obraz += x - ob.Koniec.X;
            }
            return(NajdalejPostawiony);
        }
        public static unsafe ProstokątNaObrazie PobierzZZdziecia(ref bool *ob, int x, int y)
        {
            int  WielkośćObrazu = x * y;
            int *Mapa;
            var  Lista = ZnajdźOpszary(ref ob, x, y, out Mapa);

            Lista.Sort();
            HashSet <ObiektNaMapie> tr = null;

            tr = SzukajRegionówNaKrawedzi(x, y, WielkośćObrazu, Mapa, Lista);

            Marshal.FreeHGlobal((IntPtr)Mapa);



            bool *[] Tablica      = new bool *[tr.Count];
            bool *[] TDoUsuniecia = new bool *[tr.Count];
            int      i            = 0;

            foreach (var item in tr)
            {
                Tablica[i]      = PobierzObszar(ob, item.Miejsce, x, y);
                TDoUsuniecia[i] = Tablica[i];
                i++;
            }
            Scal(WielkośćObrazu, ob, Tablica);
            foreach (var item in TDoUsuniecia)
            {
                Marshal.FreeHGlobal((IntPtr)item);
            }
            ProstokątNaObrazie zwr = ZnajdźSkrajnePunktuObrazu2(ob, x, y, tr);

            return(zwr);
        }
        private static unsafe ProstokątNaObrazie ZnajdźSkrajnePunktuObrazu(bool *Obraz, int x, int y, HashSet <ObiektNaMapie> tr)
        {
            ProstokątNaObrazie zwr = new ProstokątNaObrazie();
            {
                ObiektNaMapie PomocniczyObiekt = new ObiektNaMapie();
                foreach (var item in tr)
                {
                    SprawdźSkrajne(new Point(item.MinX, item.MinY), ref PomocniczyObiekt);
                    SprawdźSkrajne(new Point(item.MaxX, item.MaxY), ref PomocniczyObiekt);
                }
                zwr.Początek = new Point(PomocniczyObiekt.MinX, PomocniczyObiekt.MinY);
                zwr.Koniec   = new Point(PomocniczyObiekt.MaxX, PomocniczyObiekt.MaxY);
            }
            int DługośćX = zwr.Koniec.X - zwr.Początek.X;

            int[] TabPoczątów = new int[DługośćX];
            int[] TabKońców   = new int[DługośćX];
            zwr.TabicaKońców     = TabKońców;
            zwr.TablicaPoczątków = TabPoczątów;
            for (int i = zwr.Początek.X; i < zwr.Koniec.X; i++)
            {
                for (int j = zwr.Początek.Y; j < zwr.Koniec.Y; j++)
                {
                    if (Obraz[j * x + i])
                    {
                        TabPoczątów[i - zwr.Początek.X] = j - zwr.Początek.Y;
                        break;
                    }
                }
                for (int j = zwr.Koniec.Y - 1; j >= zwr.Początek.Y; j--)
                {
                    if (Obraz[j * x + i])
                    {
                        TabKońców[i - zwr.Początek.X] = j - zwr.Początek.Y;
                        break;
                    }
                }
            }
            zwr.MinimalnyX   = new Point(0, (TabKońców[0]) / 2);
            zwr.MaksymalnyX  = new Point(DługośćX - 1, TabPoczątów[DługośćX - 1]);
            zwr.MinimalnyY.Y = int.MaxValue;
            for (int i = 0; i < DługośćX; i++)
            {
                if (TabPoczątów[i] < zwr.MinimalnyY.Y)
                {
                    zwr.MinimalnyY.Y = TabPoczątów[i];
                    zwr.MinimalnyY.X = i;
                }
                if (TabKońców[i] > zwr.MaksymalnyY.Y)
                {
                    zwr.MaksymalnyY.Y = TabKońców[i];
                    zwr.MaksymalnyY.X = i;
                }
            }
            return(zwr);
        }
        public static float SprawdźOceneKątami(ProstokątNaObrazie pk)
        {
            float f = Matematyka.Podobność(Matematyka.ObliczKąt(pk.XPYP, pk.XNYP, pk.XNYN), Matematyka.ObliczKąt(pk.XNYP, pk.XPYP, pk.XPYN)) * Matematyka.Podobność(Matematyka.ObliczKąt(pk.XNYP, pk.XNYN, pk.XPYN), Matematyka.ObliczKąt(pk.XPYP, pk.XPYN, pk.XNYN));

            if (float.IsInfinity(f) || float.IsNaN(f))
            {
                return(0);
            }
            return(f * f);
        }
        public static unsafe ProstokątNaObrazie KorektaHauga(Size Rozmiar, bool *Obraz, ProstokątNaObrazie pk)
        {
            Haug h = new Haug();
            ProstokątNaObrazie pr = new ProstokątNaObrazie();

            pr.XNYN = h.ZnajdźProstopadłe(Obraz, Rozmiar, ZnajdźObszarOtaczający(pk.XNYN, Rozmiar, pk.ŚredniaDłógośc()));
            pr.XNYP = h.ZnajdźProstopadłe(Obraz, Rozmiar, ZnajdźObszarOtaczający(pk.XNYP, Rozmiar, pk.ŚredniaDłógośc()));
            pr.XPYN = h.ZnajdźProstopadłe(Obraz, Rozmiar, ZnajdźObszarOtaczający(pk.XPYN, Rozmiar, pk.ŚredniaDłógośc()));
            pr.XPYP = h.ZnajdźProstopadłe(Obraz, Rozmiar, ZnajdźObszarOtaczający(pk.XPYP, Rozmiar, pk.ŚredniaDłógośc()));
            pr.Ustaw(Rozmiar);
            return(pr);
        }
        public unsafe static float OcenaZaznaczonegoMetodaMalowanie(bool *b, bool *g, Size Rozmiar, ProstokątNaObrazie pk)
        {
            if (pk.OcenaZero)
            {
                return(0);
            }
            SprawdzanieWypełnienia G = new SprawdzanieWypełnienia(MaxOdległość, g, Rozmiar);

            G.MalujLinie(pk.XNYN, pk.XPYP);
            G.MalujLinie(pk.XPYP, pk.XNYP);
            G.MalujLinie(pk.XNYP, pk.XPYN);
            G.MalujLinie(pk.XPYN, pk.XNYN);
            float Zapamietana = G.Sprawź();

            G = new SprawdzanieWypełnienia(4, b, Rozmiar);
            G.MalujLinie(pk.XNYN, pk.XPYP);
            G.MalujLinie(pk.XPYP, pk.XNYP);
            G.MalujLinie(pk.XNYP, pk.XPYN);
            G.MalujLinie(pk.XPYN, pk.XNYN);
            return((G.Sprawź() * WaźnoścNajwiekszy + Zapamietana) * SprawdźOceneKątami(pk));
        }
        public unsafe static float OcenaZaznaczonegoGragmentu(bool *b, bool *g, Size Rozmiar, ProstokątNaObrazie pk)
        {
            if (pk.OcenaZero)
            {
                return(0);
            }
            Komputer.Matematyczne.Figury.FiguraZOdcinków fz = new Komputer.Matematyczne.Figury.FiguraZOdcinków();
            fz.Add(new Komputer.Matematyczne.Figury.Odcinek(pk.XNYN, pk.XPYP));
            fz.Add(new Komputer.Matematyczne.Figury.Odcinek(pk.XPYP, pk.XNYP));
            fz.Add(new Komputer.Matematyczne.Figury.Odcinek(pk.XNYP, pk.XPYN));
            fz.Add(new Komputer.Matematyczne.Figury.Odcinek(pk.XPYN, pk.XNYN));
            int Wszytkie       = 0;
            int WszystkieBiałe = 0;

            for (int i = 0; i < Rozmiar.Height; i++)
            {
                for (int j = 0; j < Rozmiar.Width; j++, b++, g++)
                {
                    PointF pf = new PointF(j, i);
                    if (fz.OdległośćOdNajbliszego(pf) < MaxOdległość)
                    {
                        Wszytkie++;
                        if (*b)
                        {
                            WszystkieBiałe++;
                        }
                        if (*g)
                        {
                            WszystkieBiałe += WaźnoścNajwiekszy;
                        }
                    }
                }
            }
            return((((float)WszystkieBiałe) / Wszytkie) * SprawdźOceneKątami(pk));
        }