MoinMoin,
im Zusammenhang mit meinen Ansätzen mich in 3D zu orientieren, siehe
auch hier: Beitrag "Transformation Kartesische zu polaren Koordinaten",
folgende Frage:
Ich ermittle den Schnittpunkt einer Geraden mit einer Ebene, indem ich
die Ebenengleichung in Koordinatenform aufstelle, und die Gerade dort
einsetze. Das ergibt ein Lambda, welches ich wieder in meine
Geradengleichung einsetzen kann, und den Schnittpunkt erhalte. Soweit
alles klar, und händisch klappt das auch einwandfrei.
Ich habe also meine Gerade, sie läuft von einem Punkt im Raum (P) zu
einem anderem Punkt (K). Dabei ist P ein Punkt des darzustellenden
Körpers und K der Punkt, an dem sich die "Kamera" befindet. Die
Gleichung meiner Geraden lautet also:
-> -> ->
P + lambda*(K) = G(erade)
(K) liegt vor, dass der Vektor vom Punkt zum Kamerapunkt zeigt.
Meine Ebene wird gebildet aus dem Stützvektor (S), welcher auf den
Ebenenmittelpunkt zeigt, und dem Normalvektor (N), welcher die
Ausrichtung der Ebene beschreibt (nebenbei auch noch den "Massstab"). In
Koordinatenform lautet die Ebenengleichung:
ax + by + cz - |d| = 0
wobei a,b,c den X,Y,Z-Teilen von N entsprechen und x,y,z den
X,Y,Z-Teilen der Geraden entsprechen. d ist der Stützvektor. Also setzen
wir ein:
Nx * (Px + lambda*Kx) +
Ny * (Py + lambda*Ky) +
Nz * (Pz + lambda*Kz) -
(Nx*Sx + Ny*Sy + Nz*Sz) = 0
das können wir händisch, da bis auf lamda alle Werte bekannt sind,
zusammenfassen zu:
neMenge lambdas = andreMenge einsen || /neMenge
^= lamdba = andreMenge/neMenge einsen.
Leider fehlt mir da in C jeglicher Ansatz. Ich stehe vor dem Problem,
dass ich nicht weiß, wie ich mit lambda umgehen soll. Wenn ich es
auslasse (also = 1 setze) wäre das ja erstens die Gerade von Anfang zum
Endpunkt und nicht mehr der Schnittpunkt, ausserdem würde mir ja auch
das Unterscheidungskriterium verloren gehen. Damit mein ich was, die
einsen und was die lamdas sind.
Mh wärend ich dass hier schreib, fällt mir ein, ich könnte ja noch
weiter ausklammern
Nx * (Px + lambda*Kx) +
Ny * (Py + lambda*Ky) +
Nz * (Pz + lambda*Kz) -
(Nx*Sx + Ny*Sy + Nz*Sz) = 0
Nx * Px + Nx * (lambda*Kx) +
Ny * Py + Ny * (lambda*Ky) +
Nz * Pz + Nz * (lambda*Kz) -
(Nx*Sx + Ny*Sy + Nz*Sz) = 0
Nx*Px + Ny*Py + Nz*Pz +
Nx*(lambda*Kx)+ Ny*(lambda*Ky) + Nz*(lambda*Kz) -
(Nx*Sx + Ny*Sy + Nz*Sz) = 0 || +(Nx*Sx + Ny*Sy + Nz*Sz)
Nx*Px + Ny*Py + Nz*Pz +
Nx*(lambda*Kx)+ Ny*(lambda*Ky) + Nz*(lambda*Kz) = (Nx*Sx + Ny*Sy +
Nz*Sz)
führt mich irgenddwie aber auch nicht weiter....
Oder darf ich einfach lambda an einer einzelnen Zeile ermitteln, ala:
Nx * (Px + lambda*Kx) - Nx*Sx = 0 || +Nx*Sx /Nx
Px + lambda*Kx = Nx*Sx/Nx = Sx || -Px
lambda*Kx = Sx-Px || /Kx
lambda = Sx-Px/Kx
da steckt doch sixher irgendwo der Wurm drin?
Ich hoffe man kann meinen Gedanken halbwegs folgen. Das dürfte doch
eigentlich nicht so schwer sein, nach einer unbekannten aufzulösen? Ich
plag mich nun schon seit Tagen damit rum, und komm auf keinen grünen
Zweig.
Für helfende Ansätze wär ich sehr dankbar =)
MfG Chaos
J. T. schrieb:> Nx*Px + Ny*Py + Nz*Pz +> Nx*(lambda*Kx)+ Ny*(lambda*Ky) + Nz*(lambda*Kz) = (Nx*Sx + Ny*Sy +> Nz*Sz)>> führt mich irgenddwie aber auch nicht weiter....
wieso bringt dich das nicht weiter?
Du kennst ja alles bis auf lambda
Gleichung nach lambda umformen so dass da steht
1
lambda = ......
und ausrechnen.
> Oder darf ich einfach lambda an einer einzelnen Zeile ermitteln, ala:>> Nx * (Px + lambda*Kx) - Nx*Sx = 0 || +Nx*Sx /Nx
Das ist nicht gegeben. Deine Ebenengleichung gibt das nicht her. Die
Ebenengleichung besagt, dass wenn du alle 3 Koordinaten einsetzt, dann
liegt ein Punkt auf der Ebene dann und nur dann wenn, sich die komplette
Ebenengleichung zu 0 errechnet. Das bezieht wisch aber nicht auf die
Einzelkomponenten.
J. T. schrieb:> Ich habe also meine Gerade, sie läuft von einem Punkt im Raum (P) zu> einem anderem Punkt (K). Dabei ist P ein Punkt des darzustellenden> Körpers und K der Punkt, an dem sich die "Kamera" befindet. Die> Gleichung meiner Geraden lautet also:>> -> -> ->> P + lambda*(K) = G(erade)
NItpickung.
Die Geradengleichung lautet
Gerade = P + lambda( K - P )
für den Ausdruck K - P (oder allgemeiner Endpunkt minus Anfangspunkt)
schreibt man meistens einfach dP (wobei am Papier das d für 'Delta'
steht)
P ist ein Ortsvektor, dP ist der Richtungsvektor von P nach K. lamba ist
ein Skalar (ein Zahlenwert), der von 0 bis 1 läuft. Hat lamda den Wert
0, dann befindet man sich auf der Geraden im Punkt P, hat lamba den Wert
1, dann befindet man sich auf dem Punkt K. Für lamda Werte zwischen 0
und 1 bezeichnet lamda einen Punkt auf der Geraden, der sich auf der
Linie von P nach K zwischen P und K befindet. Für lamda größer 1 bzw.
kleiner 0 sind die entsprechenden Punkte zwar auf der Geraden aber
'hinter' bzw. vor der Linie.
> Meine Ebene wird gebildet aus dem Stützvektor (S), welcher auf den> Ebenenmittelpunkt zeigt, und dem Normalvektor (N), welcher die> Ausrichtung der Ebene beschreibt (nebenbei auch noch den "Massstab").> In Koordinatenform lautet die Ebenengleichung:> ax + by + cz - |d| = 0
Machs nicht so kompliziert mit Stützvektor u. dlg.
Deine Ebene ist gegeben durch die Ebenengleichung
1
A*X + B*Y + C*Z + D = 0
(ob du +D oder -D anschreibst ist wurscht. Dann ist dann eben der
Zahlenwert für D negativ.). Ein Vierervektor.
D ist einfach nur eine Zahl (konkret ist es der Minimalabstand der Ebene
vom Koordinatenursprung, aber das braucht dich nicht weiter kümmern. Es
ist gut das zu wissen aber was das D geometrisch bedeutet ist meistens
uninteressant).
Jeder Punkt, der auf der Ebene liegt, muss diese Gleichung erfüllen,
ansonsten liegt er nicht auf der Ebene.
Insbesondere muss es also für die Geradengleichung
1
G = P + t * dP
(t ist üblich und schreibt sich schneller als lambda)
einen Punkt G gegeben, der auf der Ebene liegt, wenn die Gerade die
Ebene durchstösst.
Es muss also ein G ( = Gx, Gy, Gz ) geben, so dass
1
A * Gx + B * Gy + C * Gz + D = 0
Den Punkt G können wir aber auch in Parameterform schreiben
1
Gx = Px + t * dPx
2
Gy = Py + t * dPy
3
Gz = Pz + t * dPz
das kann man in die Punkt/Geradengleichung einsetzen
1
A*( Px + t * dPx ) + B*( Py + t * dPy ) + C*( Pz + t * dPy ) + d = 0
und nach t auflösen. t ist ja die einzige Unbekannte. Alle anderen Dinge
sind dem Zahlenwert nach ja bekannt, wenn die Gerade in Form der
Koeffizienten der Ebenengleichung A, B, C, D bzw. die Gerade in Form
2-er Punkte P und K auf ihr gegeben ist.
Am Ende willst du einen Ausdruck haben
1
t = ---------------------
Da wird ein Bruch rauskommen. Wie immer bei Brüchen heisst es aufpassen,
dass man nicht durch 0 dividiert. Daher wird man sich zuerst den Term
unter dem Bruchstrich ausrechnen und wenn der 0 ist (oder nahezu 0),
dann gibt es keine Lösung. Geometrisch bedeutet das, dass die Gerade G
parallel zur Ebene verläuft und sie nie schneidet.
Dieses dann dem Zahlenwert nach bekannte t setzt du dann in die
Einzelgleichungen für die Gerade ein
1
Gx = Px + t * dPx
2
Gy = Py + t * dPy
3
Gz = Pz + t * dPz
und kriegst somit die Koordinaten des Punktes, an dem die Gerade die
Ebene durchstösst. Der Punkt G ist ja gerade so konstruiert, dass er
beides gleichzeitig erfüllt: die Geradengleichung und die
Ebenengleichung.
Gleiches Vorgehen erbringt auch die Lösung für die Problemstellung: an
welchen Punkten G1 und G2 durchstösst eine Gerade eine Kugel. Die
Lösungsformel wird die Lösung einer quadratischen Gleichung sein, und
somit gibt es entweder 2 reelle Lösungen (die auch zusammenfallen
können) oder gar keine (wenn die Gerade die Kugel verfehlt). Allgemeiner
geht dieses Vorgehen immer dann, wenn die die Fragestellung hast: wo
durchstösst eine Gerade G eine mittels Formel gegebene Fläche bzw.
Körper. Ob sich die Gleichung dann analytisch lösen lässt ist eine
andere Frage, aber das Vorgehen ist prinzipiell dasselbe.
Karl H. schrieb:> für den Ausdruck K - P (oder allgemeiner Endpunkt minus Anfangspunkt)> schreibt man meistens einfach dP (wobei am Papier das d für 'Delta'> steht)
Das hab ich versucht, hiermit auszudrücken:
(K) liegt vor, dass der Vektor vom Punkt zum Kamerapunkt zeigt.
Der Differenzvektor quasi.
Karl H. schrieb:> P ist ein Ortsvektor, dP ist der Richtungsvektor von P nach K. lamba ist> ein Skalar (ein Zahlenwert), der von 0 bis 1 läuft. Hat lamda den Wert> 0, dann befindet man sich auf der Geraden im Punkt P, hat lamba den Wert> 1, dann befindet man sich auf dem Punkt K. Für lamda Werte zwischen 0> und 1 bezeichnet lamda einen Punkt auf der Geraden, der sich auf der> Linie von P nach K zwischen P und K befindet. Für lamda größer 1 bzw.> kleiner 0 sind die entsprechenden Punkte zwar auf der Geraden aber> 'hinter' bzw. vor der Linie.
Auch das ist mir soweit alles klar.
Karl H. schrieb:> wieso bringt dich das nicht weiter?
weil ich lambda nicht in allen termen loswerden kann. Wenn ich bspw den
Term mit Nx*(lambda*Kx) durch Nx*Kx teile, werden ja auch die anderen
Terme dadurch geteilt. Dann steht da ....+ lambda +
(Ny*(lambda*Ky))/Nx*Kx. Damit ist das lambda ja immernoch nicht allein?
Und in dem "EinzelzeilenAnsatz" steckte also doch der Wurm?
J. T. schrieb:> Karl H. schrieb:>> für den Ausdruck K - P (oder allgemeiner Endpunkt minus Anfangspunkt)>> schreibt man meistens einfach dP (wobei am Papier das d für 'Delta'>> steht)>> Das hab ich versucht, hiermit auszudrücken:> (K) liegt vor, dass der Vektor vom Punkt zum Kamerapunkt zeigt.>> Der Differenzvektor quasi.
Ja.
Aber du musst ein wenig sorgfältig sein.
Du kannt nicht das eine mal den zweiten Punkt auf der Geraden K nennen
und das andere mal ist es plötzlich ein Richtungsvektor, der vom
Startpunkt P zum Endpunkt K führt. Gewöhn dir hier eine Nomenklatur an.
>> wieso bringt dich das nicht weiter?>> weil ich lambda nicht in allen termen loswerden kann.
Du willst es ja gar nicht loswerden.
Du willst es ausrechnen! Und zwar mit dem was du hast.
In deiner letzten Gleichung ist alles dem Zahlenwert nach bekannt. Bis
auf das lamda.
> Und in dem "EinzelzeilenAnsatz" steckte also doch der Wurm?
Ja.
Halte dich an die Ebenengleichung. Sezte den Punkt ein, löse nach lamda
und fertig.
Siehe auch mein Posting von 02:39
(da hatten wir eine Zeitüberschneidung. Ich hatte nicht damit gerechnet,
dass du noch auf bist)
Wir überschneiden uns *gg
Vielen Dank für deine Erklärungsmühen, aber die geometrische Bedeutung
ist mir völlig klar. Es hapert nur noch daran, das so umzustellen, dass
t allein steht.
Karl H. schrieb:> d ist einfach nur eine Zahl (konkret ist es der Minimalabstand der Ebene> vom Koordinatenursprung, aber das braucht dich nicht weiter kümmern. Es> ist gut das zu wissen aber was das d geometrisch bedeutet ist meistens> uninteressant).
Ganz konkret ist es der Betrag des Stützvektors(zumindest, wenn ich das
richtig verstanden hab). Der muss nicht zwangsläufig senkrecht zur Ebene
stehen.
>(konkret ist es der Minimalabstand der Ebene> vom Koordinatenursprung,
Da hab ich auch ein kleines Problem mit entdeckt. Der Stützvektor zeigt
auf den Urpsrung der Ebene (Sie ist ja quasi ein Koordinatensystem im
Koordinatensystem). Wenn die Ebene aber nun zu diesem Vekor verdreht
ist, müssten sich doch Punkte finden lassen, die auf der Ebene liegen,
aber dichter am Ursprung des Urpsrungssystems liegen (des
3dimensionalen)? Der Punkt des kleinsten Abstandes muss ja auf jeden
Fall senkrecht zur Ebene liegen.
Wenn ich meinen Normalvektor so wähle, das ich quasi entlang einer Achse
gucke, dann fallen die anderen Achsen ja weg, und ich kann mein lambda/t
ganz einfach ermitteln, indem nur eine Zeile umstellen muss. Aber diese
mehreren t bringen mich irgendwie aus dem Tritt. Zumindest wenns daran
geht, das zu programmieren. Aufm Zettel gehts ganz einfach...
J. T. schrieb:> Ganz konkret ist es der Betrag des Stützvektors(zumindest, wenn ich das> richtig verstanden hab). Der muss nicht zwangsläufig senkrecht zur Ebene> stehen.
:-)
Doch das muss er.
Denn er ist der dem Betrag nach kleinste Vektor. Und damit muss er
senkrecht auf die Ebene stehen. Denn alle anderen Vektoren, auf denen
auch noch der 0-Punkt des Koordinatensystems liegt wären länger.
Es spielt aber keine grosse Rolle. Dieses geometrische 'Detail' benötigt
man fast nie.
> Da hab ich auch ein kleines Problem mit entdeckt. Der Stützvektor zeigt> auf den Urpsrung der Ebene (Sie ist ja quasi ein Koordinatensystem im> Koordinatensystem). Wenn die Ebene aber nun zu diesem Vekor verdreht> ist, müssten sich doch Punkte finden lassen, die auf der Ebene liegen,> aber dichter am Ursprung des Urpsrungssystems liegen (des> 3dimensionalen)? Der Punkt des kleinsten Abstandes muss ja auf jeden> Fall senkrecht zur Ebene liegen.
Ganz genau.
Aber in der Ebenengleichung kommt der Stützvektor überhaupt nicht als
Vektor vor sondern nur als sein Betrag (also die Länge dieses Vektors).
Das D ist quasi die Länge desjenigen Normalvektors, den man auf der
Ebene so platziert hat, dass der 0-Punkt des Koordinatensystems auf ihm
zu liegen kommt. Du kannst ja mit dem Normalvektor auf der Ebene
spazieren fahren und ihn an jedem beliebigen Punkt der Ebene errichten.
Zum Beispiel so, dass der 0-Punkt drauf liegt. Die Aussage des
Normalvektors ist ja nicht ein Punkt sondern eine Richtung. Und die
Richtung gilt natürlcih für jeden Punkt der Ebene. Anders ausgedrückt:
Du kannst auf einem Fussboden an jedem Punkt genau senkrecht nach oben
schauen. Du kannst dich aber auch genau so am Fussboden platzieren, dass
du beim senkrecht nach oben schauen genau durch ein Loch in der Decke
schaust. Das ändert nichts an der Aussage des Normalvektors. Aber von
allen Punkten auf der Ebene, gibt es nur einen, bei dem du in Richtung
des Normalvektors genau durch das Loch schaust. Und die Distanz, von
diesem Punkt aus bis zum Loch, das ist das D (wenn das Loch die
Koordinaten 0/0/0 hat) und das ist logischerweise die kleinste Distanz.
>> Wenn ich meinen Normalvektor so wähle, das ich quasi entlang einer Achse> gucke, dann fallen die anderen Achsen ja weg, und ich kann mein lambda/t> ganz einfach ermitteln, indem nur eine Zeile umstellen muss. Aber diese> mehreren t
es gibt keine mehreren t. Es gibt nur 1 einziges t. Dieses t (erkennbar
daran, dass ich keinen 'Index' x, y, oder z angeschrieben habe) ist
immer dasselbe. Eine einzige Zahl.
> bringen mich irgendwie aus dem Tritt. Zumindest wenns daran> geht, das zu programmieren. Aufm Zettel gehts ganz einfach...
Programmieren kannst du es erst, wenn du die Gleichung entsprechend nach
t aufgelöst hast.
Karl H. schrieb:> Du willst es ja gar nicht loswerden.> Du willst es ausrechnen! Und zwar mit dem was du hast.> In deiner letzten Gleichung ist alles dem Zahlenwert nach bekannt. Bis> auf das lamda.
Gut loswerden war der falsche Ausdruck, alleinstellen hab ich gemeint.
Und das Problem vor dem ich stehe, hab ich hier versucht anzureißen:
J. T. schrieb:> weil ich lambda nicht in allen termen loswerden kann. Wenn ich bspw den> Term mit Nx*(lambda*Kx) durch Nx*Kx teile, werden ja auch die anderen> Terme dadurch geteilt. Dann steht da ....+ lambda +> (Ny*(lambda*Ky))/Nx*Kx. Damit ist das lambda ja immernoch nicht allein?
A*( Px + t * dPx ) + B*( Py + t * dPy ) + C*( Pz + t * dPz ) + d = 0
|| /A
Px + t * dPx + B/A(Py + t dPy) + C/A(Pz + t dPz) + d = 0 ||-Px /dPx
t + ( (B/A(Py + t dPy)-Px)/dPx) + ( (C/A(Pz + t dPz)-Px)/dPx ) + d
in den anderen Termen stecken aber noch Ts drinne.... Ich blicks einfach
nicht....
J. T. schrieb:> Karl H. schrieb:>> Du willst es ja gar nicht loswerden.> A*( Px + t * dPx ) + B*( Py + t * dPy ) + C*( Pz + t * dPz ) + d = 0> || /A
Nö-
Klammern auflösen.
Dann alle Terme mit einem t auf die linke Seite. Alle ohne t auf die
rechte Seite.
Auf der linken Seite das t herausheben
den Term links (ohne t) nach rechts bringen
1
A*(Px + t*dPx) + B*(Py + t * dPy) + C*(Pz + t*dPz) + D = 0
Wenn man davon absieht, das ich das Minus in der Klammer hab, und du
draussen, kann man wohl sagen, das wir dasselbe raushaben.
Vielen Dank dafür =)
Das ich da nicht von selbst draufgekommen bin... Naja Mathe ist lang
lang her *gg
Nun kann ich endlich anfangen, das in ein Programm umzusetzen. Aber
erstmal in die Falle, glaub ich.
Gute Nacht, und nen Guten Rutsch, falls wir uns vorher nicht mehr lesen
=)
J. T. schrieb:> Wenn man davon absieht, das ich das Minus in der Klammer hab,> und du draussen
was aber mathematisch dasselbe ist.
Ich hab das Minus lieber draussen, weil der Ausdruck
1
... A*Px + B*Py + C*Pz + D ....
ja nichts anderes ist, als den Punkt P in die Geradengleichung
eingesetzt. Man könnte es auch als Sonderform eines Skalarproduktes
zweier Vektoren auffassen :-)
> Gute Nacht, und nen Guten Rutsch, falls wir uns vorher nicht mehr lesen> =)
Danke, dir auch.
Dann kann ich ja jetzt weiterschlafen. :-)
Karl H. schrieb:> Dann kann ich ja jetzt weiterschlafen. :-)
Du stehst nachts auf, um Leuten im Forum zu helfen?
Das nenne ich vorbildlichen Einsatz ;-)
Mark B. schrieb:> Karl H. schrieb:>> Dann kann ich ja jetzt weiterschlafen. :-)>> Du stehst nachts auf, um Leuten im Forum zu helfen?
Nö.
Bin auf der Couch aufgewacht, weil ich aufs 'du weisst schon' musste.
Bin beim Doku gucken mit dem Laptop am Schoss eingeschlafen (Making of
Star Wars).
Hihi
Gilt das eigentlich als das vielgepriesene "Das musst du auch nachts um
3 aus dem FF herbeten können"
Karl H. schrieb:> Geometrisch bedeutet das, dass die Gerade G> parallel zur Ebene verläuft und sie nie schneidet.
Zweiten Sonderfall beachten: Die Gerade liegt auf der Ebene.
Karl H. schrieb:> Die> Lösungsformel wird die Lösung einer quadratischen Gleichung sein, und> somit gibt es entweder 2 reelle Lösungen (die auch zusammenfallen> können) oder gar keine (wenn die Gerade die Kugel verfehlt).
Oder eine: Wenn die Gerade die Kugel an einem Punkt berührt.
Timm T. schrieb:> Karl H. schrieb:>> Die>> Lösungsformel wird die Lösung einer quadratischen Gleichung sein, und>> somit gibt es entweder 2 reelle Lösungendie auch zusammenfallen können>> oder gar keine (wenn die Gerade die Kugel verfehlt).>> Oder eine: Wenn die Gerade die Kugel an einem Punkt berührt.
Den hatte er, denke ich, erwähnt.
/Hannes
Karl H. schrieb:> A*(Px + t*dPx) + B*(Py + t * dPy) + C*(Pz + t*dPz) + D = 0
Hier ist uns ein Fehler Unterlaufen. Es müsste -D und nicht +D sein.
Ich hab A,B,C mal mit Nx,Ny,Nz ersetzt. K entspricht dP
NxPx + NxTKx +
NyPy + NyTKy +
NzPz + NzTKz) -
(Nx*Sx + Ny*Sy + Nz*Sz) = 0 ||-(Nx*Px+Ny*Py+Nz*Pz)
NxTKx + NyTKy + NzTKz - (NxSx+NySy+NzSz) = -(NxPx+NyPy+NzPz) ||T
ausklammern ||+(NxSx+NySy+NzSz)
T * (NxKx + NyKy + NzKz) = -(NxPx+NyPy+NzPz)+(NxSx+NySy+NzSz) ||/(NxKx
+ NyKy + NzKz)
T = -(NxPx+NyPy+NzPz)+(NxSx+NySy+NzSz)/(NxKx + NyKy + NzKz)
so müsste dann ein Schuh draus werden. Muss ich noch austesten. Bei der
erstigen Variante hat er mir nur sinnvolle Werte ausgespuckt, solange
ich den Stützvektor auf 0,0,0 gelassen hab.