Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Mi Mai 15, 2024 06:52

Foren-Übersicht » Programmierung » Mathematik-Forum
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 15 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Halbgerade schneidet Kugel
BeitragVerfasst: Mi Jul 15, 2009 14:55 
Offline
DGL Member
Benutzeravatar

Registriert: Do Okt 16, 2008 13:18
Beiträge: 252
Hi,
ich versuche im Moment einen RayTracer zu Programmieren. Als erstes würde ich einfach schauen, ob eine Halbgerade eine Kugel schneidet. Mein Problem ist, dass ich keinen Ansatz habe, wie ich anfagen muss, da wir das in der Schule noch nicht hatten. Ich denke ich würde es noch in 2 Dimensionen hinbekommen, nur mit 3 fehlt mir jeder Ansatz. Wisst ihr eine Weg mit der man Prüfen kann, ob die Kugel geschnitten wird, in den Tutorials habe ich es nicht so (oder bessergesagt garnicht) verstanden.

_________________
You even trying ...

Website: http://rise-of-light.de/


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jul 15, 2009 16:09 
Offline
DGL Member

Registriert: Sa Aug 09, 2008 09:07
Beiträge: 112
Ich bin das so angegangen:

Geradengleichung in Parameterform:
OP = OA + λ * AB
AB... Richtungsvektor der Gerade

Überprüfung ob ein Punkt auf der Oberfläche der Kugel liegt:
(OM.x - OP.x)² + (OM.y - OP.y)² + (OM - OP.z)² = r²
OM... Ortsvektor auf den Mittelpunkt der Kugel
r... Der Radius der Kugel
Die Formel ist nur etwas unpraktisch. Nach ein bisschen Grübeln bin ich auf etwas besseres gekommen:
(OM - OP)² = r²

Dann kommen folgende Schritte:
- Einsetzen
- Ausmultiplizieren
- Herausheben
- Umformen zu der Form eine quadratischen Gleichung (a*x² + b*x² + c = 0 in deinem Fall x = λ)

Für a, b und c kommen dann Folgende Gleichungen heraus:
a = AB²
b = 2 * [(OA * AB) - (OM * AB)]
c = (OA - OM)² - r²

Ich würde Vorschlagen a, b und c separat aus zu rechnen und dann die Werte in die Lösungsformel einzusetzen.
So kommst du
- keine Lösung, wenn der Term unter der Wurzel < 0 ist
- eine Lösung wenn der Term unter der Wurzel = 0 ist
- zwei Lösungen wenn der Term unter der Wurzel > 0 ist
Die Position des/der Schnittpunktes/Schnittpunkte kannst du ausrechnen indem du λ/λ1, λ2 in die Geradengleichung einsetzt.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jul 15, 2009 17:07 
Offline
DGL Member
Benutzeravatar

Registriert: Do Okt 16, 2008 13:18
Beiträge: 252
Ich verstehs immer noch nicht wirklich, am besten wäre Code. Ich versuchs mal zu lösen, indem ich 2 Zweidimensionale Koordinatensysteme nehme einmal x,y und x,z wenn ich nun in beide den Kreis einfüge und dann schaue, dann weis ich zumindest ob man es sieht. (Achso, mit "hatten wir noch nicht in der Schule" meine ich, dass die meisten Mitschüler noch nichtmal wissen was ein Vektor ist).

_________________
You even trying ...

Website: http://rise-of-light.de/


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jul 15, 2009 18:01 
Offline
DGL Member

Registriert: Sa Aug 09, 2008 09:07
Beiträge: 112
Das im 2D könnte funktionieren.

Ich halte bei sowas nicht viel von Code (außerdem kann ich kein Delphi). Das macht die Sache nicht verständlicher. Ganz im Gegenteil.
Aber wenn du nicht sagst was du nicht verstehst, kann ich dir nicht helfen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jul 15, 2009 19:14 
Offline
DGL Member
Benutzeravatar

Registriert: Do Okt 16, 2008 13:18
Beiträge: 252
Andreas hat geschrieben:
Aber wenn du nicht sagst was du nicht verstehst, kann ich dir nicht helfen.

