private bool Kollision(Strecke SAB, Strecke SPQ, out Vector ST) { // Matrix erstellen Vector BA = new Vector(SAB.A.X - SAB.B.X, SAB.A.Y - SAB.B.Y); Vector PQ = new Vector(SPQ.B.X - SPQ.A.X, SPQ.B.Y - SPQ.A.Y); Vector PA = new Vector(SAB.A.X - SPQ.A.X, SAB.A.Y - SPQ.A.Y); Matrix M = new Matrix(PQ.X, BA.X, PQ.Y, BA.Y); // Wenn Determinante 0 -> Keine Kollision if (M.Determinante() == 0.0) { ST = new Vector(); return(false); } // Schnittvektor Vector X = M.Invertiert().VektorMult(PA); double s = X.X; double t = X.Y; ST = new Vector(s, t); // Typ double kann zu Ungenauigkeiten führen const double Eps = 1E-12; if ((s < 0.0) || (t <= Eps) || (s > 1.0) || (t >= 1.0 - Eps)) { return(false); } return(true); }
private void CheckCollision() { foreach (UIElement El1 in ZeichenCanvas.Children) { if (!(El1 is Line)) { continue; } Line L1 = (Line)El1; L1.Stroke = Brushes.Black; L1.StrokeThickness = LineThickness; foreach (UIElement El2 in ZeichenCanvas.Children) { if (!(El1 is Line)) { continue; } Line L2 = (Line)El2; Strecke S1 = new Strecke(new Point(L1.X1, L1.Y1), new Point(L1.X2, L1.Y2)); Strecke S2 = new Strecke(new Point(L2.X1, L2.Y1), new Point(L2.X2, L2.Y2)); Vector ST; bool Collides = Kollision(S1, S2, out ST); if (Collides) { L1.Stroke = Brushes.Red; } } if (L1.Stroke != Brushes.Red) { L1.Stroke = Brushes.Green; } } }
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ public void SetzeInnenstrecken() { // Für jedes Hindernis foreach (Hindernis H in Hindernisse) { List <Strecke> _Strecken = new List <Strecke>(); foreach (Point A in H.Eckpunkte) { foreach (Point B in H.Eckpunkte) { // Gleiche Start- & Zielpunkte vermeiden if (A == B) { continue; } // Umgekehrte Strecken ignorieren (A -> B | B -> A) if (_Strecken.FindIndex(X => X.A == B && X.B == A) != -1) { continue; } // Strecke erstellen Strecke S = new Strecke(A, B, H); // Kanten bestimmen S.Kante = H.IstNachbar(A, B); // Strecke hinzufügen _Strecken.Add(S); } } // Strecken für das Hindernis setzen H.Strecken = _Strecken.ToArray(); } }
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ public void SetzeEndstrecken() { List <Strecke> _Strecken = Strecken.ToList(); // Höchsten Endpunkt bestimmen double HoechsterEndpunkt = double.NegativeInfinity; foreach (Strecke S in Strecken) { if (!S.Endstrecke) { continue; } if (S.B.Y >= HoechsterEndpunkt) { HoechsterEndpunkt = S.B.Y; } } // Festen Betrag setzen foreach (Strecke S in Strecken) { if (!S.Endstrecke) { continue; } Endpunkt = new Point(-10, 0); Strecke SEndpunkt = new Strecke(S.B, Endpunkt); SEndpunkt.HatFestenBetrag = true; SEndpunkt.FesterBetrag = (HoechsterEndpunkt - S.B.Y) / 2; _Strecken.Add(SEndpunkt); } Strecken = _Strecken.ToArray(); }
private bool PunktInPolygon(Point Pos) { List <Strecke> Strecken = new List <Strecke>(); foreach (UIElement El in ZeichenCanvas.Children) { if (El is Polygon) { Polygon Poly = (Polygon)El; for (int I = 0; I < Poly.Points.Count - 1; I++) { Point P1 = Poly.Points[I]; Point P2 = Poly.Points[I + 1]; Strecken.Add(new Strecke(P1, P2)); } Strecken.Add(new Strecke(Poly.Points[Poly.Points.Count - 1], Poly.Points[0])); } } const double Laenge = 100000; Random R = new Random(); int Anzahl = 0; // Startpunkt - Epsilon * Vektor von Punkt aus Point X = Pos; Vector Richtung; Richtung = new Vector(1, 0); bool IstGueltig; // Richtung so lange variieren bis sie gültig ist while (true) { IstGueltig = true; foreach (Strecke PQ in Strecken) { Vector VPQ = PQ.B - PQ.A; Vector VQP = PQ.A - PQ.B; // Wenn parallel if (Vector.Determinant(Richtung, VPQ) == 0 || Vector.Determinant(Richtung, VQP) == 0) { IstGueltig = false; break; } } // Abbrechen wenn gültig if (!IstGueltig) { Richtung = new Vector(R.NextDouble(), R.NextDouble()); continue; } else { break; } } Point PEnd = X + Richtung * Laenge; // Strahlstrecke erstellen Strecke Strahl = new Strecke(X, PEnd); TempLine.X1 = X.X; TempLine.Y1 = X.Y; TempLine.X2 = PEnd.X; TempLine.Y2 = PEnd.Y; // Kollision testen foreach (Strecke PQ in Strecken) { Vector ST; if (Kollision(Strahl, PQ, out ST)) { Anzahl++; } } // Wenn die Anzahl and Treffern nicht gerade ist -> im Polygon if (Anzahl % 2 != 0) { TempLine.Stroke = Brushes.Red; TempEllipse.Fill = Brushes.Red; return(true); } else { TempLine.Stroke = Brushes.Green; TempEllipse.Fill = Brushes.Green; return(false); } }
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ public void PunktInPolygon() { // Punkt-in-Polygon-Test nach Jordan const double Epsilon = 0.000001; const double Laenge = 100000; Random R = new Random(); foreach (Hindernis H in Hindernisse) { List <Strecke> _Strecken = H.Strecken.ToList(); foreach (Strecke AB in H.Strecken) { // Kanten sind valide if (AB.Kante) { continue; } int Anzahl = 0; // Startpunkt - Epsilon * Vektor von Punkt aus Point X = AB.A + Epsilon * AB.Vektor(); // Richtung bestimmen Vector Richtung; Vector VAB = AB.Vektor(); Vector VBA = new Vector(VAB.Y, VAB.X); Richtung = new Vector(1, 0); bool IstGueltig; // Richtung so lange variieren bis sie gültig ist while (true) { IstGueltig = true; foreach (Strecke PQ in H.Strecken) { Vector VPQ = PQ.B - PQ.A; Vector VQP = PQ.A - PQ.B; // Wenn parallel if (Vector.Determinant(Richtung, VPQ) == 0 || Vector.Determinant(Richtung, VQP) == 0) { IstGueltig = false; break; } } // Abbrechen wenn gültig if (!IstGueltig) { Richtung = new Vector(R.NextDouble(), R.NextDouble()); continue; } else { break; } } // Strahlstrecke erstellen Strecke Strahl = new Strecke(X, X + Richtung * Laenge); // Kollision testen foreach (Strecke PQ in H.Strecken) { if (!PQ.Kante) { continue; } if (AB == PQ) { continue; } Vector ST; if (Kollision(Strahl, PQ, out ST)) { Anzahl++; } } // Wenn die Anzahl and Treffern nicht gerade ist -> im Polygon if (Anzahl % 2 != 0) { _Strecken.Remove(AB); } } H.Strecken = _Strecken.ToArray(); } }