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

big_muff

Alter Hase

Beiträge: 460

Wohnort: Schweiz

Beruf: Informatikstudent (4. Semester)

  • Private Nachricht senden

21

08.07.2006, 18:56

Eine Gerade hat immer folgende Form
y=a*x+b

wobei a die Steigung und b der Ordinatenabschnitt (Die y-Koordinate an x=0) ist. a, b, x, und y sind Skalare.

Wenn du nun a und b hast, hast du damit auch die Geradengleichung. Ich habe oben bewusst nicht y1 und y2 sondern y geschrieben da ich diese 2 y danach gleichsetze. Von der Gleichung her müsste dort schon y1 und y2 stehen.

Das x und das y in folgenden Formeln sind die Koordinaten des Schnittpunktes:
x = (b2-b1)/(a1-a2)
y = a1*x+b1

Und da du dich ja offensichtlich besser mit C++ als mit Vektorgeometrie auskennst :D, hier ein bisschen Code. habe ihn aber nicht getestet und weiss auch nicht ob er funktioniert, sollte aber:

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
31
32
BOOL CollisionRayLine(Vec2 vRayPos, Vec2 vRayDir, Vec2 vLinePos1, Vec2 vLinePos2, Vec2 *pvCutPoint)
{
    Vec vCutPoint; //Schnittpunkt
    Vec vLineDir;  //Richtungsvektor der Linie
    int ia1, ib1;  //Gerade aus dem Stahl
    int ia2, ib2;  //Gerade aus der Linie
    int ix, iy;    //Schnittpunktkoordinaten

    //Aus dem Stahl eine Gerade bilden
    ia1 = vRayDir.y/vRayDir.x;
    ib1 = vRayPos.y-ia1*vRayPos.x;

    //Aus der Linie eine Gerade bilden
    vLineDir = vLinePos2-vLinePos1;
    ia2      = vLineDir.y/vLineDir.x;
    ib2      = vLinePos1.y-ia2*vLinePos1.x;

    //theoretischen Schnittpunkt berechnen
    ix = (ib2-ib1)/(ia1-ia2);
    iy = ia1+ix*ia2;
    vCutPoint = Vec2(ix, iy);

    //Prüfen ob Schnittpunkt im gültigen Bereich liegt
    if(Vec2Dot(vCutPoint-vRayPos, vRayDir)<=0)
        return FALSE;
    if(Vec2Dot(vCutPoint-vLinePos1, vLinePos2-vLinePos1)<=0 && Vec2Dot(vCutPoint-vLinePos2, vLinePos1-vLinePos2)<=0)
        return FALSE;

    *pvCutPoint=vCutPoint;

    return TRUE;
}
Nur Idioten halten Ordnung, ein Genie beherrscht das Chaos.[size=7]

[/size]HardFate - Ein Start, Ein Ziel, Viele Wege[size=7]

[/size]Ein Mitglied der VEGeiCoUndGraSonMaWiGeS Bewegung.

Anonymous

unregistriert

22

08.07.2006, 18:58

nee nix code ^^ (nur wenn es sein muß)

sag mir einfach nur ob mein gedankengang richtig war. :roll:

big_muff

Alter Hase

Beiträge: 460

Wohnort: Schweiz

Beruf: Informatikstudent (4. Semester)

  • Private Nachricht senden

23

08.07.2006, 19:02

dein Gedankengang war richtig.
Aber jetzt bin ich schon fast fertig :?
Jetzt bring ich das auch noch :D
Nur Idioten halten Ordnung, ein Genie beherrscht das Chaos.[size=7]

[/size]HardFate - Ein Start, Ein Ziel, Viele Wege[size=7]

[/size]Ein Mitglied der VEGeiCoUndGraSonMaWiGeS Bewegung.

Anonymous

unregistriert

24

08.07.2006, 19:04

big_muff
Nagut, dann poste :)

Ich wusste doch das mir das irgendwie bekannt vor kam aus überlappenden Tarifen... :roll:

Anonymous

unregistriert

25

08.07.2006, 19:57

Hi,

ich hab mal selbst was geschrieben anhand der Berechnungen die Du gepostet hast und ohne mir deinen Code anzusehen :D

Hast eigentlich recht, total simpel wenn man sich mal etwas damit befasst. :roll:

big_muff

Alter Hase

Beiträge: 460

Wohnort: Schweiz

Beruf: Informatikstudent (4. Semester)

  • Private Nachricht senden

26

09.07.2006, 13:38

Ich bin doch sehr überrascht, dass hier noch keiner der vielen Mathematiker die hier im Forum unterwegs sind Einspruch eingelegt hat. Den Weg den ich beschrieben habe war zwar nicht falsch, jedoch gibt es einen eleganteren, schnelleren und vor allem sichereren Weg (der alte versagt nämlich bei Dir.x=0). Leider musste ich gestern weg und hatte keine Zeit mehr den zu posten aber das hole ich jetzt nach.
Völlig geblendet vom "2D" dachte ich sofort an die Geradengleichung die für diesen Fall aber völliger Schwachsinn (oder zumindest unnötig) ist. Der vektorielle Weg ist da viel praktischer.
Also kommen wir zum Punkt:

Strahl: RayPos+t*RayDir
Linie: LinePos1+s*(LinePos2-LinePos1)


gleichsetzen => RayPos+t*RayDir=LinePos1+s*(LinePos2-LinePos1)

komponentenweise aufgeschrieben ergibt dies zwei Gleichungen mit zwei unbekannten. Aufgelöst nach s und t ergibt das:

s=(RayDir.y*(LinePos1.x-RayPos.x)-RayDir.x*(LinePos1.y-RayPos.y))/(RayDir.y*(LinePos1.x-LinePos2.x)-RayDir.x*(LinePos1.y-LinePos2.y))
t=(LinePos1.x*(LinePos2.y-RayPos.y)-LinePos1.y*(LinePos2.x-RayPos.x)+LinePos2.x*RayPos.y-LinePos2.y*RayPos.x)/(RayDir.y*(LinePos1.x-LinePos2.x)-RayDir.x*(LinePos1.y-LinePos2.y))


Das sieht jetzt sicher komplizierter aus als vorhin. Ist aber trotzdem einfacher und schneller. Der Term unter dem Bruch ist bei s und t identisch, weshalb es sich empfiehlt, diesen vorhin zu berechnen. Ist er 0 gibt es natürlich keine (Geraden sind parallel) oder unendlich viele (Geraden sind deckungsgleich) Lösungen.

Das Prüfen ob der Wert im Definitionsbereich liegt ist hier auch viel einfacher: Er liegt drin, wenn t>=0, s>=0 und s<=1 ist.

Der Schnittpunkt ist dann = RayPos+t*RayDir

Ich würde dir auf jeden Fall empfehlen diese Variante zu verwenden!
Nur Idioten halten Ordnung, ein Genie beherrscht das Chaos.[size=7]

[/size]HardFate - Ein Start, Ein Ziel, Viele Wege[size=7]

[/size]Ein Mitglied der VEGeiCoUndGraSonMaWiGeS Bewegung.

Werbeanzeige