Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

21

29.04.2016, 10:15

Nun, in dem Fall: Polygone in Dreiecke zerlegen und deren Flächen aufsummieren... ;)

Garzec

Alter Hase

  • »Garzec« ist der Autor dieses Themas

Beiträge: 693

Wohnort: Gießen

  • Private Nachricht senden

22

29.04.2016, 11:07

Joa da bin ich grad dran :thumbsup:

Garzec

Alter Hase

  • »Garzec« ist der Autor dieses Themas

Beiträge: 693

Wohnort: Gießen

  • Private Nachricht senden

23

29.04.2016, 12:48

Ich lasse mir die Schnittpunkte ausgeben, und unterscheide dabei auch zwischen den Eckpunkten. Dabei wollte ich mal fragen ob meine Berechnung zu senkrechten Geraden überhaupt richtig ist, oder aufgrund des Einsetzungsverfahrens immer aufgeht. In seltenen Fällen baut sich das Polygon nämlich so auf, dass er versucht durch 0 zu teilen, und da krachts natürlich ;)

Meine Berechnung:

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/// ------------------------------------------------------------------------------------------------------------------------
        /// <summary>
        /// Berechnet die Schnittpunkte
        /// </summary>
        private void BerechneSchnittpunkte()
        {
            for (int i = 0; i < 5; i++)
            {
                for (int j = i + 1; j < 5; j++)
                {
                    BerechneSchnittpunkte(i, j);
                }
            }
        }

        /// ------------------------------------------------------------------------------------------------------------------------
        /// <summary>
        /// Berechnet die Schnittpunkte
        /// </summary>
        /// <param name="start1"></param>
        /// <param name="start2"></param>
        private void BerechneSchnittpunkte(int startIndex1, int startIndex2)
        {
            int endeIndex1 = startIndex1 + 1;
            int endeIndex2 = startIndex2 + 1;

            Point start1 = punktListe[startIndex1];
            Point ende1 = punktListe[endeIndex1];
            Point start2 = punktListe[startIndex2];
            Point ende2 = punktListe[endeIndex2];

            Color farbe1 = farbenListe[startIndex1];
            Color farbe2 = farbenListe[startIndex2];

            int dx1 = ende1.X - start1.X;
            int dy1 = ende1.Y - start1.Y;
            int dx2 = ende2.X - start2.X;
            int dy2 = ende2.Y - start2.Y;

            double m1 = 1F * dy1 / dx1;
            double m2 = 1F * dy2 / dx2;

            int b1 = Round(start1.Y - start1.X * m1);
            int b2 = Round(start2.Y - start2.X * m2);

            // m1*x + b1 = m2*x + b2 -> schnittpunktX = (b1-b2) / (m2-m1) -> schnittpunktY = m1 * schnittpunktX + b1
            if (m2 != m1)
            {
                int schnittpunktX = Round(1F * (b1 - b2) / (m2 - m1));
                int schnittpunktY = Round(1F * (m1 * schnittpunktX + b1));

                Point schnittpunkt = new Point(schnittpunktX, schnittpunktY);

                Console.WriteLine("Strecke: " + farbe1 + "Strecke: " + farbe2);    //------- TEST

                Console.WriteLine("Schnittpunkt " + "{Xs: " + schnittpunktX + "} {Ys: " + schnittpunktY + "}");    //------- TEST

                Rectangle rect1 = BaueRechteck(start1.X, start1.Y, dx1, dy1);
                Rectangle rect2 = BaueRechteck(start2.X, start2.Y, dx2, dy2);

                if (rect1.Contains(schnittpunktX, schnittpunktY) && rect2.Contains(schnittpunktX, schnittpunktY))
                {
                    if (schnittpunkt != start1 && schnittpunkt != start2 && schnittpunkt != ende1 && schnittpunkt != ende2)
                    {
                        Console.WriteLine("--Schnittpunkt--");    //------- TEST
                    }
                    else
                    {
                        Console.WriteLine("--Eckpunkt--");    //------- TEST
                    }
                }
                else
                {
                    Console.WriteLine("--außerhalb--");    //------- TEST
                }
            }
            else
            {
                // m1 == m2
                if (b1 == b2)
                {
                    Console.WriteLine("aufeinander ");    //------- TEST
                }
                else
                {
                    Console.WriteLine("0 SP ");    //------- TEST
                }
            }
            Console.WriteLine("******************************************************");    //------- TEST
        }


