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

devix360

Frischling

  • »devix360« ist der Autor dieses Themas

Beiträge: 6

Wohnort: Lünen

Beruf: Student

  • Private Nachricht senden

1

12.01.2012, 15:07

Frage zur Lösung der Übungsaufgabe 3 aus Kapitel 2.2.8

Hallo,

ich habe eben die Aufgabe 3 aus dem Kapitel 2.28 bearbeitet.

Die Aufgabenstellung ist 5000 beliebige Positionsvektoren zu erzeugen, 3 Zufällige aus disen 5000 zu wählen und eine Ebene zu generieren, die durch die 3 Punkte läuft.
Dann geht es darum zu zählen wie viele der 5000 Positionsvektoren sich vor, hinter und auf der Ebene befinden.


Jetzt zu meiner Lösung.
Ich zähle, wie viele Punkte sich vor, hinter und auf der Ebene befinden und lasse dies in einer Log Datei ausgeben.
Bei mir werden auch alle Punkte die vor der Ebene sind gezählt und auch alle die sich hinter der Ebene befinden.
In der Summe ergibt das auch immer 5000.
Jedoch sollen auch die Punkte gezählt werden, die sich genau auf der Ebene befinden (was ja mindestens die 3 sein müssen, durch denen sich die Ebene streck).
Doch hier bleibt das Ergebnis immer 0 (Zeile 61).

Hier mal mein Quelltext:

C-/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
#include <iostream>
#include <TriBase.h>

using namespace std;

int main()
{
    tbInit();

    const int anzahl = 5000;
    tbVector3* posVector = new tbVector3[anzahl];   //5000 Positionsvektoren.
    tbVector3* ranVector = new tbVector3[3];        //3 Zufällige aus den 5000 Vektoren.

    //5000 zufällige Positionsvektoren erstellen.
    for(int i=0; i<anzahl; i++)
    {
        posVector[i] = tbVector3Random();
    }

    TB_INFO("5000 Zufallsvektoren wurden erstellt!");

    //3 zufällige Vektoren auswählen.
    for(int j=0; j<3; j++)
    {
        ranVector[j] = posVector[tbIntRandom(0, anzahl)];
    }

    TB_INFO("3 aus 5000 zufälligen Vektoren wurden ausgewählt!");

    //Ebene aus den 3 Punkten der Zufallsvektoren erstellen und Ebene normalisieren.
    tbPlane plane(tbPlaneFromPoints(ranVector[0], ranVector[1], ranVector[2]));

    TB_INFO("Ebene aus 3 zufälligen Vektoren wurde erstellt!");

    //Die 3 Zufallsvektoren und Ebene ins Log schreiben.
    for(int k=0; k<3; k++)
    {
        tbWriteVector3ToLog(ranVector[k]);
    }
    tbWritePlaneToLog(plane);   //Ebene ins Log schreiben.


    //Zählen wie viele der 5000 Vektoren/Punkte sich vor, hinter oder auf der Ebene befinden.
    //
    int countF = 0, countB = 0, countO = 0; //Zähler für Punkte vor (Front), hinter (Back) und auf (On) der Ebene.

    for(int l=0; l<anzahl; l++)
    {
        //Vektor zur Sicherheit normalisieren.
        //posVector[l] = tbVector3Normalize(posVector[l]);

        //Punkt auf der Vorderseite?
        if(tbPlaneDotCoords(plane, posVector[l]) > 0)
        {
            countF++;
        }
        
        //Punkt auf der Rückseite?
        if(tbPlaneDotCoords(plane, posVector[l]) < 0)
        {
            countB++;
        }

        //Punkt genau auf der Ebene
        if(tbPlaneDotCoords(plane, posVector[l]) == 0)
        {
            countO++;
        }       
    }

    tbWriteToLog("%d Vektoren befinden sich vor der Ebene", countF);
    tbWriteToLog("%d Vektoren befinden sich hinter der Ebene", countB);
    tbWriteToLog("%d Vektoren befinden sich auf der Ebene", countO);

    tbExit();
    return 0;
}