Ok dann sage ich jetzt was ich nicht verstehe. Ich gehe einfachmal den Text durch.

Zitat:
Geradengleichung in Parameterform:
OP = OA + λ * AB
AB... Richtungsvektor der Gerade

Ich verstehe auch nicht was OP oder OA heißt, ich kenne mich leider nicht so aus was Namensgebung angeht.

Zitat:
Überprüfung ob ein Punkt auf der Oberfläche der Kugel liegt:
(OM.x - OP.x)² + (OM.y - OP.y)² + (OM - OP.z)² = r²
OM... Ortsvektor auf den Mittelpunkt der Kugel
r... Der Radius der Kugel
Die Formel ist nur etwas unpraktisch. Nach ein bisschen Grübeln bin ich auf etwas besseres gekommen:
(OM - OP)² = r²

(OM.x - OP.x)² ... =r² : bringt es alles in eine 1 Dimensionale Ebene oder?
(OM - OP)² = r² : Das ist doch die erste Formel, nur zusammengefasst.

Zitat:
Dann kommen folgende Schritte:
- Einsetzen
- Ausmultiplizieren
- Herausheben
- Umformen zu der Form eine quadratischen Gleichung (a*x² + b*x² + c = 0 in deinem Fall x = λ)

Die ganzen Schritte hatten wir in dem Maße noch nicht, was mich allerdings mehr interessiert, wo sind OM OP und r hin, oder hat das jetzt nichtsmehr mit den anderen Formeln zu tun?

Zitat:
Für a, b und c kommen dann Folgende Gleichungen heraus:
a = AB²
b = 2 * [(OA * AB) - (OM * AB)]
c = (OA - OM)² - r²

a=AB²: AB ist doch der Richtungsvektor der Geraden, wie bekomme ich einen Richtungsvektor in eine Zahl.
Überhaupt sehe ich nicht den Bezug zu OA, wie kommst du von a*x²... zu a=AB² etc.
(Die Suchmaschine WolframAlpha kommt übrigens zum Ergebniss, dass bei
a*x² + b*x² + c = 0 die Lösung b=-a und c=0 ist)

Zitat:
Ich würde Vorschlagen a, b und c separat aus zu rechnen und dann die Werte in die Lösungsformel einzusetzen.
So kommst du
- keine Lösung, wenn der Term unter der Wurzel < 0 ist
- eine Lösung wenn der Term unter der Wurzel = 0 ist
- zwei Lösungen wenn der Term unter der Wurzel > 0 ist
Die Position des/der Schnittpunktes/Schnittpunkte kannst du ausrechnen indem du λ/λ1, λ2 in die Geradengleichung einsetzt.

Das zumindest glaube ich habe ich verstanden, Formel nach x umstellen, und schauen was rauskommt.

Ich hoffe ich bin kein hoffnungsloser Fall, aber wie gesagt in der Schule hatten wir das noch in keiner Weise.

_________________
You even trying ...

Website: http://rise-of-light.de/


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jul 15, 2009 20:13 
Offline
DGL Member

Registriert: Sa Aug 09, 2008 09:07
Beiträge: 112
Andreas hat geschrieben:
Aber wenn du nicht sagst was du nicht verstehst, kann ich dir nicht helfen.

Ok dann sage ich jetzt was ich nicht verstehe. Ich gehe einfachmal den Text durch.

mori hat geschrieben:
Zitat:
Geradengleichung in Parameterform:
OP = OA + λ * AB
AB... Richtungsvektor der Gerade

Ich verstehe auch nicht was OP oder OA heißt, ich kenne mich leider nicht so aus was Namensgebung angeht.


OP... Ortsvektor vom Punkt P der auf deiner Geraden liegt
OA... Ortsvektor vom Anfangspunkt der Gerade

mori hat geschrieben:
Zitat:
Überprüfung ob ein Punkt auf der Oberfläche der Kugel liegt:
(OM.x - OP.x)² + (OM.y - OP.y)² + (OM - OP.z)² = r²
OM... Ortsvektor auf den Mittelpunkt der Kugel
r... Der Radius der Kugel
Die Formel ist nur etwas unpraktisch. Nach ein bisschen Grübeln bin ich auf etwas besseres gekommen:
(OM - OP)² = r²