Ich lasse mir erstmal nur in der Konsole ausgeben, ob ich Schnittpunkte habe und unterteile diese dann in Eckpunkte und Schnittpunkte.

Dabei benutze ich:

C#-Quelltext

1
2
int schnittpunktX = Round(1F * (b1 - b2) / (m2 - m1));
int schnittpunktY = Round(1F * (m1 * schnittpunktX + b1));


Kann da der Fehler stecken?

Garzec

Alter Hase

  • »Garzec« ist der Autor dieses Themas

Beiträge: 693

Wohnort: Gießen

  • Private Nachricht senden

24

29.04.2016, 13:06

Habe mir zusätlich noch einen kleinen Test geschrieben der den Fehler gut herführt.

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/// ------------------------------------------------------------------------------------------------------------------------
        /// <summary>
        /// Testroutine
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnTest_Click(object sender, EventArgs e)
        {
            ErstelleTestPunkte(new Point[] { new Point( 34, 200 ), new Point(34, 458), new Point(525, 64), new Point(752, 84), new Point(957, 100) });
            panelZeichenFlaeche.Invalidate();
            AktualisiereLabels();
            BerechneSchnittpunkte();
        }

        /// ------------------------------------------------------------------------------------------------------------------------
        /// <summary>
        /// Erstellt die Punkte
        /// </summary>
        /// <param name="minimum"></param>
        /// <param name="maximum"></param>
        /// <returns></returns>
        private void ErstelleTestPunkte(Point[] points)
        {
            punktListe.Clear();
            for (int i = 0; i < 5; i++)
            {

                Point punkt = points[i];
                punktListe.Add(punkt);
            }
            punktListe.Add(punktListe.First());
        }


Krachen tuts dann beim Runden, d ist NaN

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/// ------------------------------------------------------------------------------------------------------------------------
        /// <summary>
        /// Rundet double-Werte
        /// </summary>
        /// <param name="d"></param>
        /// <returns></returns>
        private int Round(double d)
        {
            if (double.IsPositiveInfinity(d))
                return int.MaxValue;
            if (double.IsNegativeInfinity(d))
                return int.MinValue;
            return Convert.ToInt32(Math.Round(d, MidpointRounding.AwayFromZero));
        }

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

25

29.04.2016, 13:31

Die §y = mx + b§ Form ist in der Regel nicht die Form mit der man in der Praxis arbeiten will, da sie eben beispielsweise für senkrechte Geraden nicht funktioniert. Es ist meist besser mit der bereits erwähnten Parameterdarstellung oder der impliziten Form (§ax + by + c = 0§) zu arbeiten.

Garzec

Alter Hase

  • »Garzec« ist der Autor dieses Themas

Beiträge: 693

Wohnort: Gießen

  • Private Nachricht senden

26

29.04.2016, 15:10