Eintrag im Log sieht dann etwa immer so aus:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
(...)
INFO: Initialisierung komplett!(tribase.cpp, Zeile 104, Funktion tbInit)
INFO: 5000 Zufallsvektoren wurden erstellt!(hauptprogramm.cpp, Zeile 20, Funktion main)
INFO: 3 aus 5000 zufälligen Vektoren wurden ausgewählt!(hauptprogramm.cpp, Zeile 28, Funktion main)
INFO: Ebene aus 3 zufälligen Vektoren wurde erstellt!(hauptprogramm.cpp, Zeile 34, Funktion main)
3D-Vektor: x = 0.723, y = -0.636, z = 0.269, Länge = 1.000
3D-Vektor: x = -0.276, y = 0.559, z = -0.782, Länge = 1.000
3D-Vektor: x = 0.213, y = -0.623, z = 0.753, Länge = 1.000
Ebene: a = 0.592, b = 1.018, c = 0.595, d = 0.060, Normalenvektorlänge = 1.320
2297 Vektoren befinden sich vor der Ebene
2703 Vektoren befinden sich hinter der Ebene
0 Vektoren befinden sich auf der Ebene
INFO: TriBase-Engine wird heruntergefahren...(tribase.cpp, Zeile 113, Funktion tbExit)
(...)


Wäre nett wenn sich das mal jemand angucken könnte und mir weiter hilft.
Auch vorschläge zur Optimierung des Quelltextes sind gewünscht, da ich noch nich so lange mit C++ unterwegs bin und bereit bin zu lernen.

Danke im Voraus :)

Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von »devix360« (12.01.2012, 15:24)


2

22.01.2012, 19:27

Es scheint einen kleinen Rundungsfehler in der TriBase-Engine zu geben.
folgender Code sollte funktionieren (ich hab dir die Stellen mit Kommentaren markiert!)

C-/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
#include <TriBase.h>

const int NUM_VEC = 5000;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   LPSTR CmdLine, int CmdShow)
{
    tbInit();

    tbVector3 Vektor[NUM_VEC]; // Anzahl an Vektoren erzeugen
    tbVector3 VektorRan[3];

    srand(timeGetTime());   // Zufallsgenerator

    for(int i = 0; i < NUM_VEC; i++)
    {
        Vektor[i].x = tbFloatRandom(-10, 10);
        Vektor[i].y = tbFloatRandom(-10, 10);
        Vektor[i].z = tbFloatRandom(-10, 10);
        Vektor[i] = tbVector3Normalize(Vektor[i]);
    }
    for(int i = 0; i < 3; i++)
    {
        VektorRan[i] = Vektor[rand() % NUM_VEC];
        tbWriteVector3ToLog(VektorRan[i]);
    }

    tbPlane Ebene = tbPlaneFromPoints(VektorRan[0], VektorRan[1], VektorRan[2]);
    Ebene = tbPlaneNormalize(Ebene);
    
    tbWritePlaneToLog(Ebene);

    int AnzahlAuf = 0;
    int AnzahlVor = 0;
    int AnzahlHin = 0;

    for(int i = 0; i < NUM_VEC; i++) 
    {
        if(tbPlaneDotCoords(Ebene, Vektor[i]) < -0.0001f)   // Hier und...
            AnzahlHin++;
        else if(tbPlaneDotCoords(Ebene, Vektor[i]) > 0.0001f) // ...hier
            AnzahlVor++;
        else
            AnzahlAuf++;
    }

    tbWriteToLog("%d Vektoren befinden sich auf der Ebene", AnzahlAuf);
    tbWriteToLog("%d Vektoren befinden sich vor der Ebene", AnzahlVor);
    tbWriteToLog("%d Vektoren befinden sich hinter der Ebene", AnzahlHin);

    tbExit();
    return 0;
}


Jetzt hast du im Bereich von 0.0001 und -0.0001 alle Punkte auf der Ebene. Ich denke mal deswegen steht auch im Buch die Aufgabe folgendermaßen:
"Punkte die fast genau auf der Ebene liegen (mindestens die drei ausgewählten), sind auch zu zählen"

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

3

22.01.2012, 19:30

Genau, niemals Gleitkommazahlen mit == vergleichen, außer du weißt ganz genau warum du es tust. Immer Rundungsfehler bedenken.
tbPlaneDotCoords() müsste man übrigens nur einmal berechnen ;)

devix360

Frischling

  • »devix360« ist der Autor dieses Themas

Beiträge: 6

Wohnort: Lünen

Beruf: Student

  • Private Nachricht senden

4

24.01.2012, 01:15

Danke klucki9.

Das war mein Fehler.
Jetzt läuft das Programm vernünftig.

Werbeanzeige