/// <summary> /// łączy skrzyżowania pewne /// </summary> private void LaczSkrzyzowania() { List <WierzcholekDrogi> skrzyzowania = WierzcholkiDrog.FindAll(o => o.TypWierzcholka == TypWierzcholkaSamochodow.Skrzyzowanie); foreach (WierzcholekDrogi wierzcholek in skrzyzowania) { WierzcholekDrogi wlasciwy = null; foreach (WierzcholekDrogi potencjalny in skrzyzowania) { if (wierzcholek != potencjalny && wierzcholek.Krawedzie.Find(o => o.ZwrocPrzeciwnyWierzcholek(wierzcholek) == potencjalny) == null) { if ((wlasciwy == null || Punkt <double> .Odleglosc(wlasciwy.Pozycja, wierzcholek.Pozycja) > Punkt <double> .Odleglosc(potencjalny.Pozycja, wierzcholek.Pozycja)) && Punkt <double> .ZwrocRelacje(wierzcholek.Pozycja, potencjalny.Pozycja) != Relacja.Brak && !CzyIstniejeWierzcholekPomiedzy(wierzcholek, potencjalny)) { wlasciwy = potencjalny; } } } if (wlasciwy != null) { drogi.Add(KrawedzGrafu.StworzDroge(wlasciwy, wierzcholek)); } } }
/// <summary> /// Przekształca połączenia drogowe na wierzchołki /// </summary> private void ZamienDrogiNaWierzcholki() { List <KrawedzGrafu> tymczasowaLista = drogi.ToList(); foreach (KrawedzGrafu droga in tymczasowaLista) { WierzcholekDrogi pierwszy = (WierzcholekDrogi)droga.WierzcholekA; for (int i = 0; i < droga.DlugoscKrawedzi(); ++i) { Punkt <double> punkt; if (droga.ZwrocRelacje() == Relacja.Pionowe) { punkt = new Punkt <double>(pierwszy.Pozycja.X, pierwszy.Pozycja.Y + 1); } else { punkt = new Punkt <double>(pierwszy.Pozycja.X + 1, pierwszy.Pozycja.Y); } WierzcholekDrogi kolejny = DodajLubZnajdzWierzcholek(punkt, TypWierzcholkaSamochodow.Droga); drogi.Add(KrawedzGrafu.StworzDroge(pierwszy, kolejny)); pierwszy = kolejny; } drogi.Add(KrawedzGrafu.StworzDroge(pierwszy, (WierzcholekDrogi)droga.WierzcholekB)); drogi.Remove(droga.UsunKrawedz()); } }
/// <summary> /// Wyliczanie przejść dla pieszych /// </summary> private void GenerujPrzejsciaPieszych() { List <KrawedzGrafu> drogiTymczasowe = drogi.ToList(); foreach (KrawedzGrafu droga in drogiTymczasowe) { if (droga.DlugoscKrawedzi() > 1) { Punkt <double> punkt; if (droga.ZwrocRelacje() == Relacja.Pionowe) { punkt = new Punkt <double>(droga.WierzcholekA.Pozycja.X, (int)(droga.DlugoscKrawedzi() / 2) + droga.WierzcholekA.Pozycja.Y); } else { punkt = new Punkt <double>((int)(droga.DlugoscKrawedzi() / 2) + droga.WierzcholekA.Pozycja.X, droga.WierzcholekA.Pozycja.Y); } WierzcholekDrogi wierzcholekA = (WierzcholekDrogi)droga.WierzcholekA; WierzcholekDrogi wierzcholekB = (WierzcholekDrogi)droga.WierzcholekB; WierzcholekDrogi dzielacyWierzcholek = new WierzcholekDrogi(punkt, TypWierzcholkaSamochodow.Pasy); WierzcholkiDrog.Add(dzielacyWierzcholek); drogi.Remove(droga.UsunKrawedz()); drogi.Add(KrawedzGrafu.StworzDroge(wierzcholekA, dzielacyWierzcholek)); drogi.Add(KrawedzGrafu.StworzDroge(dzielacyWierzcholek, wierzcholekB)); } } }
private void TworzPolaczeniaKopiowanychTras(Punkt <double> punktA, Punkt <double> punktB) { WierzcholekChodnika wierzcholekA = DodajLubZnajdzWierzcholek(punktA); WierzcholekChodnika wierzcholekB = DodajLubZnajdzWierzcholek(punktB); Chodniki.Add(KrawedzGrafu.StworzDroge(wierzcholekA, wierzcholekB)); }
private void LaczTraseWWierzcholku(KrawedzGrafu trasa, WierzcholekChodnika laczacyWierzcholek) { WierzcholekChodnika wierzcholekA = (WierzcholekChodnika)trasa.WierzcholekA; WierzcholekChodnika wierzcholekB = (WierzcholekChodnika)trasa.WierzcholekB; Chodniki.Remove(trasa.UsunKrawedz()); Chodniki.Add(KrawedzGrafu.StworzDroge(wierzcholekA, laczacyWierzcholek)); Chodniki.Add(KrawedzGrafu.StworzDroge(laczacyWierzcholek, wierzcholekB)); }
public static KrawedzGrafu StworzDroge(WierzcholekGrafu wierzcholekA, WierzcholekGrafu wierzcholekB) { KrawedzGrafu nowaDroga = new KrawedzGrafu(wierzcholekA, wierzcholekB); wierzcholekA.Krawedzie.Add(nowaDroga); wierzcholekB.Krawedzie.Add(nowaDroga); return(nowaDroga); }
/// <summary> /// Wyznacza połączenia które są pewnikiem i są podstawą między innymi połączeniami /// </summary> private void GenerujPoloczeniaKonieczne() { Punkt <double> punktGorny = new Punkt <double>(0, rozmiarMapyY / 2); Punkt <double> punktDolny = new Punkt <double>(0, rozmiarMapyY / 2); Punkt <double> punktLewy = new Punkt <double>(rozmiarMapyX / 2, 0); Punkt <double> punktPrawy = new Punkt <double>(rozmiarMapyX / 2, 0); foreach (WierzcholekDrogi wierzcholek in WierzcholkiDrog) { if (wierzcholek.Pozycja.Y < punktGorny.Y && wierzcholek.Pozycja.Y != GRANICA_GORNA) { punktGorny = wierzcholek.Pozycja; } if (wierzcholek.Pozycja.Y > punktDolny.Y && wierzcholek.Pozycja.Y != GRANICA_DOLNA) { punktDolny = wierzcholek.Pozycja; } if (wierzcholek.Pozycja.X > punktPrawy.X && wierzcholek.Pozycja.X != GRANICA_PRAWA) { punktPrawy = wierzcholek.Pozycja; } if (wierzcholek.Pozycja.X < punktLewy.X && wierzcholek.Pozycja.X != GRANICA_LEWA) { punktLewy = wierzcholek.Pozycja; } } List <WierzcholekDrogi> punktyWejscia = WierzcholkiDrog.ToList(); foreach (WierzcholekDrogi wierzcholek in punktyWejscia) { Punkt <double> punktPrzeciecia = new Punkt <double>(0, 0); if (wierzcholek.Pozycja.Y == GRANICA_GORNA) // Góra { punktPrzeciecia = new Punkt <double>(wierzcholek.Pozycja.X, punktGorny.Y); } else if (wierzcholek.Pozycja.X == GRANICA_PRAWA) // Prawa { punktPrzeciecia = new Punkt <double>(punktPrawy.X, wierzcholek.Pozycja.Y); } else if (wierzcholek.Pozycja.Y == GRANICA_DOLNA) // Dół { punktPrzeciecia = new Punkt <double>(wierzcholek.Pozycja.X, punktDolny.Y); } else if (wierzcholek.Pozycja.X == GRANICA_LEWA) // Lewa { punktPrzeciecia = new Punkt <double>(punktLewy.X, wierzcholek.Pozycja.Y); } WierzcholekDrogi nowyWierzcholek = DodajLubZnajdzWierzcholek(punktPrzeciecia); drogi.Add(KrawedzGrafu.StworzDroge(nowyWierzcholek, wierzcholek)); } }
private WierzcholekChodnika DzielTraseWPunkcie(KrawedzGrafu trasa, Punkt <double> punkt) { WierzcholekChodnika wierzcholekA = (WierzcholekChodnika)trasa.WierzcholekA; WierzcholekChodnika wierzcholekB = (WierzcholekChodnika)trasa.WierzcholekB; WierzcholekChodnika dzielacyWierzcholek = new WierzcholekChodnika(punkt, TypWierzcholkaPieszych.ChodnikDrogi); WierzcholkiChodnikow.Add(dzielacyWierzcholek); Chodniki.Remove(trasa.UsunKrawedz()); Chodniki.Add(KrawedzGrafu.StworzDroge(wierzcholekA, dzielacyWierzcholek)); Chodniki.Add(KrawedzGrafu.StworzDroge(dzielacyWierzcholek, wierzcholekB)); return(dzielacyWierzcholek); }
private void ProbujLaczycChodnik(Punkt <double> punkt, WierzcholekChodnika wierzcholek) { WierzcholekChodnika szukanyWierzcholek = WierzcholkiChodnikow.Find(o => o.Pozycja.Equals(punkt)); if (szukanyWierzcholek != null) { Chodniki.Add(KrawedzGrafu.StworzDroge(wierzcholek, szukanyWierzcholek)); } else { KrawedzGrafu szukanaKrawedz = SzukajDrogiPomiedzyPunktem(punkt); if (szukanaKrawedz != null) { szukanyWierzcholek = DzielTraseWPunkcie(szukanaKrawedz, punkt); Chodniki.Add(KrawedzGrafu.StworzDroge(szukanyWierzcholek, wierzcholek)); } } }
/// <summary> /// Usówa ślepe połączenia, usówa nadmiarowe skrzyżowania, tworzy zakręty /// </summary> private void RedukujPolaczenia() { for (int i = 0; i < WierzcholkiDrog.Count; ++i) { WierzcholekDrogi wierzcholek = WierzcholkiDrog[i]; if (wierzcholek.TypWierzcholka == TypWierzcholkaSamochodow.Skrzyzowanie) { if (wierzcholek.Krawedzie.Count == 1) { for (int j = wierzcholek.Krawedzie.Count - 1; j >= 0; --j) { drogi.Remove(wierzcholek.Krawedzie[j].UsunKrawedz()); } WierzcholkiDrog.Remove(wierzcholek); } else if (wierzcholek.Krawedzie.Count == 2) { if (Punkt <double> .ZwrocRelacje(wierzcholek.Krawedzie[0].ZwrocPrzeciwnyWierzcholek(wierzcholek).Pozycja, wierzcholek.Krawedzie[1].ZwrocPrzeciwnyWierzcholek(wierzcholek).Pozycja) == Relacja.Brak) { wierzcholek.TypWierzcholka = TypWierzcholkaSamochodow.Zakret; } else { drogi.Add(KrawedzGrafu.StworzDroge(wierzcholek.Krawedzie[1].ZwrocPrzeciwnyWierzcholek(wierzcholek), wierzcholek.Krawedzie[0].ZwrocPrzeciwnyWierzcholek(wierzcholek))); for (int j = wierzcholek.Krawedzie.Count - 1; j >= 0; --j) { drogi.Remove(wierzcholek.Krawedzie[j].UsunKrawedz() as KrawedzGrafu); } WierzcholkiDrog.Remove(wierzcholek); } } } else if (wierzcholek.TypWierzcholka == TypWierzcholkaSamochodow.PunktWejscia) { if (wierzcholek.Krawedzie.Count == 0) { WierzcholkiDrog.Remove(wierzcholek); } } } }
/// <summary> /// Usówa nadmiarowe skrzyżowania /// </summary> private void RedukujPolaczenia() { foreach (WierzcholekChodnika wierzcholek in WierzcholkiChodnikow) { if (wierzcholek.CzyJestDrogaWLewo() && wierzcholek.CzyJestDrogaWPrawo()) { if (!(wierzcholek.CzyJestDrogaWDol() || wierzcholek.CzyJestDrogaWGore())) { WierzcholekChodnika wierzcholekA = (WierzcholekChodnika)wierzcholek.ZwrocKrawedzLewa().ZwrocPrzeciwnyWierzcholek(wierzcholek); WierzcholekChodnika wierzcholekB = (WierzcholekChodnika)wierzcholek.ZwrocKrawedzPrawa().ZwrocPrzeciwnyWierzcholek(wierzcholek); Chodniki.Remove(wierzcholek.ZwrocKrawedzLewa().UsunKrawedz()); Chodniki.Remove(wierzcholek.ZwrocKrawedzPrawa().UsunKrawedz()); Chodniki.Add(KrawedzGrafu.StworzDroge(wierzcholekA, wierzcholekB)); } } if (wierzcholek.CzyJestDrogaWDol() && wierzcholek.CzyJestDrogaWGore()) { if (!(wierzcholek.CzyJestDrogaWLewo() || wierzcholek.CzyJestDrogaWPrawo())) { WierzcholekChodnika wierzcholekA = (WierzcholekChodnika)wierzcholek.ZwrocKrawedzGorna().ZwrocPrzeciwnyWierzcholek(wierzcholek); WierzcholekChodnika wierzcholekB = (WierzcholekChodnika)wierzcholek.ZwrocKrawedzDolna().ZwrocPrzeciwnyWierzcholek(wierzcholek); Chodniki.Remove(wierzcholek.ZwrocKrawedzGorna().UsunKrawedz()); Chodniki.Remove(wierzcholek.ZwrocKrawedzDolna().UsunKrawedz()); Chodniki.Add(KrawedzGrafu.StworzDroge(wierzcholekA, wierzcholekB)); } } } for (int i = WierzcholkiChodnikow.Count - 1; i >= 0; --i) { if (WierzcholkiChodnikow[i].Krawedzie.Count == 0) { WierzcholkiChodnikow.Remove(WierzcholkiChodnikow[i]); } } }
private void BudujChodnik(Punkt <double> punktA, Punkt <double> punktB) { WierzcholekChodnika wierzcholekA; if (punktA.X == 0) { wierzcholekA = new WierzcholekChodnika(new Punkt <double>(punktA.X - 0.5, punktA.Y), TypWierzcholkaPieszych.PunktWejscia); } else if (punktA.Y == 0) { wierzcholekA = new WierzcholekChodnika(new Punkt <double>(punktA.X, punktA.Y - 0.5), TypWierzcholkaPieszych.PunktWejscia); } else { wierzcholekA = new WierzcholekChodnika(punktA, TypWierzcholkaPieszych.ChodnikPrzestrzeni); } WierzcholekChodnika wierzcholekB; if (punktB.X == rozmiarMapyX - 1) { wierzcholekB = new WierzcholekChodnika(new Punkt <double>(punktB.X + 0.5, punktB.Y), TypWierzcholkaPieszych.PunktWejscia); } else if (punktB.Y == rozmiarMapyY - 1) { wierzcholekB = new WierzcholekChodnika(new Punkt <double>(punktB.X, punktB.Y + 0.5), TypWierzcholkaPieszych.PunktWejscia); } else { wierzcholekB = new WierzcholekChodnika(punktB, TypWierzcholkaPieszych.ChodnikPrzestrzeni); } WierzcholkiChodnikow.Add(wierzcholekA); WierzcholkiChodnikow.Add(wierzcholekB); Chodniki.Add(KrawedzGrafu.StworzDroge(wierzcholekA, wierzcholekB)); ZaznaczNaMapie <TypPrzestrzeni>(Mapa, new Prostokat((Punkt <int>)punktA, (Punkt <int>)punktB), TypPrzestrzeni.Chodnik); }
/// <summary> /// Odwzorowuje chodniki z połączeń drogowych /// </summary> private void OdwzorujChodnikiZDrog(GeneratorPolaczenSamochodow generatorPolaczen) { foreach (WierzcholekDrogi wierzcholek in generatorPolaczen.WierzcholkiDrog) { if (!wierzcholek.CzyJestDrogaWGore() && !(wierzcholek.TypWierzcholka == TypWierzcholkaSamochodow.PunktWejscia && !wierzcholek.CzyJestDrogaWGore())) { TworzPolaczeniaKopiowanychTras(new Punkt <double>(wierzcholek.Pozycja.X * 2 - 0.5, wierzcholek.Pozycja.Y * 2 - 0.5), new Punkt <double>(wierzcholek.Pozycja.X * 2 + 1.5, wierzcholek.Pozycja.Y * 2 - 0.5)); } if (!wierzcholek.CzyJestDrogaWDol() && !(wierzcholek.TypWierzcholka == TypWierzcholkaSamochodow.PunktWejscia && !wierzcholek.CzyJestDrogaWDol())) { TworzPolaczeniaKopiowanychTras(new Punkt <double>(wierzcholek.Pozycja.X * 2 - 0.5, wierzcholek.Pozycja.Y * 2 + 1.5), new Punkt <double>(wierzcholek.Pozycja.X * 2 + 1.5, wierzcholek.Pozycja.Y * 2 + 1.5)); } if (!wierzcholek.CzyJestDrogaWLewo() && !(wierzcholek.TypWierzcholka == TypWierzcholkaSamochodow.PunktWejscia && !wierzcholek.CzyJestDrogaWLewo())) { TworzPolaczeniaKopiowanychTras(new Punkt <double>(wierzcholek.Pozycja.X * 2 - 0.5, wierzcholek.Pozycja.Y * 2 - 0.5), new Punkt <double>(wierzcholek.Pozycja.X * 2 - 0.5, wierzcholek.Pozycja.Y * 2 + 1.5)); } if (!wierzcholek.CzyJestDrogaWPrawo() && !(wierzcholek.TypWierzcholka == TypWierzcholkaSamochodow.PunktWejscia && !wierzcholek.CzyJestDrogaWPrawo())) { TworzPolaczeniaKopiowanychTras(new Punkt <double>(wierzcholek.Pozycja.X * 2 + 1.5, wierzcholek.Pozycja.Y * 2 - 0.5), new Punkt <double>(wierzcholek.Pozycja.X * 2 + 1.5, wierzcholek.Pozycja.Y * 2 + 1.5)); } if (wierzcholek.TypWierzcholka == TypWierzcholkaSamochodow.Pasy) { WierzcholekChodnika wierzcholekA = null; WierzcholekChodnika wierzcholekB = null; if (wierzcholek.CzyJestDrogaWDol() && wierzcholek.CzyJestDrogaWGore()) { wierzcholekA = DodajLubZnajdzWierzcholek(new Punkt <double>(wierzcholek.Pozycja.X * 2 - 0.5, wierzcholek.Pozycja.Y * 2 + 0.5)); wierzcholekB = DodajLubZnajdzWierzcholek(new Punkt <double>(wierzcholek.Pozycja.X * 2 + 1.5, wierzcholek.Pozycja.Y * 2 + 0.5)); wierzcholekA.UstawObiektWejscia(((WejscieNaPasy)wierzcholek.ObiektDrogi).PrzejscieDlaPieszych, wierzcholekB); wierzcholekB.UstawObiektWejscia(((WejscieNaPasy)wierzcholek.ObiektDrogi).PrzejscieDlaPieszych, wierzcholekA); } else if (wierzcholek.CzyJestDrogaWPrawo() && wierzcholek.CzyJestDrogaWLewo()) { wierzcholekA = DodajLubZnajdzWierzcholek(new Punkt <double>(wierzcholek.Pozycja.X * 2 + 0.5, wierzcholek.Pozycja.Y * 2 - 0.5)); wierzcholekB = DodajLubZnajdzWierzcholek(new Punkt <double>(wierzcholek.Pozycja.X * 2 + 0.5, wierzcholek.Pozycja.Y * 2 + 1.5)); wierzcholekA.UstawObiektWejscia(((WejscieNaPasy)wierzcholek.ObiektDrogi).PrzejscieDlaPieszych, wierzcholekB); wierzcholekB.UstawObiektWejscia(((WejscieNaPasy)wierzcholek.ObiektDrogi).PrzejscieDlaPieszych, wierzcholekA); } wierzcholekA.TypWierzcholka = TypWierzcholkaPieszych.Pasy; wierzcholekB.TypWierzcholka = TypWierzcholkaPieszych.Pasy; KrawedzGrafu krawedzA = SzukajDrogiPomiedzyPunktem(wierzcholekA.Pozycja); LaczTraseWWierzcholku(krawedzA, wierzcholekA); KrawedzGrafu krawedzB = SzukajDrogiPomiedzyPunktem(wierzcholekB.Pozycja); LaczTraseWWierzcholku(krawedzB, wierzcholekB); Chodniki.Add(KrawedzGrafu.StworzDroge(wierzcholekA, wierzcholekB)); } } }