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

1

24.04.2004, 03:27

tbLineHitsTriangle()

Hallo,

Warum liefter mir folgender Funktionsaufruf

tbLineHitsTriangle(tbVector3(0,195,229),tbVector3(0,172,268),tbVector3(-50.000000f,-19.283627f,-22.981333f),tbVector3(-50.000000f,19.283627f,22.981333f),tbVector3(50.000000f,19.283627f,22.981333f),&vSchnittpunkt));

true zurück, mit dem angeblichen Schnittpunkt (0.000000/193.825256/230.991959), wo man doch schon an den z-Werten des Dreiecks und denen der Linie sehen kann, dass sich diese in weiter Entfernung voneinander befinden?

mfg
Jürgen

Anonymous

unregistriert

2

24.04.2004, 12:42

ich weiss jetzt nicht, ob daran auch dein Problem liegt,
aber die tbLineHitsTriangle hat einen kleinen Bug :
Die Normale (dort : Plane.n) wird immer wieder überschrieben......

hier der richtige Code :

Quellcode

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
    // Die Ebene dieses Dreiecks berechnen
    tbPlane Plane(tbPlaneFromPoints(vTriangleA, vTriangleB, vTriangleC));
    tbVector3 tNormale = Plane.n;

    // Schnittpunkt der Linie mit der Ebene bestimmen
    tbVector3 vIntersection;
    if(!tbLineHitsPlane(vLineA, vLineB, Plane, &vIntersection))
    {
        // Sie schneidet die Ebene nicht - dann kann sie das Dreieck
        // erst recht nicht schneiden.
        return FALSE;
    }

    // Erstellen der ersten Ebene entlang den Punkten A und B und
    // Einsetzen des Punkts in die Gleichung. Falls das Ergebnis kleiner
    // als null ist, liegt der Punkt hinter der Ebene und damit nicht im
    // Dreieck.
    tbVector3 vTemp(tbVector3Cross(vTriangleA - vTriangleB, tNormale));
    Plane = tbPlaneFromPointNormal(vTriangleA, vTemp);
    if(tbPlaneDotCoords(Plane, vIntersection) < 0.0f) return FALSE;

    // Test mit der zweiten Ebene entlang den Punkten B und C
    vTemp = tbVector3Cross(vTriangleB - vTriangleC, tNormale);
    Plane = tbPlaneFromPointNormal(vTriangleB, vTemp);
    if(tbPlaneDotCoords(Plane, vIntersection) < 0.0f) return FALSE;

    // Test mit der dritten Ebene entlang den Punkten C und A
    vTemp = tbVector3Cross(vTriangleC - vTriangleA, tNormale);
    Plane = tbPlaneFromPointNormal(vTriangleC, vTemp);
    if(tbPlaneDotCoords(Plane, vIntersection) < 0.0f) return FALSE;

3

24.04.2004, 17:01

daran hats leider nicht gelegen. trotzdem danke für die Antwort. hat keiner sonst noch eine Erklärung?

4

05.05.2004, 01:46

Ich komm nicht drauf, kann mir denn keiner kurz helfen bei dem Problem? Die krummen Werte stammen aus meinem Protokoll und liefern mir eben bei einer Kamerabewegung, die sich auf der z-Achse weit hinter dem zu prüfenden Dreieck abspielt eine Kollsion.

Zu Testzwecken rufe ich die Funktion direkt mit den entsprechenden Werten aus dem Protokoll auf:

if(tbLineHitsTriangle(tbVector3(0,195,229),tbVector3(0,172,268),tbVector3(-50.000000f,-19.283627f,-22.981333f),tbVector3(-50.000000f,19.283627f,22.981333f),tbVector3(50.000000f,19.283627f,22.981333f),&vSchnittpunkt))
tbWriteToLog("KOLLISION; Schnittpunkt (%f/%f/%f)",vSchnittpunkt.x,vSchnittpunkt.y,vSchnittpunkt.z);
else tbWriteToLog("KEINE KOLLSION");

liefert wie schon beschrieben true mit folgendem Schnittpunkt: SP (0.000000/193.825256/230.991959)

---
Ein weiterer Test, nur mit den gleichen Werten nur zur nächsten ganzen Zahl gerundet bringt das selbe Ergebniss:
KOLLISION; Schnittpunkt (0.000000/192.573227/233.114960)

if(tbLineHitsTriangle(tbVector3(0,195,229),tbVector3(0,172,268),tbVector3(-50.000000f,-19.0f,-23.0f),tbVector3(-50.000000f,19.0f,23.0f),tbVector3(50.000000f,19.0f,23.0f),&vSchnittpunkt))
tbWriteToLog("KOLLISION; Schnittpunkt (%f/%f/%f)",vSchnittpunkt.x,vSchnittpunkt.y,vSchnittpunkt.z);
else tbWriteToLog("KEINE KOLLSION");

---
Ein dritter Test, dieses mal werden die 3 Punkte des Dreiecks in umgekehrter Reihenfolge angegeben liefert richtigerweise "KEINE KOLLISION":