(OM.x - OP.x)² ... =r² : bringt es alles in eine 1 Dimensionale Ebene oder?
(OM - OP)² = r² : Das ist doch die erste Formel, nur zusammengefasst.


Es gibt keine "1 Dimensionale Ebene".
Angenommen wir kennen OM, OP und r.
Um prüfen zu können ob P sich auf der Kugel befindet brauchen wir jetzt den Pythagoras.
(OM.x - OP.x)² + (OM.y - OP.y)² + (OM.z - OP.z)² = Abstand²
Ist aber nicht so schön zum Rechnen wenn die Komponenten irgendwo in der Formel herumkugeln.
Wenn man aber genau hinsieht, erkennt man dass der linke Teil durch das Skalareprodukt ersetzt werden kann:
(OM - OP) * (OM - OP) = r²
oder kurz:
(OM - OP)² = r²

mori hat geschrieben:
Zitat:
Dann kommen folgende Schritte:
- Einsetzen
- Ausmultiplizieren
- Herausheben
- Umformen zu der Form eine quadratischen Gleichung (a*x² + b*x² + c = 0 in deinem Fall x = λ)

Die ganzen Schritte hatten wir in dem Maße noch nicht, was mich allerdings mehr interessiert, wo sind OM OP und r hin, oder hat das jetzt nichtsmehr mit den anderen Formeln zu tun?


a*x² + b*x² + c = 0
Ist die allgemeine Form eine quadratischen Gleichung.
Die quadratische Gleichung hab ich nicht komplett hingeschrieben weil es nicht wirklich übersichtlich ist.
AB² * λ² + 2 * [(OA * AB) - (OM * AB)] * λ + (OA - OM)² - r² = 0
Die Lösungsformel für diese Gleichung ist allgemein gefasst:
x1,2 = (-b ± √(b² - 4ac)) / (2a)

mori hat geschrieben:
Zitat:
Für a, b und c kommen dann Folgende Gleichungen heraus:
a = AB²
b = 2 * [(OA * AB) - (OM * AB)]
c = (OA - OM)² - r²

a=AB²: AB ist doch der Richtungsvektor der Geraden, wie bekomme ich einen Richtungsvektor in eine Zahl.
Überhaupt sehe ich nicht den Bezug zu OA, wie kommst du von a*x²... zu a=AB² etc.
(Die Suchmaschine WolframAlpha kommt übrigens zum Ergebniss, dass bei
a*x² + b*x² + c = 0 die Lösung b=-a und c=0 ist)


AB² ist eine Zahl, AB ist der Richtungsvektor. AB² = AB * AB = AB.x² + AB.y² + AB.z²

a*x² + b*x² + c = 0
sollte eig.
a*x² + b*x + c = 0
lauten.
Und die Gleichung kann keine Lösung heben, immerhin sind da 4 Unbekannte.

a = AB²
b = 2 * [(OA * AB) - (OM * AB)]
c = (OA - OM)² - r²
Rechnest du aus und setzt es in die Lösungsformel für quadratische Gleichungen ein.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jul 16, 2009 09:03 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mär 30, 2007 18:35
Beiträge: 331
Edit: Weiß garnicht ob das gestimmt hat :?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jul 16, 2009 10:28 
Offline
DGL Member
Benutzeravatar

Registriert: Do Okt 16, 2008 13:18
Beiträge: 252
Ich schaus mir nochmal an, ich habe jetzt aber einen Lösungsansatz für 2D selber gemacht, ich schreib es einfach mal hin denn ich bin mir nicht so sicher ob ich einen Fehler gemacht habe.
Als erstes braucht man ja die Definition eins Kreisringes die ist ja
r²=(Kreis.x-X)²+(Kreis.y-Y)² oder r=Wurzel((Kreis.x-X)²+(Kreis.y-Y)²)

Dann haben wir die Gerade Gerade.y=AnfangsPunkt.y+(Steigung.y/Steigung.x)*X
Jetzt formen wir nach X um
Also minus AnfangsPuntk.y und geteilt durch (Steigung.y/Steigung.x)
Dann haben wir
(Gerade.y-AnfangsPunkt.y)/(Steigung.y/Steigung.x)=X