Ich habe meine Berechnung jetzt umgebaut, wie CeDoMain es schon vorgegeben hat. Als Versuch nutze ich meine oben genannte "Testroutine". Seine Berechnung habe ich jetzt so umgesetzt:

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
 private void SchnittpunktBerechnung(int startIndex1, int startIndex2)
        {
            //Strecke AB = Punkt1 + s * (Punkt2 - Punkt1)
            //Strecke CD = Punkt3 + t * (Punkt4 - Punkt3)

            int endeIndex1 = startIndex1 + 1;
            int endeIndex2 = startIndex2 + 1;

            Point start1 = punktListe[startIndex1];
            Point ende1 = punktListe[endeIndex1];
            Point start2 = punktListe[startIndex2];
            Point ende2 = punktListe[endeIndex2];

            Color farbe1 = farbenListe[startIndex1];
            Color farbe2 = farbenListe[startIndex2];

            // Punkte

            int x1 = start1.X;      //Punkt1 X
            int x2 = ende1.X;       //Punkt2 X
            int x3 = start2.X;      //Punkt3 X
            int x4 = ende2.X;       //Punkt4 X

            int y1 = start1.Y;      //Punkt1 Y
            int y2 = ende1.Y;       //Punkt2 Y
            int y3 = start2.Y;      //Punkt3 Y
            int y4 = ende2.Y;       //Punkt4 Y

            // Konstanten

            int mx = x2 - x1;
            int nx = x4 - x3;
            int ox = x3 - x1;

            int my = y2 - y1;
            int ny = y4 - y3;
            int oy = y3 - y1;

            // Determinanten

            int d1 = mx * ny - my * nx;
            int d2 = ox * ny - oy * nx;
            int d3 = mx * oy - my * ox;

            // Fallunterscheidung

            if (d1 == d2 && d1 == d3 && d1 == 0)
            {
                Console.WriteLine("Strecken liegen aufeinander");    //------- TEST
            }
            else if (d1 == 0 && d2 != 0 && d3 != 0)
            {
                Console.WriteLine("kein Schnittpunkt");    //------- TEST
            }
            else if (d1 != 0)
            {
                Console.WriteLine("Schnittpunkt");    //------- TEST
            }

            // s und t

            int s = d2 / d1;
            int t = d3 / d1;

            // Überprüfung s und t

            Console.WriteLine("Strecke: " + farbe1 + "Strecke: " + farbe2);    //------- TEST

            if (s > 0 && s < 1 && t > 0 && t < 1)
            {
                Console.WriteLine("Schnittpunkt auf den Strecken");    //------- TEST
            }
            else
            {
                Console.WriteLine("Schnittpunkt auf den Geraden aber nicht auf den Strecken");    //------- TEST
            }

            // Schnittpunktberechnung

            int sx = x1 + s * (x2 - x1);
            int sy = y1 + s * (y2 - y1);

            // Schnittpunkt

            Point schnittPunkt = new Point(sx,sy);

            Console.WriteLine(schnittPunkt);    //------- TEST

            Console.WriteLine("************************************************************");    //------- TEST
        }


Dennoch erkennt er jetzt den für den Test eingebauten Schnittpunkt nicht mehr :S

Das Ganze sieht momentan so aus:

http://imgur.com/CIeZyFY

Der Schnittpunkt bei Gelb/Grün sollte auf der Strecke liegen

Edit: habe den Fehler schon selber behoben, das Intervall muss ja >= und nicht > etc. sein :dash: sorry

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Garzec« (29.04.2016, 15:19)


Garzec

Alter Hase

  • »Garzec« ist der Autor dieses Themas

Beiträge: 693

Wohnort: Gießen

  • Private Nachricht senden

27

29.04.2016, 15:59

@CeDoMain

Ich gehe davon aus, dass deine Berechnung richtig ist, bei meinem Test wird t aber negativ, daher die Frage nach dem Intervall. Reicht die Abfrage

s >= 0 && s <= 1 && t >= 0 && t <= 1

aus oder werden noch Sonderfälle/Maximalwerte/... benötigt? Weil bei mir erkennt er dann die Schnittpunkte nicht richtig, wenn t negativ wird, was ja an vielen Stellen Möglichkeiten bietet.

CeDoMain

Alter Hase

Beiträge: 587

Wohnort: Ilmenau

Beruf: Student für Mechatronik

  • Private Nachricht senden

28

30.04.2016, 00:06