if(tbLineHitsTriangle(tbVector3(0,195,229),tbVector3(0,172,268),tbVector3(50.000000f,19.0f,23.0f),tbVector3(-50.000000f,19.0f,23.0f),tbVector3(-50.000000f,-19.0f,-23.0f),&vSchnittpunkt))
tbWriteToLog("KOLLISION; Schnittpunkt (%f/%f/%f)",vSchnittpunkt.x,vSchnittpunkt.y,vSchnittpunkt.z);
else tbWriteToLog("KEINE KOLLSION");
---------------------------------------------------------------------------
jetzt das seltsame: nehme ich die Werte aus Test Nr2 (der mit dem falschen Ergebniss) und wende dann darauf die Zeilen Code aus der Funktion direkt an und schaue mir die Zwischenergebnisse an, komme ich zu dem Ergebniss, dass die Funktion eigentlich durchaus richtig rechnet, die Linie schneidet die DreiecksEBENE tatsächlich, und beim Überprüfen ob der Schnittpunkt im Dreieck liegt ist der 2te Wert negativ, woraufhin er die Funktion eigentlich verlassen sollte und FALSE zurückliefern.

Hier erst das Ergebniss aus dem Protokoll und dann der verwendete Testcode:
Linie schneitet Dreiecks-Ebene
Test1: 17800000.000000
Test2: -162610704.000000
Test3: 180410704.000000

tbVector3 vLineA = tbVector3(0,195,229);
tbVector3 vLineB = tbVector3(0,172,268);
tbVector3 vTriangleA = tbVector3(-50.000000f,-19.0f,-23.0f);
tbVector3 vTriangleB = tbVector3(-50.000000f, 19.0f, 23.0f);
tbVector3 vTriangleC = tbVector3( 50.000000f, 19.0f, 23.0f);

tbPlane Plane(tbPlaneFromPoints(vTriangleA, vTriangleB, vTriangleC));
tbVector3 tNormale = Plane.n;

// Schnittpunkt der Linie mit der Ebene bestimmen
tbVector3 vIntersection;
if(!tbLineHitsPlane(vLineA, vLineB, Plane, &vIntersection))
{ tbWriteToLog("Linie schneitet Dreiecks-Ebene nicht");
// Sie schneidet die Ebene nicht - dann kann sie das Dreieck
// erst recht nicht schneiden.
}
else tbWriteToLog("Linie schneitet Dreiecks-Ebene");

// Erstellen der ersten Ebene entlang den Punkten A und B und
// Einsetzen des Punkts in die Gleichung. Falls das Ergebniss kleiner
// als null ist, liegt der Punkt hinter der Ebene und damit nicht im
// Dreieck.
tbVector3 vTemp(tbVector3Cross(vTriangleA - vTriangleB, tNormale));
Plane = tbPlaneFromPointNormal(vTriangleA, vTemp);
float test1;
test1 = tbPlaneDotCoords(Plane, vIntersection);
tbWriteToLog("Test1: %f",test1);

// Test mit der zweiten Ebene entlang den Punkten B und C
vTemp = tbVector3Cross(vTriangleB - vTriangleC, tNormale);
Plane = tbPlaneFromPointNormal(vTriangleB, vTemp);
float test2;
test2 = tbPlaneDotCoords(Plane, vIntersection);
tbWriteToLog("Test2: %f",test2);;

// Test mit der dritten Ebene entlang den Punkten C und A
vTemp = tbVector3Cross(vTriangleC - vTriangleA, tNormale);
Plane = tbPlaneFromPointNormal(vTriangleC, vTemp);
float test3;
test3 = tbPlaneDotCoords(Plane, vIntersection);
tbWriteToLog("Test3: %f",test3);
---
Entschuldigigung, möglicherweise stehe ich gerade irgendwie auf dem Schlauch, vielleicht mache einen dummen Anfängerfehler oder habe das Buch nicht aufmerksam genug gelesen, aber könnte mir mal jemand helfen und sich das anschauen?
greets
Jürgen

In Deinem Beitrag befinden sich noch Fehler.
Bitte bearbeite die rot markierten Stellen und lösche diesen Text.

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

5

28.11.2004, 15:17

Hmmm ich habe das selbe Prob. Der eine Fehler mit der Normalen ist mir auch aufgefallen und dass man theoretisch eine normale oder gegebenfalls 2 umdrehen müsste....

P.S: irre ich mich oder liefert die Funktion tbTriangleHitsTriangle nicht eine Fehlerhafte Liene zurück wenn die Normalvektoren gleich sind?

6

14.12.2004, 20:11

war jetzt schon lange her als ich das Problem hatte, aber inzwischen habe ich es dann doch hingekriegt. Es lag schon an dem Problem, das Fabster beschrieben hat (Danke nochmals), ich habe es nur nicht gleich gerafft, wie man das ausbessert (habe nur den Quellcode geändert, ohne die Bibliothek neu zu erstellen)

Werbeanzeige