Jetzt kommt der Teil wo ich mir nicht sicher bin:
Jetzt muss man die andere Formel nach X umstellen
Also erstmal (Kreis.x-X)² auflösen dann haben wir
r²=Kreis.x²-2*X*Kreis.x+X²+(Kreis.y-Y)²
Jetzt habe ich minus Kreis.x² und minus (Kreis.y-Y)² gerechnet
Danach sah es so aus
r²-Kreis.x²-(Kreis.y-Y)²=-2*X*Kreis.x+X²
Danach habe ich plus 2*X*Kreis.x gerechnet.
Die Formel sah dann so aus
(r²-Kreis.x²-(Kreis.y-Y)²)/(2*X*Kreis.x)=X²
Wenn man jetzt die Wurzel zieht hat man das Ergebniss für X und kann gleichsetzten, oder?

_________________
You even trying ...

Website: http://rise-of-light.de/


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jul 16, 2009 10:56 
Offline
DGL Member

Registriert: Sa Aug 09, 2008 09:07
Beiträge: 112
Nein.
Auf der linken Seite steht immer noch X.
Wie ich schon erwähnt habe muss da eine quadratische Gleichung raus kommen (tut sie ja auch bei dir), da eine Gerade mit einem Kreis bis zu 2 Schnittpunkte haben kann.
Wenn du deine Gleichung lösen willst musst du sie in genannte Form bringen. a*x² + b*x + c = 0.
Bzw. in deinem Fall praktischer Weise nur x² + p*x + q = 0.

r²-Kreis.x²-(Kreis.y-Y)²=-2*X*Kreis.x+X²
X² - X*2*Kreis.x - r² + Kreis.x² + (Kreis.y-Y)² = 0
somit wäre p = -2*Kreis.x
und q = - r² + Kreis.x² + (Kreis.y-Y)²

Dann rechnest du p und q aus (sofern die Formeln stimmen) und setzt in diese Formel ein
x1,2 = -p/2 ± √(p²/4 - q)
und bekommst die x-Werte der Schnittpunkte.
Jetzt noch die Werte in die Geradengleichung einsetzten und so bekommst du die y-Werte.

Ich würde mir an deiner Stelle einmal genau Vektoren ansehen. Die Geradengleichung ist da um einiges vorteilhafter.
Es gibt bei der Gleichung y = kx + d den Sonderfall dass k unendlich ist. Was dir bei den Vektoren nicht passieren kann.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Jul 18, 2009 15:39 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Aug 18, 2007 18:47
Beiträge: 694
Wohnort: Köln
Programmiersprache: Java
Sehr anschaulich wird das auch in den Kollisiontutorials erläutert.

_________________
Es werde Licht.
glEnable(GL_LIGHTING);
Und es ward Licht.


Zitat aus einem Java Buch: "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off"

on error goto next


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Jul 18, 2009 18:44 
Offline
DGL Member
Benutzeravatar

Registriert: Do Okt 16, 2008 13:18
Beiträge: 252
Danke für den Tipp, ich bin eben selber drauf gekommen. Ich mache es ein bischen anders.
Code:
  1. function TKugel.IsIn(Ray: TRay):TRGBA;
  2. var
  3.   Dist:TVector;
  4.   B:Single;
  5. begin
  6. Result.r:=Color.r;
  7. Result.g:=Color.g;
  8. Result.b:=Color.b;
  9. Result.a:=1;
  10.  
  11. dist.x:= Position.x - ray.Position.x*ray.Richtung.x;
  12. dist.y:= Position.y - ray.Position.y*ray.Richtung.y;
  13. dist.z:= Position.z - ray.Position.z*ray.Richtung.z;
  14.  
  15. B:=dist.x*dist.x+dist.y*dist.y+dist.z*dist.z;
  16. If B<0 then B:=-B;
  17. B:=Sqrt(B);
  18.  
  19. if (B < radius) then
  20.    begin
  21.    Result.a:=Color.a+B/radius;
  22.    end;
  23. end;

