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

Aktuelle Zeit: So Dez 22, 2024 08:24

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



Ein neues Thema erstellen Auf das Thema antworten  [ 9 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Do Feb 05, 2009 11:33 
Offline
DGL Member

Registriert: Fr Okt 24, 2003 22:26
Beiträge: 120
Wohnort: Mannheim
Programmiersprache: Delphi
Hallo,

ich suche eine schnelle Funktion (Mathematik oder Source), die mir einen Punkt P auf eine Ebene E projiziert

Gegeben ist: Ebene E in Hessischer Normalform mit EN und ED sowie ein Punkt P

Ich kann mir den Punkt schon errechen, indem ich einen Strahl durch P bilde in Richtung EN und die Intersection mit der Ebene bilde.
Das scheint mir aber zu langsam.

Kennt aber jemand eine optimierten schnellen Code oder Mathematik? Den brauch ich, da ich diese Rechnung millionenfach ausführen muss.

Grüße
User69


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Feb 05, 2009 12:03 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jul 29, 2003 00:11
Beiträge: 436
Genau so mit dem Strahl hab ich das gemacht. Sieht mir eigentlich nicht übermäßig langsam aus, keine fiesen Funktionsaufrufe drin...
Code:
  1.  
  2. /**
  3.  * Projeziert den Vektor auf eine Ebene, die in hessischer Normalform gegeben ist.
  4.  *
  5.  * @param n Die Normale der Ebene.
  6.  * @param d Der Abstand der Ebene zum Ursprung.
  7.  */
  8. Vector3 Vector3::project(Vector3 n, double d) {
  9.     double quotient = n[0]*n[0] + n[1]*n[1] + n[2]*n[2];
  10.     if (quotient == 0.0) {
  11.         return Vector3::nullVector;
  12.     }
  13.     double lambda = (d - n[0]*v[0] - n[1]*v[1] - n[2]*v[2]) / quotient;
  14.     Vector3 result(v[0] + lambda*n[0], v[1] + lambda*n[1], v[2] + lambda*n[2]);
  15.     return result;
  16. }
  17.  


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Feb 05, 2009 12:35 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Falls du das auf der Grafikkarte rechnen willst, kann bei "millionenfacher" Ausführung durchaus sinnvoll sein, musst du dies in eine Matrix verpacken.

Also deine Ebene ist gegeben durch:
Normale n = (nx, ny, nz, 0)^T und einen Abstand d
Die Normale muss normalisiert sein. Für einen Punkt p auf der Ebene gilt: nx*px + ny*py + nz*pz + d = 0

Dann musst du für einen beliebigen Punkt p = (px, py, pz, 1)^T folgendes Berechnen:
p - n * (n^T * p + d)

Als Transformationsmatrix sieht das für den Punkt p dann so aus:
Code:
  1. | -nx*nx+1  -nx*ny    -nx*nz    -nx*d |   | px |
  2. | -ny*nx    -ny*ny+1  -ny*nz    -ny*d | * | py |
  3. | -nz*nx    -nz*ny    -nz*nz+1  -nz*d |   | pz |
  4. | 0         0         0         1     |   | 1  |
  5.  


Wenn man das mal ausrechnet:
Code:
  1. | -nx*nx*px+px + -nx*ny*px    + -nx*nz*px    + -nx*d |
  2. | -ny*nx*py    + -ny*ny*py+py + -ny*nz*py    + -ny*d |
  3. | -nz*nx*pz    + -nz*ny*pz    + -nz*nz*pz+pz + -nz*d |
  4. | 0            + 0            + 0            + 1     |

bzw.
Code:
  1. | -nx*nx*px + -nx*ny*px + -nx*nz*px + -nx*d |   | px |
  2. | -ny*nx*py + -ny*ny*py + -ny*nz*py + -ny*d | + | py |
  3. | -nz*nx*pz + -nz*ny*pz + -nz*nz*pz + -nz*d |   | pz |
  4. | 0         + 0         + 0         + 0     |   | 1  |

also
p - n * (n^T * p + d)

sofern ich mich nicht verechnet habe ;)


Edit:
@Philip:
Sicher das das da richtig ist mit dem Quotienten? Ich denke das funktioniert nur wenn der Normalenvektor normalisiert ist, weil dann die Länge und auch der Quotient 1 ist. In jedem Fall sollte man auf Normalisierung und if-Bedingungen verzichten wenn man etwas millionenfach macht.

Edit2: p - n * (n^T * p + d) statt p + n * (n^T * p + d)

Edit252: Ok, nun sollte es hoffentlich stimmen.

_________________
Yeah! :mrgreen:


Zuletzt geändert von Coolcat am Do Feb 05, 2009 14:11, insgesamt 3-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Feb 05, 2009 12:59 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jul 29, 2003 00:11
Beiträge: 436
Relativ sicher. Das ist einfach die Geradengleichung eingesetzt in die hessische Normalform und umgestellt nach Lambda.
Denke auch nicht, dass die Normale der Ebene dafür normalisiert sein muss.
Jedenfalls funktioniert es in einem Projekt wie gewollt. :)
Die If-Bedingung mag unter "normalen" Umständen sinnfrei sein (Welche Ebene hat schon eine Normale der Länge 0...), aber in dem Projekt, wo das eingesetzt wird, kann das unter ganz fiesen Umständen vorkommen. :)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Feb 05, 2009 13:44 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
@Philip: Ok, hast recht. :)

Bei mir war auch noch nen Fehler drin..."-" statt "+"

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Feb 05, 2009 13:48 
Offline
DGL Member

Registriert: Fr Okt 24, 2003 22:26
Beiträge: 120
Wohnort: Mannheim
Programmiersprache: Delphi
Danke.
Ich werd den Code von Philip heut abend mal testen.
Da ich meine Rechnung schon von einem normaliserten Vector ausgehen kann kann ich ja den quotient als auch die if Schleife sparen (speed optimization).
Ich denk der quotient macht nur Sinn, wenn keine Normalisierung vorliegt, da er nur dann <>1 wird.

Grüße
User69


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Feb 05, 2009 14:14 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Meine Matrix war immer noch nicht richtig, habs jetzt nochmal editiert...ich hoffe es stimmt nun endlich. Wenn du auf der CPU arbeitest und den Quotienten da weglässt ist die Lösung von Philip sowieso schneller.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Feb 05, 2009 14:54 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jul 29, 2003 00:11
Beiträge: 436
Mir fällt gerade noch ein: Wenn deine Ebene genau im Koordinatensystem liegt, z.B. die XZ-Ebene ist, dann kannst du auch ganz billig projezieren, indem du einfach die Y-Komponente des Punktes weglässt. Bzw. wenn die Normale der Ebene halt (0, 1, 0) ist, dann Y-Komponente = d der hessischen Normalform.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mär 15, 2009 19:42 
Offline
DGL Member

Registriert: Sa Aug 09, 2008 09:07
Beiträge: 112
user69 hat geschrieben:
...if Schleife...


böses Wort :wink:


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


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 6 Gäste


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:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.023s | 16 Queries | GZIP : On ]