예제 #1
0
        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();
        }
예제 #5
0
        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();
            }
        }