Ich weis nicht ob das jetzt 100% richtig ist, (vorallem drehen habe ich noch nicht getestet). Aber zumindest erscheint eine Kugel auf dem Bildschirm. (Ersetzt man zum Schluss B/radius durch B erscheinen Muster, die man durch die Farbwerte verändern kann)

_________________
You even trying ...

Website: http://rise-of-light.de/


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Jul 19, 2009 09:17 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mär 30, 2007 18:35
Beiträge: 331
Ein paar Optimierungen:

-B kann nicht negativ werden, deswegen ist die if-Abfrage nicht nötig
-wenn du B mit radius*radius (speicherst du am besten vorher) vergleichst sparst du dir ein teures sqrt()

Außerdem glaube ich nicht, dass das stimmt. Es sei denn Ray.Richtung = normalize(Ray.Richtung) * |(Ray.Position - Position)|
Man sollte erst die Distanz zwischen der Kugel (M) und dem Ausgangspunkt des Strahls (R) ausrechnen. Danach rechnet man den Punkt (P) aus, der die gleiche Distanz von R hat und auf der Gerade liegt. Wenn nun |P - M| <= r ist, dann liegt es in der Kugel.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Jul 24, 2009 20:50 
Offline
DGL Member

Registriert: Di Mai 24, 2005 16:43
Beiträge: 710
Ich hab hier nur den Code aus meinem Java-Raytracer, vielleicht hilft er ja:
Code:
  1.     public IntersectInfo intersect(Sphere sphere) {
  2.         double a, b, c;
  3.         // Gleichungen aufstellen
  4.         a = d.square();
  5.         b = 2 * Vector3f.dotProduct(d, Vector3f.sub(p, sphere.p));
  6.         c = (Vector3f.sub(sphere.p, p)).square() - sphere.r * sphere.r;
  7.         // Determinante bestimmen
  8.         double det = b*b - 4.0*a*c;
  9.         if (det < 0.0)
  10.             return new IntersectInfo();
  11.         det = Math.sqrt(det);
  12.         double q = -0.5 * (b + psgn(b) * det);
  13.         double x1 = q / a;
  14.         double x2 = c / q;
  15.         // x1 und x2 sortieren
  16.         if (x1 > x2) {
  17.             q = x2;
  18.             x2 = x1;
  19.             x1 = q;
  20.         }
  21.         // Beide Schnittpunkte liegen "hinter" dem Betrachter (nur für Halbgeraden)
  22.         if ((x1 < 0.0) && (x2 < 0.0)) {
  23.             return new IntersectInfo();
  24.         }
  25.         IntersectInfo iinfo = new IntersectInfo();
  26.         iinfo.p1 = Vector3f.add(p, Vector3f.scale(d, x1));
  27.         // Ein Schnittpunkt
  28.         if (x1 == x2) {
  29.             iinfo.contacts = 1;
  30.             iinfo.p2 = iinfo.p1;            
  31.         // Zwei Schnittpunkte            
  32.         } else {
  33.             iinfo.contacts = 2;
  34.             iinfo.p2 = Vector3f.add(p, Vector3f.scale(d, x2));            
  35.         }
  36.         return iinfo;
  37.     }

Die verwendeten Klassen Sphere, Vector3f und IntersectInfo sind denke ich selbsterklärend ;)

mfg


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Jul 27, 2009 07:17 
Offline
DGL Member
Benutzeravatar

Registriert: Do Okt 16, 2008 13:18
Beiträge: 252
@Seth: Super danke, endlich Code den man vernünftig in Delphi umschreiben kann, die ganzen C++ Codes im Internet benutzen alle überladene Operatoren und das ist dann eine riesen Arbeit das ganze in Delphi zu schreiben. Ich werde mir den Code mal anschauen, diese Woche bin ich zwar weg aber dann melde ich mich nochmal.

_________________
You even trying ...

Website: http://rise-of-light.de/


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jul 30, 2009 09:15 
Offline
DGL Member

Registriert: Di Mai 24, 2005 16:43
Beiträge: 710
p ist übrigens der Orts- und d der Richtungsvektor der Halbgeraden ;)


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 15 Beiträge ] 
Foren-Übersicht » Programmierung » Mathematik-Forum


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.046s | 17 Queries | GZIP : On ]