Liegt denn der Betrag von t im Intervall [0;1], wenn der Punkt auf der Strecke ist? Und ist außerhalb wenn er nicht auf beiden Strecken liegt? Ich vermute, dass das mit der Reihenfolge zusammenhängt, in der die Verbindungsvektoren berechnet werden. Also A-B oder B-A - ich prüfe das mal nach.

Ansonsten gute Neuigkeiten: Gestern Nacht (im Bett fallen mir immer schlaue Dinge ein ;) ) habe ich mir den Algorithmus fertig überlegt, wie man die Fläche für jedes beliebige Vieleck berechnet. Ich schreib das morgen mal auf und dann kannst du damit weitermachen. :)

EDIT: Fast vergessen: Nein, die Prüfung für das Intervall reicht definitv. Probier das mit dem Betrag mal aus, ansonsten wird aber keine andere Prüfung benötigt.
Mit freundlichem Gruß
CeDo
Discord: #6996 | Skype: cedomain

Lass solche persönlichen Angriffe lieber bleiben, meine sind härter.

CeDoMain

Alter Hase

Beiträge: 587

Wohnort: Ilmenau

Beruf: Student für Mechatronik

  • Private Nachricht senden

29

30.04.2016, 00:18

Habe meinen Fehler gefunden! Sorry. Der Übergang von Herleitung zu meiner LGS-Löserei hat einen Fehler. Oben steht ja:
§s(B_x-A_x)-t(D_x-C_x)=C_x-A_x§
§s(B_y-A_y)-t(D_y-C_y)=C_y-A_y§

Damit man das 1:1 in ein LGS packen kann (wie ich das gemacht hab), muss vor dem t ein + stehen:
§s(B_x-A_x)+t(C_x-D_x)=C_x-A_x§
§s(B_y-A_y)+t(C_y-D_y)=C_y-A_y§

Das ist äquivalent zu dem oberen, aber jetzt müssen §n_x§ und §n_y§ anders definiert werden:
§n_x=C_x-D_x§
§n_y=C_y-D_y§

Wenn du die beiden Zeilen in deinem Programm abänderst (C und D vertauschen), dann müsste es funktionieren. :)
Mit freundlichem Gruß
CeDo
Discord: #6996 | Skype: cedomain

Lass solche persönlichen Angriffe lieber bleiben, meine sind härter.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »CeDoMain« (02.05.2016, 17:56) aus folgendem Grund: Fehler entfernt (o mit n vertauscht)


Garzec

Alter Hase

  • »Garzec« ist der Autor dieses Themas

Beiträge: 693

Wohnort: Gießen

  • Private Nachricht senden

30

02.05.2016, 08:01

Habe jetzt folgendes geändert:

C#-Quelltext

1
2
3
4
5
6
7
            int mx = x2 - x1;
            int nx = x3 - x4; // x4-x3
            int ox = x3 - x4; //x3 - x1;

            int my = y2 - y1;
            int ny = y3 - y4; // y4-y3
            int oy = y3 - y4; //y3 - y1;


x1-x4 sind die Punkte Ax-Dx und y1-y4 sind die Punkte Ay-Dy. Auskommentiert sind die ursprünglichen Rechnungen. Bei mir passt es aber leider noch nicht richtig, jeder Punkt sei jetzt ein Schnittpunkt auf den Strecken der Geraden. ?(

Oder hab ich nur was falsch abgeändert?

Zumindest erkennt er jetzt jeden Eckpunkt durch die Abfrage

C#-Quelltext

1
(s >= 0 && s <= 1 && t >= 0 && t <= 1)


schon als Schnittpunkt der Strecke. Und die Eckpunkte sollen ja nicht dazugehören.

Durch einen Test ergab sich, dass alle Punkte dadurch s = 0 haben und t = 1 haben. Da hab ich wohl noch was falsches in der Berechnung.

Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »Garzec« (02.05.2016, 08:18)


Werbeanzeige